Files
mostlymatter/model/post.go
George Goldberg 275188ad04 PLT-4839 Split too-long Slack messages on import. (#4679)
* PLT-4839 Split too-long Slack messages on import.

This PR also takes the opportunity to make the max values for Post
properties into constants for easier use elsewhere, as has previously
been done for Channel properties.

* Only count runes once.
2016-12-02 08:13:15 -05:00

181 строка
5.1 KiB
Go

// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package model
import (
"encoding/json"
"io"
"unicode/utf8"
)
const (
POST_SYSTEM_MESSAGE_PREFIX = "system_"
POST_DEFAULT = ""
POST_SLACK_ATTACHMENT = "slack_attachment"
POST_SYSTEM_GENERIC = "system_generic"
POST_JOIN_LEAVE = "system_join_leave"
POST_ADD_REMOVE = "system_add_remove"
POST_HEADER_CHANGE = "system_header_change"
POST_CHANNEL_DELETED = "system_channel_deleted"
POST_EPHEMERAL = "system_ephemeral"
POST_FILEIDS_MAX_RUNES = 150
POST_FILENAMES_MAX_RUNES = 4000
POST_HASHTAGS_MAX_RUNES = 1000
POST_MESSAGE_MAX_RUNES = 4000
POST_PROPS_MAX_RUNES = 8000
)
type Post struct {
Id string `json:"id"`
CreateAt int64 `json:"create_at"`
UpdateAt int64 `json:"update_at"`
DeleteAt int64 `json:"delete_at"`
UserId string `json:"user_id"`
ChannelId string `json:"channel_id"`
RootId string `json:"root_id"`
ParentId string `json:"parent_id"`
OriginalId string `json:"original_id"`
Message string `json:"message"`
Type string `json:"type"`
Props StringInterface `json:"props"`
Hashtags string `json:"hashtags"`
Filenames StringArray `json:"filenames,omitempty"` // Deprecated, do not use this field any more
FileIds StringArray `json:"file_ids,omitempty"`
PendingPostId string `json:"pending_post_id" db:"-"`
HasReactions bool `json:"has_reactions,omitempty"`
}
func (o *Post) ToJson() string {
b, err := json.Marshal(o)
if err != nil {
return ""
} else {
return string(b)
}
}
func PostFromJson(data io.Reader) *Post {
decoder := json.NewDecoder(data)
var o Post
err := decoder.Decode(&o)
if err == nil {
return &o
} else {
return nil
}
}
func (o *Post) Etag() string {
return Etag(o.Id, o.UpdateAt)
}
func (o *Post) IsValid() *AppError {
if len(o.Id) != 26 {
return NewLocAppError("Post.IsValid", "model.post.is_valid.id.app_error", nil, "")
}
if o.CreateAt == 0 {
return NewLocAppError("Post.IsValid", "model.post.is_valid.create_at.app_error", nil, "id="+o.Id)
}
if o.UpdateAt == 0 {
return NewLocAppError("Post.IsValid", "model.post.is_valid.update_at.app_error", nil, "id="+o.Id)
}
if len(o.UserId) != 26 {
return NewLocAppError("Post.IsValid", "model.post.is_valid.user_id.app_error", nil, "")
}
if len(o.ChannelId) != 26 {
return NewLocAppError("Post.IsValid", "model.post.is_valid.channel_id.app_error", nil, "")
}
if !(len(o.RootId) == 26 || len(o.RootId) == 0) {
return NewLocAppError("Post.IsValid", "model.post.is_valid.root_id.app_error", nil, "")
}
if !(len(o.ParentId) == 26 || len(o.ParentId) == 0) {
return NewLocAppError("Post.IsValid", "model.post.is_valid.parent_id.app_error", nil, "")
}
if len(o.ParentId) == 26 && len(o.RootId) == 0 {
return NewLocAppError("Post.IsValid", "model.post.is_valid.root_parent.app_error", nil, "")
}
if !(len(o.OriginalId) == 26 || len(o.OriginalId) == 0) {
return NewLocAppError("Post.IsValid", "model.post.is_valid.original_id.app_error", nil, "")
}
if utf8.RuneCountInString(o.Message) > POST_MESSAGE_MAX_RUNES {
return NewLocAppError("Post.IsValid", "model.post.is_valid.msg.app_error", nil, "id="+o.Id)
}
if utf8.RuneCountInString(o.Hashtags) > POST_HASHTAGS_MAX_RUNES {
return NewLocAppError("Post.IsValid", "model.post.is_valid.hashtags.app_error", nil, "id="+o.Id)
}
// should be removed once more message types are supported
if !(o.Type == POST_DEFAULT || o.Type == POST_JOIN_LEAVE || o.Type == POST_ADD_REMOVE || o.Type == POST_SLACK_ATTACHMENT || o.Type == POST_HEADER_CHANGE) {
return NewLocAppError("Post.IsValid", "model.post.is_valid.type.app_error", nil, "id="+o.Type)
}
if utf8.RuneCountInString(ArrayToJson(o.Filenames)) > POST_FILENAMES_MAX_RUNES {
return NewLocAppError("Post.IsValid", "model.post.is_valid.filenames.app_error", nil, "id="+o.Id)
}
if utf8.RuneCountInString(ArrayToJson(o.FileIds)) > POST_FILEIDS_MAX_RUNES {
return NewLocAppError("Post.IsValid", "model.post.is_valid.file_ids.app_error", nil, "id="+o.Id)
}
if utf8.RuneCountInString(StringInterfaceToJson(o.Props)) > POST_PROPS_MAX_RUNES {
return NewLocAppError("Post.IsValid", "model.post.is_valid.props.app_error", nil, "id="+o.Id)
}
return nil
}
func (o *Post) PreSave() {
if o.Id == "" {
o.Id = NewId()
}
o.OriginalId = ""
if o.CreateAt == 0 {
o.CreateAt = GetMillis()
}
o.UpdateAt = o.CreateAt
if o.Props == nil {
o.Props = make(map[string]interface{})
}
if o.Filenames == nil {
o.Filenames = []string{}
}
if o.FileIds == nil {
o.FileIds = []string{}
}
}
func (o *Post) MakeNonNil() {
if o.Props == nil {
o.Props = make(map[string]interface{})
}
}
func (o *Post) AddProp(key string, value interface{}) {
o.MakeNonNil()
o.Props[key] = value
}
func (o *Post) IsSystemMessage() bool {
return len(o.Type) >= len(POST_SYSTEM_MESSAGE_PREFIX) && o.Type[:len(POST_SYSTEM_MESSAGE_PREFIX)] == POST_SYSTEM_MESSAGE_PREFIX
}