Move internal/payload to pkg/payload

This commit is contained in:
Denis Arh
2019-10-01 17:51:39 +02:00
parent 5e3f3f1342
commit ebfa4cbffd
33 changed files with 29 additions and 28 deletions
+12
View File
@@ -0,0 +1,12 @@
package payload
import (
"encoding/json"
"github.com/cortezaproject/corteza-server/pkg/payload/incoming"
)
func Unmarshal(raw []byte) (*incoming.Payload, error) {
var p = &incoming.Payload{}
return p, json.Unmarshal(raw, p)
}
+32
View File
@@ -0,0 +1,32 @@
package incoming
type (
Channels struct{}
ChannelJoin struct {
ChannelID string `json:"id"`
}
ChannelPart struct {
ChannelID string `json:"id"`
}
// @deprecated
ChannelViewRecord struct {
ChannelID uint64 `json:"channelID,string,omitempty"`
LastMessageID uint64 `json:"lastMessageID,string,omitempty"`
}
ChannelCreate struct {
Name *string `json:"name"`
Topic *string `json:"topic"`
Type *string `json:"type"`
}
ChannelUpdate struct {
ID string `json:"id"`
Name *string `json:"name"`
Topic *string `json:"topic"`
Type *string `json:"type"`
}
)
+18
View File
@@ -0,0 +1,18 @@
package incoming
type (
MessageCreate struct {
ChannelID string `json:"channelID"`
ReplyTo uint64 `json:"replyTo,omitempty,string"`
Message string `json:"message"`
}
MessageUpdate struct {
ID string `json:"messageID"`
Message string `json:"message"`
}
MessageDelete struct {
ID string `json:"messageID"`
}
)
+20
View File
@@ -0,0 +1,20 @@
package incoming
type Payload struct {
// Channel actions
*Channels `json:"channels"`
*ChannelJoin `json:"joinChannel"`
*ChannelPart `json:"partChannel"`
*ChannelCreate `json:"createChannel"`
*ChannelUpdate `json:"updateChannel"`
*ChannelViewRecord `json:"recordChannelView"`
// Message actions
*MessageCreate `json:"createMessage"`
*MessageUpdate `json:"updateMessage"`
*MessageDelete `json:"deleteMessage"`
*Users `json:"getUsers"`
}
+5
View File
@@ -0,0 +1,5 @@
package incoming
type (
Users struct{}
)
+312
View File
@@ -0,0 +1,312 @@
package payload
import (
"context"
"fmt"
"net/url"
messagingTypes "github.com/cortezaproject/corteza-server/messaging/types"
"github.com/cortezaproject/corteza-server/pkg/auth"
"github.com/cortezaproject/corteza-server/pkg/payload/outgoing"
systemTypes "github.com/cortezaproject/corteza-server/system/types"
)
const (
attachmentURL = "/attachment/%d/original/%s"
attachmentPreviewURL = "/attachment/%d/preview.%s"
)
func Activity(a *messagingTypes.Activity) *outgoing.Activity {
return &outgoing.Activity{
MessageID: a.MessageID,
ChannelID: a.ChannelID,
Kind: a.Kind,
UserID: a.UserID,
}
}
func Message(ctx context.Context, msg *messagingTypes.Message) *outgoing.Message {
var currentUserID = auth.GetIdentityFromContext(ctx).Identity()
var canEdit = msg.Type.IsEditable() && msg.UserID == currentUserID
var canReply = msg.Type.IsRepliable() && msg.ReplyTo == 0
return &outgoing.Message{
ID: msg.ID,
Type: string(msg.Type),
ChannelID: msg.ChannelID,
Message: msg.Message,
UserID: msg.UserID,
ReplyTo: msg.ReplyTo,
Replies: msg.Replies,
RepliesFrom: Uint64stoa(msg.RepliesFrom),
Unread: MessageUnread(msg.Unread),
Attachment: Attachment(msg.Attachment, currentUserID),
Mentions: messageMentionSet(msg.Mentions),
Reactions: messageReactionSumSet(msg.Flags),
IsPinned: msg.Flags.IsPinned(),
IsBookmarked: msg.Flags.IsBookmarked(currentUserID),
CanReply: canReply,
CanEdit: canEdit,
CanDelete: canEdit,
CreatedAt: msg.CreatedAt,
UpdatedAt: msg.UpdatedAt,
DeletedAt: msg.DeletedAt,
}
}
func Messages(ctx context.Context, msg messagingTypes.MessageSet) *outgoing.MessageSet {
msgs := make([]*outgoing.Message, len(msg))
for k, m := range msg {
msgs[k] = Message(ctx, m)
}
retval := outgoing.MessageSet(msgs)
return &retval
}
func messageReactionSumSet(flags messagingTypes.MessageFlagSet) outgoing.MessageReactionSumSet {
var (
rr = make([]*outgoing.MessageReactionSum, 0)
rIndex = map[string]int{}
has bool
i int
)
_ = flags.Walk(func(flag *messagingTypes.MessageFlag) error {
if flag.IsReaction() {
r := &outgoing.MessageReactionSum{Reaction: flag.Flag, UserIDs: []string{}, Count: 0}
if i, has = rIndex[flag.Flag]; !has {
i, rIndex[flag.Flag] = len(rr), len(rr)
rr = append(rr, r)
}
rr[i].UserIDs = append(rr[i].UserIDs, Uint64toa(flag.UserID))
rr[i].Count++
}
return nil
})
return rr
}
// Converts slice of mentions into slice of strings containing all user IDs
// These are IDs of users mentioned in the message
func messageMentionSet(mm messagingTypes.MentionSet) outgoing.MessageMentionSet {
return Uint64stoa(mm.UserIDs())
}
func MessageReaction(f *messagingTypes.MessageFlag) *outgoing.MessageReaction {
return &outgoing.MessageReaction{
UserID: f.UserID,
MessageID: f.MessageID,
Reaction: f.Flag,
}
}
func MessageReactionRemoved(f *messagingTypes.MessageFlag) *outgoing.MessageReactionRemoved {
return &outgoing.MessageReactionRemoved{
UserID: f.UserID,
MessageID: f.MessageID,
Reaction: f.Flag,
}
}
func MessagePin(f *messagingTypes.MessageFlag) *outgoing.MessagePin {
return &outgoing.MessagePin{
UserID: f.UserID,
MessageID: f.MessageID,
}
}
func MessagePinRemoved(f *messagingTypes.MessageFlag) *outgoing.MessagePinRemoved {
return &outgoing.MessagePinRemoved{
UserID: f.UserID,
MessageID: f.MessageID,
}
}
func Channel(ch *messagingTypes.Channel) *outgoing.Channel {
var flag = messagingTypes.ChannelMembershipFlagNone
if ch.Member != nil {
flag = ch.Member.Flag
}
return &outgoing.Channel{
ID: Uint64toa(ch.ID),
Name: ch.Name,
LastMessageID: Uint64toa(ch.LastMessageID),
Topic: ch.Topic,
Type: string(ch.Type),
MembershipFlag: string(flag),
MembershipPolicy: string(ch.MembershipPolicy),
Members: Uint64stoa(ch.Members),
Unread: ChannelUnread(ch.Unread),
CanJoin: ch.CanJoin,
CanPart: ch.CanPart,
CanObserve: ch.CanObserve,
CanSendMessages: ch.CanSendMessages,
CanDeleteMessages: ch.CanDeleteMessages,
CanChangeMembers: ch.CanChangeMembers,
CanChangeMembershipPolicy: ch.CanChangeMembershipPolicy,
CanUpdate: ch.CanUpdate,
CanArchive: ch.CanArchive,
CanDelete: ch.CanDelete,
CreatedAt: ch.CreatedAt,
UpdatedAt: ch.UpdatedAt,
ArchivedAt: ch.ArchivedAt,
DeletedAt: ch.DeletedAt,
}
}
func Channels(channels messagingTypes.ChannelSet) *outgoing.ChannelSet {
cc := make([]*outgoing.Channel, len(channels))
for k, c := range channels {
cc[k] = Channel(c)
}
retval := outgoing.ChannelSet(cc)
return &retval
}
func ChannelMember(m *messagingTypes.ChannelMember) *outgoing.ChannelMember {
return &outgoing.ChannelMember{
UserID: m.UserID,
Type: string(m.Type),
CreatedAt: m.CreatedAt,
UpdatedAt: m.UpdatedAt,
}
}
func ChannelMembers(members messagingTypes.ChannelMemberSet) *outgoing.ChannelMemberSet {
mm := make([]*outgoing.ChannelMember, len(members))
for k, c := range members {
mm[k] = ChannelMember(c)
}
retval := outgoing.ChannelMemberSet(mm)
return &retval
}
func Unread(v *messagingTypes.Unread) *outgoing.Unread {
if v == nil {
return nil
}
return &outgoing.Unread{
ChannelID: v.ChannelID,
ThreadID: v.ReplyTo,
LastMessageID: v.LastMessageID,
Count: v.Count,
ThreadCount: v.ThreadCount,
ThreadTotal: v.ThreadTotal,
}
}
func ChannelUnread(v *messagingTypes.Unread) *outgoing.Unread {
if v == nil || (v.Count == 0 && v.ThreadCount == 0) {
return nil
}
return &outgoing.Unread{
LastMessageID: v.LastMessageID,
Count: v.Count,
ThreadCount: v.ThreadCount,
ThreadTotal: v.ThreadTotal,
}
}
func MessageUnread(v *messagingTypes.Unread) *outgoing.Unread {
if v == nil || v.Count == 0 {
return nil
}
return &outgoing.Unread{
LastMessageID: v.LastMessageID,
Count: v.Count,
}
}
func ChannelJoin(channelID, userID uint64) *outgoing.ChannelJoin {
return &outgoing.ChannelJoin{
ID: Uint64toa(channelID),
UserID: Uint64toa(userID),
}
}
func ChannelPart(channelID, userID uint64) *outgoing.ChannelPart {
return &outgoing.ChannelPart{
ID: Uint64toa(channelID),
UserID: Uint64toa(userID),
}
}
func User(user *systemTypes.User) *outgoing.User {
if user == nil {
return nil
}
return &outgoing.User{
ID: user.ID,
Name: user.Name,
Handle: user.Handle,
Username: user.Username,
Email: user.Email,
}
}
func Attachment(in *messagingTypes.Attachment, userID uint64) *outgoing.Attachment {
if in == nil {
return nil
}
var (
signParams = fmt.Sprintf("?sign=%s&userID=%d", auth.DefaultSigner.Sign(userID, in.ID), userID)
preview string
)
if in.Meta.Preview != nil {
var ext = in.Meta.Preview.Extension
if ext == "" {
ext = "jpg"
}
preview = fmt.Sprintf(attachmentPreviewURL, in.ID, ext)
}
return &outgoing.Attachment{
ID: Uint64toa(in.ID),
UserID: Uint64toa(in.UserID),
Url: fmt.Sprintf(attachmentURL, in.ID, url.PathEscape(in.Name)) + signParams,
PreviewUrl: preview + signParams,
Meta: in.Meta,
Name: in.Name,
CreatedAt: in.CreatedAt,
UpdatedAt: in.UpdatedAt,
}
}
func Command(cmd *messagingTypes.Command) *outgoing.Command {
if cmd == nil {
return nil
}
return &outgoing.Command{
Name: cmd.Name,
Description: cmd.Description,
}
}
func Commands(cc messagingTypes.CommandSet) *outgoing.CommandSet {
out := make([]*outgoing.Command, len(cc))
for k, m := range cc {
out[k] = Command(m)
}
retval := outgoing.CommandSet(out)
return &retval
}
+18
View File
@@ -0,0 +1,18 @@
package outgoing
import "encoding/json"
type (
// where the activity is and who is active
Activity struct {
UserID uint64 `json:"userID,string"`
Kind string `json:"kind,omitempty"`
MessageID uint64 `json:"messageID,string,omitempty"`
ChannelID uint64 `json:"channelID,string,omitempty"`
Present bool `json:"present"`
}
)
func (p *Activity) EncodeMessage() ([]byte, error) {
return json.Marshal(Payload{Activity: p})
}
+20
View File
@@ -0,0 +1,20 @@
package outgoing
import (
"time"
)
type (
Attachment struct {
ID string `json:"attachmentID"`
UserID string `json:"userID"`
Url string `json:"url"`
PreviewUrl string `json:"previewUrl,omitempty"`
Meta interface{} `json:"meta"`
Name string `json:"name"`
CreatedAt time.Time `json:"createdAt,omitempty"`
UpdatedAt *time.Time `json:"updatedAt,omitempty"`
}
AttachmentSet []*Attachment
)
+71
View File
@@ -0,0 +1,71 @@
package outgoing
import (
"encoding/json"
"time"
)
type (
ChannelJoin struct {
// ID of the channel user is joining
ID string `json:"channelID"`
// ID of the user that is joining
UserID string `json:"userID"`
}
ChannelPart struct {
// Channel to part (nil) for ALL channels
ID string `json:"channelID"`
// Who is parting
UserID string `json:"userID"`
}
Channel struct {
// Channel to part (nil) for ALL channels
ID string `json:"channelID"`
Name string `json:"name"`
Topic string `json:"topic"`
Type string `json:"type"`
MembershipPolicy string `json:"membershipPolicy"`
LastMessageID string `json:"lastMessageID"`
Unread *Unread `json:"unread,omitempty"`
Members []string `json:"members,omitempty"`
MembershipFlag string `json:"membershipFlag"`
CanJoin bool `json:"canJoin"`
CanPart bool `json:"canPart"`
CanObserve bool `json:"canObserve"`
CanSendMessages bool `json:"canSendMessages"`
CanDeleteMessages bool `json:"canDeleteMessages"`
CanChangeMembers bool `json:"canChangeMembers"`
CanChangeMembershipPolicy bool `json:"canChangeMembershipPolicy"`
CanUpdate bool `json:"canUpdate"`
CanArchive bool `json:"canArchive"`
CanDelete bool `json:"canDelete"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt *time.Time `json:"updatedAt,omitempty"`
ArchivedAt *time.Time `json:"archivedAt,omitempty"`
DeletedAt *time.Time `json:"deletedAt,omitempty"`
}
ChannelSet []*Channel
)
func (p *ChannelJoin) EncodeMessage() ([]byte, error) {
return json.Marshal(Payload{ChannelJoin: p})
}
func (p *ChannelPart) EncodeMessage() ([]byte, error) {
return json.Marshal(Payload{ChannelPart: p})
}
func (p *Channel) EncodeMessage() ([]byte, error) {
return json.Marshal(Payload{Channel: p})
}
func (p *ChannelSet) EncodeMessage() ([]byte, error) {
return json.Marshal(Payload{ChannelSet: p})
}
+26
View File
@@ -0,0 +1,26 @@
package outgoing
import (
"encoding/json"
"time"
)
type (
ChannelMember struct {
// Channel to part (nil) for ALL channels
UserID uint64 `json:"userID,string"`
Type string `json:"type"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt *time.Time `json:"updatedAt,omitempty"`
}
ChannelMemberSet []*ChannelMember
)
func (p *ChannelMember) EncodeMessage() ([]byte, error) {
return json.Marshal(Payload{ChannelMember: p})
}
func (p *ChannelMemberSet) EncodeMessage() ([]byte, error) {
return json.Marshal(Payload{ChannelMemberSet: p})
}
+18
View File
@@ -0,0 +1,18 @@
package outgoing
import (
"encoding/json"
)
type (
Command struct {
Name string `json:"name"`
Description string `json:"description"`
}
CommandSet []*Command
)
func (p *CommandSet) EncodeMessage() ([]byte, error) {
return json.Marshal(Payload{CommandSet: p})
}
+19
View File
@@ -0,0 +1,19 @@
package outgoing
import (
"encoding/json"
)
type (
Error struct {
Message string `json:"m"`
}
)
func (p *Error) EncodeMessage() ([]byte, error) {
return json.Marshal(Payload{Error: p})
}
func NewError(err error) *Error {
return &Error{Message: err.Error()}
}
+89
View File
@@ -0,0 +1,89 @@
package outgoing
import (
"encoding/json"
"time"
)
type (
Message struct {
ID uint64 `json:"messageID,string"`
Type string `json:"type"`
Message string `json:"message"`
ChannelID uint64 `json:"channelID,string"`
UserID uint64 `json:"userID,string"`
ReplyTo uint64 `json:"replyTo,omitempty,string"`
Replies uint `json:"replies,omitempty"`
RepliesFrom []string `json:"repliesFrom,omitempty"`
Unread *Unread `json:"unread,omitempty"`
Attachment *Attachment `json:"att,omitempty"`
Mentions MessageMentionSet `json:"mentions,omitempty"`
Reactions MessageReactionSumSet `json:"reactions,omitempty"`
IsBookmarked bool `json:"isBookmarked"`
IsPinned bool `json:"isPinned"`
CanReply bool `json:"canReply"`
CanEdit bool `json:"canEdit"`
CanDelete bool `json:"canDelete"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt *time.Time `json:"updatedAt,omitempty"`
DeletedAt *time.Time `json:"deletedAt,omitempty"`
}
MessageSet []*Message
MessageMentionSet []string
// Used for single reaction event notification
MessageReactionSum struct {
UserIDs []string `json:"userIDs"`
Reaction string `json:"reaction"`
Count uint `json:"count"`
}
MessageReactionSumSet []*MessageReactionSum
// Used for single reaction event notification
MessageReaction struct {
MessageID uint64 `json:"messageID,string"`
UserID uint64 `json:"userID,string"`
Reaction string `json:"reaction"`
}
MessageReactionRemoved MessageReaction
// Used for single pin/unpin event notification
MessagePin struct {
MessageID uint64 `json:"messageID,string"`
UserID uint64 `json:"userID,string"`
}
MessagePinRemoved MessagePin
)
func (p *Message) EncodeMessage() ([]byte, error) {
return json.Marshal(Payload{Message: p})
}
func (p *MessageSet) EncodeMessage() ([]byte, error) {
return json.Marshal(Payload{MessageSet: p})
}
func (p *MessageReaction) EncodeMessage() ([]byte, error) {
return json.Marshal(Payload{MessageReaction: p})
}
func (p *MessageReactionRemoved) EncodeMessage() ([]byte, error) {
return json.Marshal(Payload{MessageReactionRemoved: p})
}
func (p *MessagePin) EncodeMessage() ([]byte, error) {
return json.Marshal(Payload{MessagePin: p})
}
func (p *MessagePinRemoved) EncodeMessage() ([]byte, error) {
return json.Marshal(Payload{MessagePinRemoved: p})
}
+35
View File
@@ -0,0 +1,35 @@
package outgoing
type (
Payload struct {
*Error `json:"error,omitempty"`
*Message `json:"message,omitempty"`
*MessageSet `json:"messages,omitempty"`
*Activity `json:"activity,omitempty"`
*MessageReaction `json:"messageReaction,omitempty"`
*MessageReactionRemoved `json:"messageReactionRemoved,omitempty"`
*MessagePin `json:"messagePin,omitempty"`
*MessagePinRemoved `json:"messagePinRemoved,omitempty"`
*ChannelJoin `json:"channelJoin,omitempty"`
*ChannelPart `json:"channelPart,omitempty"`
*Channel `json:"channel,omitempty"`
*ChannelSet `json:"channels,omitempty"`
*Unread `json:"unread,omitempty"`
*ChannelMember `json:"channelMember,omitempty"`
*ChannelMemberSet `json:"channelMembers,omitempty"`
*CommandSet `json:"commands,omitempty"`
}
// This is same-same but different as using the json.Marshaler
// (this one does not cause json.Marshal to call itself)
MessageEncoder interface {
EncodeMessage() ([]byte, error)
}
)
+21
View File
@@ -0,0 +1,21 @@
package outgoing
// @todo need to decide on settings format & structure...
// type (
// SettingValue struct {
// Name string `json:"name"`
// Type SettingType `json:"type"`
// Value interface{} `json:"value"`
// ReadOnly bool `json:"ro"`
// }
//
// Settings []SettingValue
//
// SettingType string
// )
//
// const (
// SettingTypeBool SettingType = "Boolean"
// SettingTypeString SettingType = "String"
// SettingTypeNumber SettingType = "Number"
// )
+20
View File
@@ -0,0 +1,20 @@
package outgoing
import "encoding/json"
type (
Unread struct {
ChannelID uint64 `json:"channelID,string,omitempty"`
ThreadID uint64 `json:"threadID,string,omitempty"`
LastMessageID uint64 `json:"lastMessageID,string,omitempty"`
Count uint32 `json:"count"`
ThreadCount uint32 `json:"threadCount"`
ThreadTotal uint32 `json:"threadTotal,omitempty"`
}
)
func (p *Unread) EncodeMessage() ([]byte, error) {
return json.Marshal(Payload{Unread: p})
}
+14
View File
@@ -0,0 +1,14 @@
package outgoing
type (
User struct {
// Channel to part (nil) for ALL channels
ID uint64 `json:"userID,string"`
Name string `json:"name"`
Email string `json:"email"`
Username string `json:"username"`
Handle string `json:"handle"`
}
UserSet []*User
)
+37
View File
@@ -0,0 +1,37 @@
package payload
import (
"strconv"
)
func Uint64toa(i uint64) string {
return strconv.FormatUint(i, 10)
}
func Uint64stoa(uu []uint64) []string {
ss := make([]string, len(uu))
for i, u := range uu {
ss[i] = Uint64toa(u)
}
return ss
}
// ParseUInt64 parses an string to uint64
func ParseUInt64(s string) uint64 {
if s == "" {
return 0
}
i, _ := strconv.ParseUint(s, 10, 64)
return i
}
// ParseUInt64s parses a slice of strings into a slice of uint64s
func ParseUInt64s(ss []string) []uint64 {
uu := make([]uint64, len(ss))
for i, s := range ss {
uu[i] = ParseUInt64(s)
}
return uu
}