Reorganize file util functionality (#7848)
* reorganize file util functionality * fix api test compilation * fix rebase issue
Этот коммит содержится в:
30
app/app.go
30
app/app.go
@@ -43,6 +43,7 @@ type App struct {
|
||||
Compliance einterfaces.ComplianceInterface
|
||||
DataRetention einterfaces.DataRetentionInterface
|
||||
Elasticsearch einterfaces.ElasticsearchInterface
|
||||
Emoji einterfaces.EmojiInterface
|
||||
Ldap einterfaces.LdapInterface
|
||||
Metrics einterfaces.MetricsInterface
|
||||
Mfa einterfaces.MfaInterface
|
||||
@@ -133,6 +134,12 @@ func RegisterAccountMigrationInterface(f func(*App) einterfaces.AccountMigration
|
||||
accountMigrationInterface = f
|
||||
}
|
||||
|
||||
var brandInterface func(*App) einterfaces.BrandInterface
|
||||
|
||||
func RegisterBrandInterface(f func(*App) einterfaces.BrandInterface) {
|
||||
brandInterface = f
|
||||
}
|
||||
|
||||
var clusterInterface func(*App) einterfaces.ClusterInterface
|
||||
|
||||
func RegisterClusterInterface(f func(*App) einterfaces.ClusterInterface) {
|
||||
@@ -151,6 +158,18 @@ func RegisterDataRetentionInterface(f func(*App) einterfaces.DataRetentionInterf
|
||||
dataRetentionInterface = f
|
||||
}
|
||||
|
||||
var elasticsearchInterface func(*App) einterfaces.ElasticsearchInterface
|
||||
|
||||
func RegisterElasticsearchInterface(f func(*App) einterfaces.ElasticsearchInterface) {
|
||||
elasticsearchInterface = f
|
||||
}
|
||||
|
||||
var emojiInterface func(*App) einterfaces.EmojiInterface
|
||||
|
||||
func RegisterEmojiInterface(f func(*App) einterfaces.EmojiInterface) {
|
||||
emojiInterface = f
|
||||
}
|
||||
|
||||
var jobsDataRetentionJobInterface func(*App) ejobs.DataRetentionJobInterface
|
||||
|
||||
func RegisterJobsDataRetentionJobInterface(f func(*App) ejobs.DataRetentionJobInterface) {
|
||||
@@ -203,14 +222,21 @@ func (a *App) initEnterprise() {
|
||||
if accountMigrationInterface != nil {
|
||||
a.AccountMigration = accountMigrationInterface(a)
|
||||
}
|
||||
a.Brand = einterfaces.GetBrandInterface()
|
||||
if brandInterface != nil {
|
||||
a.Brand = brandInterface(a)
|
||||
}
|
||||
if clusterInterface != nil {
|
||||
a.Cluster = clusterInterface(a)
|
||||
}
|
||||
if complianceInterface != nil {
|
||||
a.Compliance = complianceInterface(a)
|
||||
}
|
||||
a.Elasticsearch = einterfaces.GetElasticsearchInterface()
|
||||
if elasticsearchInterface != nil {
|
||||
a.Elasticsearch = elasticsearchInterface(a)
|
||||
}
|
||||
if emojiInterface != nil {
|
||||
a.Emoji = emojiInterface(a)
|
||||
}
|
||||
if ldapInterface != nil {
|
||||
a.Ldap = ldapInterface(a)
|
||||
utils.AddConfigListener(func(_, cfg *model.Config) {
|
||||
|
||||
22
app/emoji.go
22
app/emoji.go
@@ -51,7 +51,7 @@ func (a *App) CreateEmoji(sessionUserId string, emoji *model.Emoji, multiPartIma
|
||||
if imageData := multiPartImageData.File["image"]; len(imageData) == 0 {
|
||||
err := model.NewAppError("Context", "api.context.invalid_body_param.app_error", map[string]interface{}{"Name": "createEmoji"}, "", http.StatusBadRequest)
|
||||
return nil, err
|
||||
} else if err := UploadEmojiImage(emoji.Id, imageData[0]); err != nil {
|
||||
} else if err := a.UploadEmojiImage(emoji.Id, imageData[0]); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ func (a *App) GetEmojiList(page, perPage int) ([]*model.Emoji, *model.AppError)
|
||||
}
|
||||
}
|
||||
|
||||
func UploadEmojiImage(id string, imageData *multipart.FileHeader) *model.AppError {
|
||||
func (a *App) UploadEmojiImage(id string, imageData *multipart.FileHeader) *model.AppError {
|
||||
file, err := imageData.Open()
|
||||
if err != nil {
|
||||
return model.NewAppError("uploadEmojiImage", "api.emoji.upload.open.app_error", nil, "", http.StatusBadRequest)
|
||||
@@ -100,7 +100,7 @@ func UploadEmojiImage(id string, imageData *multipart.FileHeader) *model.AppErro
|
||||
if err := gif.EncodeAll(newbuf, resized_gif); err != nil {
|
||||
return model.NewAppError("uploadEmojiImage", "api.emoji.upload.large_image.gif_encode_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
if err := utils.WriteFile(newbuf.Bytes(), getEmojiImagePath(id)); err != nil {
|
||||
if err := a.WriteFile(newbuf.Bytes(), getEmojiImagePath(id)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -112,18 +112,14 @@ func UploadEmojiImage(id string, imageData *multipart.FileHeader) *model.AppErro
|
||||
if err := png.Encode(newbuf, resized_image); err != nil {
|
||||
return model.NewAppError("uploadEmojiImage", "api.emoji.upload.large_image.encode_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
if err := utils.WriteFile(newbuf.Bytes(), getEmojiImagePath(id)); err != nil {
|
||||
if err := a.WriteFile(newbuf.Bytes(), getEmojiImagePath(id)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if err := utils.WriteFile(buf.Bytes(), getEmojiImagePath(id)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
return a.WriteFile(buf.Bytes(), getEmojiImagePath(id))
|
||||
}
|
||||
|
||||
func (a *App) DeleteEmoji(emoji *model.Emoji) *model.AppError {
|
||||
@@ -131,7 +127,7 @@ func (a *App) DeleteEmoji(emoji *model.Emoji) *model.AppError {
|
||||
return err
|
||||
}
|
||||
|
||||
deleteEmojiImage(emoji.Id)
|
||||
a.deleteEmojiImage(emoji.Id)
|
||||
a.deleteReactionsForEmoji(emoji.Name)
|
||||
return nil
|
||||
}
|
||||
@@ -158,7 +154,7 @@ func (a *App) GetEmojiImage(emojiId string) (imageByte []byte, imageType string,
|
||||
} else {
|
||||
var img []byte
|
||||
|
||||
if data, err := utils.ReadFile(getEmojiImagePath(emojiId)); err != nil {
|
||||
if data, err := a.ReadFile(getEmojiImagePath(emojiId)); err != nil {
|
||||
return nil, "", model.NewAppError("getEmojiImage", "api.emoji.get_image.read.app_error", nil, err.Error(), http.StatusNotFound)
|
||||
} else {
|
||||
img = data
|
||||
@@ -217,8 +213,8 @@ func imageToPaletted(img image.Image) *image.Paletted {
|
||||
return pm
|
||||
}
|
||||
|
||||
func deleteEmojiImage(id string) {
|
||||
if err := utils.MoveFile(getEmojiImagePath(id), "emoji/"+id+"/image_deleted"); err != nil {
|
||||
func (a *App) deleteEmojiImage(id string) {
|
||||
if err := a.MoveFile(getEmojiImagePath(id), "emoji/"+id+"/image_deleted"); err != nil {
|
||||
l4g.Error("Failed to rename image when deleting emoji %v", id)
|
||||
}
|
||||
}
|
||||
|
||||
62
app/file.go
62
app/file.go
@@ -57,7 +57,43 @@ const (
|
||||
IMAGE_PREVIEW_PIXEL_WIDTH = 1024
|
||||
)
|
||||
|
||||
func GetInfoForFilename(post *model.Post, teamId string, filename string) *model.FileInfo {
|
||||
func (a *App) FileBackend() (utils.FileBackend, *model.AppError) {
|
||||
return utils.NewFileBackend(&a.Config().FileSettings)
|
||||
}
|
||||
|
||||
func (a *App) ReadFile(path string) ([]byte, *model.AppError) {
|
||||
backend, err := a.FileBackend()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return backend.ReadFile(path)
|
||||
}
|
||||
|
||||
func (a *App) MoveFile(oldPath, newPath string) *model.AppError {
|
||||
backend, err := a.FileBackend()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return backend.MoveFile(oldPath, newPath)
|
||||
}
|
||||
|
||||
func (a *App) WriteFile(f []byte, path string) *model.AppError {
|
||||
backend, err := a.FileBackend()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return backend.WriteFile(f, path)
|
||||
}
|
||||
|
||||
func (a *App) RemoveFile(path string) *model.AppError {
|
||||
backend, err := a.FileBackend()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return backend.RemoveFile(path)
|
||||
}
|
||||
|
||||
func (a *App) GetInfoForFilename(post *model.Post, teamId string, filename string) *model.FileInfo {
|
||||
// Find the path from the Filename of the form /{channelId}/{userId}/{uid}/{nameWithExtension}
|
||||
split := strings.SplitN(filename, "/", 5)
|
||||
if len(split) < 5 {
|
||||
@@ -79,7 +115,7 @@ func GetInfoForFilename(post *model.Post, teamId string, filename string) *model
|
||||
|
||||
// Open the file and populate the fields of the FileInfo
|
||||
var info *model.FileInfo
|
||||
if data, err := utils.ReadFile(path); err != nil {
|
||||
if data, err := a.ReadFile(path); err != nil {
|
||||
l4g.Error(utils.T("api.file.migrate_filenames_to_file_infos.file_not_found.error"), post.Id, filename, path, err)
|
||||
return nil
|
||||
} else {
|
||||
@@ -121,7 +157,7 @@ func (a *App) FindTeamIdForFilename(post *model.Post, filename string) string {
|
||||
} else {
|
||||
for _, team := range teams {
|
||||
path := fmt.Sprintf("teams/%s/channels/%s/users/%s/%s/%s", team.Id, post.ChannelId, post.UserId, id, name)
|
||||
if _, err := utils.ReadFile(path); err == nil {
|
||||
if _, err := a.ReadFile(path); err == nil {
|
||||
// Found the team that this file was posted from
|
||||
return team.Id
|
||||
}
|
||||
@@ -168,7 +204,7 @@ func (a *App) MigrateFilenamesToFileInfos(post *model.Post) []*model.FileInfo {
|
||||
l4g.Error(utils.T("api.file.migrate_filenames_to_file_infos.team_id.error"), post.Id, filenames)
|
||||
} else {
|
||||
for _, filename := range filenames {
|
||||
info := GetInfoForFilename(post, teamId, filename)
|
||||
info := a.GetInfoForFilename(post, teamId, filename)
|
||||
if info == nil {
|
||||
continue
|
||||
}
|
||||
@@ -286,7 +322,7 @@ func (a *App) UploadFiles(teamId string, channelId string, userId string, fileHe
|
||||
}
|
||||
}
|
||||
|
||||
HandleImages(previewPathList, thumbnailPathList, imageDataList)
|
||||
a.HandleImages(previewPathList, thumbnailPathList, imageDataList)
|
||||
|
||||
return resStruct, nil
|
||||
}
|
||||
@@ -321,7 +357,7 @@ func (a *App) DoUploadFile(now time.Time, rawTeamId string, rawChannelId string,
|
||||
info.ThumbnailPath = pathPrefix + nameWithoutExtension + "_thumb.jpg"
|
||||
}
|
||||
|
||||
if err := utils.WriteFile(data, info.Path); err != nil {
|
||||
if err := a.WriteFile(data, info.Path); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -332,7 +368,7 @@ func (a *App) DoUploadFile(now time.Time, rawTeamId string, rawChannelId string,
|
||||
return info, nil
|
||||
}
|
||||
|
||||
func HandleImages(previewPathList []string, thumbnailPathList []string, fileData [][]byte) {
|
||||
func (a *App) HandleImages(previewPathList []string, thumbnailPathList []string, fileData [][]byte) {
|
||||
wg := new(sync.WaitGroup)
|
||||
|
||||
for i := range fileData {
|
||||
@@ -341,12 +377,12 @@ func HandleImages(previewPathList []string, thumbnailPathList []string, fileData
|
||||
wg.Add(2)
|
||||
go func(img *image.Image, path string, width int, height int) {
|
||||
defer wg.Done()
|
||||
generateThumbnailImage(*img, path, width, height)
|
||||
a.generateThumbnailImage(*img, path, width, height)
|
||||
}(img, thumbnailPathList[i], width, height)
|
||||
|
||||
go func(img *image.Image, path string, width int) {
|
||||
defer wg.Done()
|
||||
generatePreviewImage(*img, path, width)
|
||||
a.generatePreviewImage(*img, path, width)
|
||||
}(img, previewPathList[i], width)
|
||||
}
|
||||
}
|
||||
@@ -417,7 +453,7 @@ func getImageOrientation(input io.Reader) (int, error) {
|
||||
}
|
||||
}
|
||||
|
||||
func generateThumbnailImage(img image.Image, thumbnailPath string, width int, height int) {
|
||||
func (a *App) generateThumbnailImage(img image.Image, thumbnailPath string, width int, height int) {
|
||||
thumbWidth := float64(IMAGE_THUMBNAIL_PIXEL_WIDTH)
|
||||
thumbHeight := float64(IMAGE_THUMBNAIL_PIXEL_HEIGHT)
|
||||
imgWidth := float64(width)
|
||||
@@ -438,13 +474,13 @@ func generateThumbnailImage(img image.Image, thumbnailPath string, width int, he
|
||||
return
|
||||
}
|
||||
|
||||
if err := utils.WriteFile(buf.Bytes(), thumbnailPath); err != nil {
|
||||
if err := a.WriteFile(buf.Bytes(), thumbnailPath); err != nil {
|
||||
l4g.Error(utils.T("api.file.handle_images_forget.upload_thumb.error"), thumbnailPath, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func generatePreviewImage(img image.Image, previewPath string, width int) {
|
||||
func (a *App) generatePreviewImage(img image.Image, previewPath string, width int) {
|
||||
var preview image.Image
|
||||
|
||||
if width > IMAGE_PREVIEW_PIXEL_WIDTH {
|
||||
@@ -460,7 +496,7 @@ func generatePreviewImage(img image.Image, previewPath string, width int) {
|
||||
return
|
||||
}
|
||||
|
||||
if err := utils.WriteFile(buf.Bytes(), previewPath); err != nil {
|
||||
if err := a.WriteFile(buf.Bytes(), previewPath); err != nil {
|
||||
l4g.Error(utils.T("api.file.handle_images_forget.upload_preview.error"), previewPath, err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/mattermost/mattermost-server/model"
|
||||
"github.com/mattermost/mattermost-server/utils"
|
||||
)
|
||||
|
||||
func TestGeneratePublicLinkHash(t *testing.T) {
|
||||
@@ -51,7 +50,7 @@ func TestDoUploadFile(t *testing.T) {
|
||||
} else {
|
||||
defer func() {
|
||||
<-th.App.Srv.Store.FileInfo().PermanentDelete(info1.Id)
|
||||
utils.RemoveFile(info1.Path)
|
||||
th.App.RemoveFile(info1.Path)
|
||||
}()
|
||||
}
|
||||
|
||||
@@ -65,7 +64,7 @@ func TestDoUploadFile(t *testing.T) {
|
||||
} else {
|
||||
defer func() {
|
||||
<-th.App.Srv.Store.FileInfo().PermanentDelete(info2.Id)
|
||||
utils.RemoveFile(info2.Path)
|
||||
th.App.RemoveFile(info2.Path)
|
||||
}()
|
||||
}
|
||||
|
||||
@@ -79,7 +78,7 @@ func TestDoUploadFile(t *testing.T) {
|
||||
} else {
|
||||
defer func() {
|
||||
<-th.App.Srv.Store.FileInfo().PermanentDelete(info3.Id)
|
||||
utils.RemoveFile(info3.Path)
|
||||
th.App.RemoveFile(info3.Path)
|
||||
}()
|
||||
}
|
||||
|
||||
@@ -93,7 +92,7 @@ func TestDoUploadFile(t *testing.T) {
|
||||
} else {
|
||||
defer func() {
|
||||
<-th.App.Srv.Store.FileInfo().PermanentDelete(info3.Id)
|
||||
utils.RemoveFile(info3.Path)
|
||||
th.App.RemoveFile(info3.Path)
|
||||
}()
|
||||
}
|
||||
|
||||
|
||||
@@ -1497,8 +1497,8 @@ func (a *App) OldImportFile(timestamp time.Time, file io.Reader, teamId string,
|
||||
|
||||
img, width, height := prepareImage(data)
|
||||
if img != nil {
|
||||
generateThumbnailImage(*img, fileInfo.ThumbnailPath, width, height)
|
||||
generatePreviewImage(*img, fileInfo.PreviewPath, width)
|
||||
a.generateThumbnailImage(*img, fileInfo.ThumbnailPath, width, height)
|
||||
a.generatePreviewImage(*img, fileInfo.PreviewPath, width)
|
||||
}
|
||||
|
||||
return fileInfo, nil
|
||||
|
||||
@@ -751,7 +751,7 @@ func (a *App) GetProfileImage(user *model.User) ([]byte, bool, *model.AppError)
|
||||
} else {
|
||||
path := "users/" + user.Id + "/profile.png"
|
||||
|
||||
if data, err := utils.ReadFile(path); err != nil {
|
||||
if data, err := a.ReadFile(path); err != nil {
|
||||
readFailed = true
|
||||
|
||||
if img, err = CreateProfileImage(user.Username, user.Id, a.Config().FileSettings.InitialFont); err != nil {
|
||||
@@ -759,7 +759,7 @@ func (a *App) GetProfileImage(user *model.User) ([]byte, bool, *model.AppError)
|
||||
}
|
||||
|
||||
if user.LastPictureUpdate == 0 {
|
||||
if err := utils.WriteFile(img, path); err != nil {
|
||||
if err := a.WriteFile(img, path); err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
}
|
||||
@@ -812,7 +812,7 @@ func (a *App) SetProfileImage(userId string, imageData *multipart.FileHeader) *m
|
||||
|
||||
path := "users/" + userId + "/profile.png"
|
||||
|
||||
if err := utils.WriteFile(buf.Bytes(), path); err != nil {
|
||||
if err := a.WriteFile(buf.Bytes(), path); err != nil {
|
||||
return model.NewAppError("SetProfileImage", "api.user.upload_profile_user.upload_profile.app_error", nil, "", http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
|
||||
Ссылка в новой задаче
Block a user