mirror of
https://github.com/mattermost/mattermost.git
synced 2026-05-28 04:35:04 -04:00
MM-12463 : Added capability to bulk export custom emojis (#9790)
This commit is contained in:
parent
2104c6878c
commit
246ff89391
4 changed files with 177 additions and 2 deletions
|
|
@ -5,14 +5,17 @@ package app
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/mattermost/mattermost-server/model"
|
||||
)
|
||||
|
||||
func (a *App) BulkExport(writer io.Writer) *model.AppError {
|
||||
func (a *App) BulkExport(writer io.Writer, file string, pathToEmojiDir string, dirNameToExportEmoji string) *model.AppError {
|
||||
if err := a.ExportVersion(writer); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -32,6 +35,9 @@ func (a *App) BulkExport(writer io.Writer) *model.AppError {
|
|||
if err := a.ExportAllPosts(writer); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := a.ExportCustomEmoji(writer, file, pathToEmojiDir, dirNameToExportEmoji); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
@ -338,3 +344,88 @@ func (a *App) BuildPostReactions(postId string) (*[]ReactionImportData, *model.A
|
|||
return &reactionsOfPost, nil
|
||||
|
||||
}
|
||||
|
||||
func (a *App) ExportCustomEmoji(writer io.Writer, file string, pathToEmojiDir string, dirNameToExportEmoji string) *model.AppError {
|
||||
pageNumber := 0
|
||||
for {
|
||||
customEmojiList, err := a.GetEmojiList(pageNumber, 100, model.EMOJI_SORT_BY_NAME)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(customEmojiList) == 0 {
|
||||
break
|
||||
}
|
||||
|
||||
pageNumber++
|
||||
|
||||
pathToDir := a.createDirForEmoji(file, dirNameToExportEmoji)
|
||||
|
||||
for _, emoji := range customEmojiList {
|
||||
emojiImagePath := pathToEmojiDir + emoji.Id + "/image"
|
||||
err := a.copyEmojiImages(emoji.Id, emojiImagePath, pathToDir)
|
||||
if err != nil {
|
||||
return model.NewAppError("BulkExport", "app.export.export_custom_emoji.copy_emoji_images.error", nil, "err="+err.Error(), http.StatusBadRequest)
|
||||
}
|
||||
|
||||
filePath := dirNameToExportEmoji + "/" + emoji.Id + "/image"
|
||||
|
||||
emojiImportObject := ImportLineFromEmoji(emoji, filePath)
|
||||
|
||||
if err := a.ExportWriteLine(writer, emojiImportObject); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Creates directory named 'exported_emoji' to copy the emoji files
|
||||
// Directory and the file specified by admin share the same path
|
||||
func (a *App) createDirForEmoji(file string, dirName string) string {
|
||||
pathToFile, _ := filepath.Abs(file)
|
||||
pathSlice := strings.Split(pathToFile, "/")
|
||||
if len(pathSlice) > 0 {
|
||||
pathSlice = pathSlice[:len(pathSlice)-1]
|
||||
}
|
||||
pathToDir := strings.Join(pathSlice, "/") + "/" + dirName
|
||||
|
||||
if _, err := os.Stat(pathToDir); os.IsNotExist(err) {
|
||||
os.Mkdir(pathToDir, os.ModePerm)
|
||||
}
|
||||
return pathToDir
|
||||
}
|
||||
|
||||
// Copies emoji files from 'data/emoji' dir to 'exported_emoji' dir
|
||||
func (a *App) copyEmojiImages(emojiId string, emojiImagePath string, pathToDir string) error {
|
||||
var err error
|
||||
|
||||
fromPath, err := os.Open(emojiImagePath)
|
||||
if fromPath == nil || err != nil {
|
||||
return errors.New("Error reading " + emojiImagePath + "file")
|
||||
}
|
||||
defer fromPath.Close()
|
||||
|
||||
emojiDir := pathToDir + "/" + emojiId
|
||||
|
||||
if _, err := os.Stat(emojiDir); os.IsNotExist(err) {
|
||||
os.Mkdir(emojiDir, os.ModePerm)
|
||||
}
|
||||
if err != nil {
|
||||
return errors.New("Error creating directory for the emoji " + err.Error())
|
||||
}
|
||||
toPath, err := os.OpenFile(emojiDir+"/image", os.O_RDWR|os.O_CREATE, 0666)
|
||||
if err != nil {
|
||||
return errors.New("Error creating the image file " + err.Error())
|
||||
}
|
||||
defer toPath.Close()
|
||||
|
||||
_, err = io.Copy(toPath, fromPath)
|
||||
if err != nil {
|
||||
return errors.New("Error copying emojis " + err.Error())
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -139,3 +139,13 @@ func ImportReactionFromPost(reaction *model.Reaction) *ReactionImportData {
|
|||
CreateAt: &reaction.CreateAt,
|
||||
}
|
||||
}
|
||||
|
||||
func ImportLineFromEmoji(emoji *model.Emoji, filePath string) *LineImportData {
|
||||
return &LineImportData{
|
||||
Type: "emoji",
|
||||
Emoji: &EmojiImportData{
|
||||
Name: &emoji.Name,
|
||||
Image: &filePath,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package app
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
|
@ -103,3 +104,69 @@ func TestExportUserChannels(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDirCreationForEmoji(t *testing.T) {
|
||||
th := Setup().InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
pathToDir := th.App.createDirForEmoji("test.json", "exported_emoji_test")
|
||||
defer os.Remove(pathToDir)
|
||||
if _, err := os.Stat(pathToDir); os.IsNotExist(err) {
|
||||
t.Fatal("Directory exported_emoji_test should exist")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCopyEmojiImages(t *testing.T) {
|
||||
th := Setup().InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
emoji := &model.Emoji{
|
||||
Id: th.BasicUser.Id,
|
||||
}
|
||||
|
||||
// Creating a dir named `exported_emoji_test` in the root of the repo
|
||||
pathToDir := "../exported_emoji_test"
|
||||
|
||||
os.Mkdir(pathToDir, 0777)
|
||||
defer os.RemoveAll(pathToDir)
|
||||
|
||||
filePath := "../data/emoji/" + emoji.Id
|
||||
emojiImagePath := filePath + "/image"
|
||||
|
||||
var _, err = os.Stat(filePath)
|
||||
if os.IsNotExist(err) {
|
||||
os.MkdirAll(filePath, 0777)
|
||||
}
|
||||
|
||||
// Creating a file with the name `image` to copy it to `exported_emoji_test`
|
||||
os.OpenFile(filePath+"/image", os.O_RDONLY|os.O_CREATE, 0777)
|
||||
defer os.RemoveAll(filePath)
|
||||
|
||||
copyError := th.App.copyEmojiImages(emoji.Id, emojiImagePath, pathToDir)
|
||||
if copyError != nil {
|
||||
t.Fatal(copyError)
|
||||
}
|
||||
|
||||
if _, err := os.Stat(pathToDir + "/" + emoji.Id + "/image"); os.IsNotExist(err) {
|
||||
t.Fatal("File should exist ", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestExportCustomEmoji(t *testing.T) {
|
||||
th := Setup().InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
filePath := "../demo.json"
|
||||
|
||||
fileWriter, _ := os.Create(filePath)
|
||||
defer os.Remove(filePath)
|
||||
|
||||
pathToEmojiDir := "../data/emoji/"
|
||||
dirNameToExportEmoji := "exported_emoji_test"
|
||||
|
||||
err := th.App.ExportCustomEmoji(fileWriter, filePath, pathToEmojiDir, dirNameToExportEmoji)
|
||||
defer os.RemoveAll("../" + dirNameToExportEmoji)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -180,7 +180,14 @@ func bulkExportCmdF(command *cobra.Command, args []string) error {
|
|||
}
|
||||
defer fileWriter.Close()
|
||||
|
||||
if err := a.BulkExport(fileWriter); err != nil {
|
||||
// Path to directory of custom emoji
|
||||
pathToEmojiDir := "data/emoji/"
|
||||
|
||||
// Name of the directory to export custom emoji
|
||||
dirNameToExportEmoji := "exported_emoji"
|
||||
|
||||
// args[0] points to the filename/filepath passed with export bulk command
|
||||
if err := a.BulkExport(fileWriter, args[0], pathToEmojiDir, dirNameToExportEmoji); err != nil {
|
||||
CommandPrettyPrintln(err.Error())
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue