diff options
author | Harrison Healey <harrisonmhealey@gmail.com> | 2016-09-30 11:06:30 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-09-30 11:06:30 -0400 |
commit | 8a0e649f989a824bb3bbfd1900a5b8e5383b47e1 (patch) | |
tree | 4b424929fe13ebec438d2f41a2729e37e5160720 /model/client.go | |
parent | a2deeed597dea15d9b7ca237be71988469f58cdd (diff) | |
download | chat-8a0e649f989a824bb3bbfd1900a5b8e5383b47e1.tar.gz chat-8a0e649f989a824bb3bbfd1900a5b8e5383b47e1.tar.bz2 chat-8a0e649f989a824bb3bbfd1900a5b8e5383b47e1.zip |
PLT-3105 Files table migration (#4068)
* Implemented initial changes for files table
* Removed *_benchmark_test.go files
* Re-implemented GetPublicFile and added support for old path
* Localization for files table
* Moved file system code into utils package
* Finished server-side changes and added initial upgrade script
* Added getPostFiles api
* Re-add Extension and HasPreviewImage fields to FileInfo
* Removed unused translation
* Fixed merge conflicts left over after permissions changes
* Forced FileInfo.extension to be lower case
* Changed FileUploadResponse to contain the FileInfos instead of FileIds
* Fixed permissions on getFile* calls
* Fixed notifications for file uploads
* Added initial version of client code for files changes
* Permanently added FileIds field to Post object and removed Post.HasFiles
* Updated PostStore.Update to be usable in more circumstances
* Re-added Filenames field and switched file migration to be entirely lazy-loaded
* Increased max listener count for FileStore
* Removed unused fileInfoCache
* Moved file system code back into api
* Removed duplicate test case
* Fixed unit test running on ports other than 8065
* Renamed HasPermissionToPostContext to HasPermissionToChannelByPostContext
* Refactored handleImages to make it more easily understandable
* Renamed getPostFiles to getFileInfosForPost
* Re-added pre-FileIds posts to analytics
* Changed files to be saved as their ids as opposed to id/filename.ext
* Renamed FileInfo.UserId to FileInfo.CreatorId
* Fixed detection of language in CodePreview
* Fixed switching between threads in the RHS not loading new files
* Add serverside protection against a rare bug where the client sends the same file twice for a single post
* Refactored the important parts of uploadFile api call into a function that can be called without a web context
Diffstat (limited to 'model/client.go')
-rw-r--r-- | model/client.go | 111 |
1 files changed, 75 insertions, 36 deletions
diff --git a/model/client.go b/model/client.go index 1048239be..f9a56b86e 100644 --- a/model/client.go +++ b/model/client.go @@ -124,6 +124,10 @@ func (c *Client) GetGeneralRoute() string { return "/general" } +func (c *Client) GetFileRoute(fileId string) string { + return fmt.Sprintf("/files/%v", fileId) +} + func (c *Client) DoPost(url, data, contentType string) (*http.Response, *AppError) { rq, _ := http.NewRequest("POST", c.Url+url, strings.NewReader(data)) rq.Header.Set("Content-Type", contentType) @@ -1289,8 +1293,33 @@ func (c *Client) UploadProfileFile(data []byte, contentType string) (*Result, *A return c.uploadFile(c.ApiUrl+"/users/newimage", data, contentType) } -func (c *Client) UploadPostAttachment(data []byte, contentType string) (*Result, *AppError) { - return c.uploadFile(c.ApiUrl+c.GetTeamRoute()+"/files/upload", data, contentType) +func (c *Client) UploadPostAttachment(data []byte, channelId string, filename string) (*FileUploadResponse, *AppError) { + c.clearExtraProperties() + + body := &bytes.Buffer{} + writer := multipart.NewWriter(body) + + if part, err := writer.CreateFormFile("files", filename); err != nil { + return nil, NewLocAppError("UploadPostAttachment", "model.client.upload_post_attachment.file.app_error", nil, err.Error()) + } else if _, err = io.Copy(part, bytes.NewBuffer(data)); err != nil { + return nil, NewLocAppError("UploadPostAttachment", "model.client.upload_post_attachment.file.app_error", nil, err.Error()) + } + + if part, err := writer.CreateFormField("channel_id"); err != nil { + return nil, NewLocAppError("UploadPostAttachment", "model.client.upload_post_attachment.channel_id.app_error", nil, err.Error()) + } else if _, err = io.Copy(part, strings.NewReader(channelId)); err != nil { + return nil, NewLocAppError("UploadPostAttachment", "model.client.upload_post_attachment.channel_id.app_error", nil, err.Error()) + } + + if err := writer.Close(); err != nil { + return nil, NewLocAppError("UploadPostAttachment", "model.client.upload_post_attachment.writer.app_error", nil, err.Error()) + } + + if result, err := c.uploadFile(c.ApiUrl+c.GetTeamRoute()+"/files/upload", body.Bytes(), writer.FormDataContentType()); err != nil { + return nil, err + } else { + return result.Data.(*FileUploadResponse), nil + } } func (c *Client) uploadFile(url string, data []byte, contentType string) (*Result, *AppError) { @@ -1312,55 +1341,51 @@ func (c *Client) uploadFile(url string, data []byte, contentType string) (*Resul } } -func (c *Client) GetFile(url string, isFullUrl bool) (*Result, *AppError) { - var rq *http.Request - if isFullUrl { - rq, _ = http.NewRequest("GET", url, nil) +func (c *Client) GetFile(fileId string) (io.ReadCloser, *AppError) { + if r, err := c.DoApiGet(c.GetFileRoute(fileId)+"/get", "", ""); err != nil { + return nil, err } else { - rq, _ = http.NewRequest("GET", c.ApiUrl+c.GetTeamRoute()+"/files/get"+url, nil) - } - - if len(c.AuthToken) > 0 { - rq.Header.Set(HEADER_AUTH, "BEARER "+c.AuthToken) + c.fillInExtraProperties(r) + return r.Body, nil } +} - if rp, err := c.HttpClient.Do(rq); err != nil { - return nil, NewLocAppError(url, "model.client.connecting.app_error", nil, err.Error()) - } else if rp.StatusCode >= 300 { - return nil, AppErrorFromJson(rp.Body) +func (c *Client) GetFileThumbnail(fileId string) (io.ReadCloser, *AppError) { + if r, err := c.DoApiGet(c.GetFileRoute(fileId)+"/get_thumbnail", "", ""); err != nil { + return nil, err } else { - defer closeBody(rp) - return &Result{rp.Header.Get(HEADER_REQUEST_ID), - rp.Header.Get(HEADER_ETAG_SERVER), rp.Body}, nil + c.fillInExtraProperties(r) + return r.Body, nil } } -func (c *Client) GetFileInfo(url string) (*Result, *AppError) { - var rq *http.Request - rq, _ = http.NewRequest("GET", c.ApiUrl+c.GetTeamRoute()+"/files/get_info"+url, nil) - - if len(c.AuthToken) > 0 { - rq.Header.Set(HEADER_AUTH, "BEARER "+c.AuthToken) +func (c *Client) GetFilePreview(fileId string) (io.ReadCloser, *AppError) { + if r, err := c.DoApiGet(c.GetFileRoute(fileId)+"/get_preview", "", ""); err != nil { + return nil, err + } else { + defer closeBody(r) + c.fillInExtraProperties(r) + return r.Body, nil } +} - if rp, err := c.HttpClient.Do(rq); err != nil { - return nil, NewLocAppError(url, "model.client.connecting.app_error", nil, err.Error()) - } else if rp.StatusCode >= 300 { - return nil, AppErrorFromJson(rp.Body) +func (c *Client) GetFileInfo(fileId string) (*FileInfo, *AppError) { + if r, err := c.DoApiGet(c.GetFileRoute(fileId)+"/get_info", "", ""); err != nil { + return nil, err } else { - defer closeBody(rp) - return &Result{rp.Header.Get(HEADER_REQUEST_ID), - rp.Header.Get(HEADER_ETAG_SERVER), FileInfoFromJson(rp.Body)}, nil + defer closeBody(r) + c.fillInExtraProperties(r) + return FileInfoFromJson(r.Body), nil } } -func (c *Client) GetPublicLink(filename string) (*Result, *AppError) { - if r, err := c.DoApiPost(c.GetTeamRoute()+"/files/get_public_link", MapToJson(map[string]string{"filename": filename})); err != nil { - return nil, err +func (c *Client) GetPublicLink(fileId string) (string, *AppError) { + if r, err := c.DoApiGet(c.GetFileRoute(fileId)+"/get_public_link", "", ""); err != nil { + return "", err } else { defer closeBody(r) - return &Result{r.Header.Get(HEADER_REQUEST_ID), - r.Header.Get(HEADER_ETAG_SERVER), StringFromJson(r.Body)}, nil + c.fillInExtraProperties(r) + return StringFromJson(r.Body), nil } } @@ -1930,3 +1955,17 @@ func (c *Client) GetWebrtcToken() (map[string]string, *AppError) { return MapFromJson(r.Body), nil } } + +// GetFileInfosForPost returns a list of FileInfo objects for a given post id, if successful. +// Otherwise, it returns an error. +func (c *Client) GetFileInfosForPost(channelId string, postId string, etag string) ([]*FileInfo, *AppError) { + c.clearExtraProperties() + + if r, err := c.DoApiGet(c.GetChannelRoute(channelId)+fmt.Sprintf("/posts/%v/get_file_infos", postId), "", etag); err != nil { + return nil, err + } else { + defer closeBody(r) + c.fillInExtraProperties(r) + return FileInfosFromJson(r.Body), nil + } +} |