summaryrefslogtreecommitdiffstats
path: root/app/import.go
diff options
context:
space:
mode:
authorGeorge Goldberg <george@gberg.me>2017-06-28 15:26:38 +0100
committerChristopher Speller <crspeller@gmail.com>2017-06-28 07:26:38 -0700
commit37642a4f1e99b2cb89fa6969ad34a892fabab5be (patch)
tree5f11d2b29a19ef4a309395d3cbc3f0451696f3fa /app/import.go
parentfb2ef7708bfcf0f05adfe35b4bd3fe73fc73a54f (diff)
downloadchat-37642a4f1e99b2cb89fa6969ad34a892fabab5be.tar.gz
chat-37642a4f1e99b2cb89fa6969ad34a892fabab5be.tar.bz2
chat-37642a4f1e99b2cb89fa6969ad34a892fabab5be.zip
PLT-6937: Bulk Importing of Direct/Group channels and posts. (#6761)
* PLT-6937: Bulk Importing of Direct/Group channels and posts. * Show group/direct channels in sidebar.
Diffstat (limited to 'app/import.go')
-rw-r--r--app/import.go240
1 files changed, 234 insertions, 6 deletions
diff --git a/app/import.go b/app/import.go
index 156591c0b..0a607e68e 100644
--- a/app/import.go
+++ b/app/import.go
@@ -17,17 +17,20 @@ import (
l4g "github.com/alecthomas/log4go"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/utils"
+ "github.com/mattermost/platform/store"
)
// Import Data Models
type LineImportData struct {
- Type string `json:"type"`
- Team *TeamImportData `json:"team"`
- Channel *ChannelImportData `json:"channel"`
- User *UserImportData `json:"user"`
- Post *PostImportData `json:"post"`
- Version *int `json:"version"`
+ Type string `json:"type"`
+ Team *TeamImportData `json:"team"`
+ Channel *ChannelImportData `json:"channel"`
+ User *UserImportData `json:"user"`
+ Post *PostImportData `json:"post"`
+ DirectChannel *DirectChannelImportData `json:"direct_channel"`
+ DirectPost *DirectPostImportData `json:"direct_post"`
+ Version *int `json:"version"`
}
type TeamImportData struct {
@@ -97,6 +100,20 @@ type PostImportData struct {
CreateAt *int64 `json:"create_at"`
}
+type DirectChannelImportData struct {
+ Members *[]string `json:"members"`
+
+ Header *string `json:"header"`
+}
+
+type DirectPostImportData struct {
+ ChannelMembers *[]string `json:"channel_members"`
+ User *string `json:"user"`
+
+ Message *string `json:"message"`
+ CreateAt *int64 `json:"create_at"`
+}
+
type LineImportWorkerData struct {
LineImportData
LineNumber int
@@ -233,6 +250,18 @@ func ImportLine(line LineImportData, dryRun bool) *model.AppError {
} else {
return ImportPost(line.Post, dryRun)
}
+ case line.Type == "direct_channel":
+ if line.DirectChannel == nil {
+ return model.NewAppError("BulkImport", "app.import.import_line.null_direct_channel.error", nil, "", http.StatusBadRequest)
+ } else {
+ return ImportDirectChannel(line.DirectChannel, dryRun)
+ }
+ case line.Type == "direct_post":
+ if line.DirectPost == nil {
+ return model.NewAppError("BulkImport", "app.import.import_line.null_direct_post.error", nil, "", http.StatusBadRequest)
+ } else {
+ return ImportDirectPost(line.DirectPost, dryRun)
+ }
default:
return model.NewLocAppError("BulkImport", "app.import.import_line.unknown_line_type.error", map[string]interface{}{"Type": line.Type}, "")
}
@@ -945,6 +974,205 @@ func validatePostImportData(data *PostImportData) *model.AppError {
return nil
}
+func ImportDirectChannel(data *DirectChannelImportData, dryRun bool) *model.AppError {
+ if err := validateDirectChannelImportData(data); err != nil {
+ return err
+ }
+
+ // If this is a Dry Run, do not continue any further.
+ if dryRun {
+ return nil
+ }
+
+ var userIds []string
+ for _, username := range *data.Members {
+ if result := <-Srv.Store.User().GetByUsername(username); result.Err == nil {
+ user := result.Data.(*model.User)
+ userIds = append(userIds, user.Id)
+ } else {
+ return model.NewAppError("BulkImport", "app.import.import_direct_channel.member_not_found.error", nil, "", http.StatusBadRequest)
+ }
+ }
+
+ var channel *model.Channel
+
+ if len(userIds) == 2 {
+ ch, err := createDirectChannel(userIds[0], userIds[1])
+ if err != nil && err.Id != store.CHANNEL_EXISTS_ERROR {
+ return model.NewAppError("BulkImport", "app.import.import_direct_channel.create_direct_channel.error", nil, "", http.StatusBadRequest)
+ } else {
+ channel = ch
+ }
+ } else {
+ ch, err := createGroupChannel(userIds, userIds[0])
+ if err != nil && err.Id != store.CHANNEL_EXISTS_ERROR {
+ return model.NewAppError("BulkImport", "app.import.import_direct_channel.create_group_channel.error", nil, "", http.StatusBadRequest)
+ } else {
+ channel = ch
+ }
+ }
+
+ for _, userId := range userIds {
+ preferences := model.Preferences{
+ model.Preference{
+ UserId: userId,
+ Category: model.PREFERENCE_CATEGORY_DIRECT_CHANNEL_SHOW,
+ Name: channel.Id,
+ Value: "true",
+ },
+ }
+ if result := <-Srv.Store.Preference().Save(&preferences); result.Err != nil {
+ result.Err.StatusCode = http.StatusBadRequest
+ return result.Err
+ }
+ }
+
+ if data.Header != nil {
+ channel.Header = *data.Header
+ if result := <-Srv.Store.Channel().Update(channel); result.Err != nil {
+ return model.NewAppError("BulkImport", "app.import.import_direct_channel.update_header_failed.error", nil, "", http.StatusBadRequest)
+ }
+ }
+
+ return nil
+}
+
+func validateDirectChannelImportData(data *DirectChannelImportData) *model.AppError {
+ if data.Members == nil {
+ return model.NewLocAppError("BulkImport", "app.import.validate_direct_channel_import_data.members_required.error", nil, "")
+ }
+
+ if len(*data.Members) != 2 {
+ if len(*data.Members) < model.CHANNEL_GROUP_MIN_USERS {
+ return model.NewLocAppError("BulkImport", "app.import.validate_direct_channel_import_data.members_too_few.error", nil, "")
+ } else if len(*data.Members) > model.CHANNEL_GROUP_MAX_USERS {
+ return model.NewLocAppError("BulkImport", "app.import.validate_direct_channel_import_data.members_too_many.error", nil, "")
+ }
+ }
+
+ if data.Header != nil && utf8.RuneCountInString(*data.Header) > model.CHANNEL_HEADER_MAX_RUNES {
+ return model.NewLocAppError("BulkImport", "app.import.validate_direct_channel_import_data.header_length.error", nil, "")
+ }
+
+ return nil
+}
+
+func ImportDirectPost(data *DirectPostImportData, dryRun bool) *model.AppError {
+ if err := validateDirectPostImportData(data); err != nil {
+ return err
+ }
+
+ // If this is a Dry Run, do not continue any further.
+ if dryRun {
+ return nil
+ }
+
+ var userIds []string
+ for _, username := range *data.ChannelMembers {
+ if result := <-Srv.Store.User().GetByUsername(username); result.Err == nil {
+ user := result.Data.(*model.User)
+ userIds = append(userIds, user.Id)
+ } else {
+ return model.NewAppError("BulkImport", "app.import.import_direct_post.channel_member_not_found.error", nil, "", http.StatusBadRequest)
+ }
+ }
+
+ var channel *model.Channel
+ if len(userIds) == 2 {
+ ch, err := createDirectChannel(userIds[0], userIds[1])
+ if err != nil && err.Id != store.CHANNEL_EXISTS_ERROR {
+ return model.NewAppError("BulkImport", "app.import.import_direct_channel.create_direct_channel.error", nil, "", http.StatusBadRequest)
+ } else {
+ channel = ch
+ }
+ } else {
+ ch, err := createGroupChannel(userIds, userIds[0])
+ if err != nil && err.Id != store.CHANNEL_EXISTS_ERROR {
+ return model.NewAppError("BulkImport", "app.import.import_direct_channel.create_group_channel.error", nil, "", http.StatusBadRequest)
+ } else {
+ channel = ch
+ }
+ }
+
+ var user *model.User
+ if result := <-Srv.Store.User().GetByUsername(*data.User); result.Err != nil {
+ return model.NewAppError("BulkImport", "app.import.import_direct_post.user_not_found.error", map[string]interface{}{"Username": *data.User}, "", http.StatusBadRequest)
+ } else {
+ user = result.Data.(*model.User)
+ }
+
+ // Check if this post already exists.
+ var posts []*model.Post
+ if result := <-Srv.Store.Post().GetPostsCreatedAt(channel.Id, *data.CreateAt); result.Err != nil {
+ return result.Err
+ } else {
+ posts = result.Data.([]*model.Post)
+ }
+
+ var post *model.Post
+ for _, p := range posts {
+ if p.Message == *data.Message {
+ post = p
+ break
+ }
+ }
+
+ if post == nil {
+ post = &model.Post{}
+ }
+
+ post.ChannelId = channel.Id
+ post.Message = *data.Message
+ post.UserId = user.Id
+ post.CreateAt = *data.CreateAt
+
+ post.Hashtags, _ = model.ParseHashtags(post.Message)
+
+ if post.Id == "" {
+ if result := <-Srv.Store.Post().Save(post); result.Err != nil {
+ return result.Err
+ }
+ } else {
+ if result := <-Srv.Store.Post().Overwrite(post); result.Err != nil {
+ return result.Err
+ }
+ }
+
+ return nil
+}
+
+func validateDirectPostImportData(data *DirectPostImportData) *model.AppError {
+ if data.ChannelMembers == nil {
+ return model.NewLocAppError("BulkImport", "app.import.validate_direct_post_import_data.channel_members_required.error", nil, "")
+ }
+
+ if len(*data.ChannelMembers) != 2 {
+ if len(*data.ChannelMembers) < model.CHANNEL_GROUP_MIN_USERS {
+ return model.NewLocAppError("BulkImport", "app.import.validate_direct_post_import_data.channel_members_too_few.error", nil, "")
+ } else if len(*data.ChannelMembers) > model.CHANNEL_GROUP_MAX_USERS {
+ return model.NewLocAppError("BulkImport", "app.import.validate_direct_post_import_data.channel_members_too_many.error", nil, "")
+ }
+ }
+
+ if data.User == nil {
+ return model.NewAppError("BulkImport", "app.import.validate_direct_post_import_data.user_missing.error", nil, "", http.StatusBadRequest)
+ }
+
+ if data.Message == nil {
+ return model.NewAppError("BulkImport", "app.import.validate_direct_post_import_data.message_missing.error", nil, "", http.StatusBadRequest)
+ } else if utf8.RuneCountInString(*data.Message) > model.POST_MESSAGE_MAX_RUNES {
+ return model.NewAppError("BulkImport", "app.import.validate_direct_post_import_data.message_length.error", nil, "", http.StatusBadRequest)
+ }
+
+ if data.CreateAt == nil {
+ return model.NewAppError("BulkImport", "app.import.validate_direct_post_import_data.create_at_missing.error", nil, "", http.StatusBadRequest)
+ } else if *data.CreateAt == 0 {
+ return model.NewAppError("BulkImport", "app.import.validate_direct_post_import_data.create_at_zero.error", nil, "", http.StatusBadRequest)
+ }
+
+ return nil
+}
+
//
// -- Old SlackImport Functions --
// Import functions are sutible for entering posts and users into the database without