MM-60987: Move message_export code to monorepo (#28674)
* move message_export code to monorepo * update license headers * moving over `dedicated filestore` (#1772) from enterprise master
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
1d04a2292d
Коммит
b8e462e198
155
server/enterprise/message_export/common_export/common_export.go
Обычный файл
155
server/enterprise/message_export/common_export/common_export.go
Обычный файл
@@ -0,0 +1,155 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.enterprise for license information.
|
||||
|
||||
package common_export
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/mattermost/mattermost/server/public/model"
|
||||
)
|
||||
|
||||
const MissingFileMessage = "File missing for post; cannot copy file to archive"
|
||||
|
||||
type ChannelMemberJoin struct {
|
||||
UserId string
|
||||
IsBot bool
|
||||
Email string
|
||||
Username string
|
||||
Datetime int64
|
||||
}
|
||||
|
||||
type ChannelMemberLeave struct {
|
||||
UserId string
|
||||
IsBot bool
|
||||
Email string
|
||||
Username string
|
||||
Datetime int64
|
||||
}
|
||||
|
||||
type ChannelMember struct {
|
||||
UserId string
|
||||
IsBot bool
|
||||
Email string
|
||||
Username string
|
||||
}
|
||||
type ChannelMembers map[string]ChannelMember
|
||||
type MembersByChannel map[string]ChannelMembers
|
||||
|
||||
type MetadataChannel struct {
|
||||
TeamId *string
|
||||
TeamName *string
|
||||
TeamDisplayName *string
|
||||
ChannelId string
|
||||
ChannelName string
|
||||
ChannelDisplayName string
|
||||
ChannelType model.ChannelType
|
||||
RoomId string
|
||||
StartTime int64
|
||||
EndTime int64
|
||||
MessagesCount int
|
||||
AttachmentsCount int
|
||||
}
|
||||
|
||||
type Metadata struct {
|
||||
Channels map[string]MetadataChannel
|
||||
MessagesCount int
|
||||
AttachmentsCount int
|
||||
StartTime int64
|
||||
EndTime int64
|
||||
}
|
||||
|
||||
func (metadata *Metadata) Update(post *model.MessageExport, attachments int) {
|
||||
channelMetadata, ok := metadata.Channels[*post.ChannelId]
|
||||
if !ok {
|
||||
channelMetadata = MetadataChannel{
|
||||
TeamId: post.TeamId,
|
||||
TeamName: post.TeamName,
|
||||
TeamDisplayName: post.TeamDisplayName,
|
||||
ChannelId: *post.ChannelId,
|
||||
ChannelName: *post.ChannelName,
|
||||
ChannelDisplayName: *post.ChannelDisplayName,
|
||||
ChannelType: *post.ChannelType,
|
||||
RoomId: fmt.Sprintf("%v - %v", ChannelTypeDisplayName(*post.ChannelType), *post.ChannelId),
|
||||
StartTime: *post.PostCreateAt,
|
||||
MessagesCount: 0,
|
||||
AttachmentsCount: 0,
|
||||
}
|
||||
}
|
||||
|
||||
channelMetadata.EndTime = *post.PostCreateAt
|
||||
channelMetadata.AttachmentsCount += attachments
|
||||
metadata.AttachmentsCount += attachments
|
||||
channelMetadata.MessagesCount += 1
|
||||
metadata.MessagesCount += 1
|
||||
if metadata.StartTime == 0 {
|
||||
metadata.StartTime = *post.PostCreateAt
|
||||
}
|
||||
metadata.EndTime = *post.PostCreateAt
|
||||
metadata.Channels[*post.ChannelId] = channelMetadata
|
||||
}
|
||||
|
||||
func GetJoinsAndLeavesForChannel(startTime int64, endTime int64, channelMembersHistory []*model.ChannelMemberHistoryResult, channelMembers ChannelMembers) ([]ChannelMemberJoin, []ChannelMemberLeave) {
|
||||
joins := []ChannelMemberJoin{}
|
||||
leaves := []ChannelMemberLeave{}
|
||||
|
||||
alreadyJoined := map[string]bool{}
|
||||
for _, cmh := range channelMembersHistory {
|
||||
if cmh.UserDeleteAt > 0 && cmh.UserDeleteAt < startTime {
|
||||
continue
|
||||
}
|
||||
|
||||
if cmh.JoinTime > endTime {
|
||||
continue
|
||||
}
|
||||
|
||||
if cmh.LeaveTime != nil && *cmh.LeaveTime < startTime {
|
||||
continue
|
||||
}
|
||||
|
||||
if cmh.JoinTime <= endTime {
|
||||
joins = append(joins, ChannelMemberJoin{
|
||||
UserId: cmh.UserId,
|
||||
IsBot: cmh.IsBot,
|
||||
Email: cmh.UserEmail,
|
||||
Username: cmh.Username,
|
||||
Datetime: cmh.JoinTime,
|
||||
})
|
||||
alreadyJoined[cmh.UserId] = true
|
||||
}
|
||||
|
||||
if cmh.LeaveTime != nil && *cmh.LeaveTime <= endTime {
|
||||
leaves = append(leaves, ChannelMemberLeave{
|
||||
UserId: cmh.UserId,
|
||||
IsBot: cmh.IsBot,
|
||||
Email: cmh.UserEmail,
|
||||
Username: cmh.Username,
|
||||
Datetime: *cmh.LeaveTime,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
for _, member := range channelMembers {
|
||||
if alreadyJoined[member.UserId] {
|
||||
continue
|
||||
}
|
||||
|
||||
joins = append(joins, ChannelMemberJoin{
|
||||
UserId: member.UserId,
|
||||
IsBot: member.IsBot,
|
||||
Email: member.Email,
|
||||
Username: member.Username,
|
||||
Datetime: startTime,
|
||||
})
|
||||
}
|
||||
return joins, leaves
|
||||
}
|
||||
|
||||
func ChannelTypeDisplayName(channelType model.ChannelType) string {
|
||||
return map[model.ChannelType]string{
|
||||
model.ChannelTypeOpen: "public",
|
||||
model.ChannelTypePrivate: "private",
|
||||
model.ChannelTypeDirect: "direct",
|
||||
model.ChannelTypeGroup: "group",
|
||||
}[channelType]
|
||||
}
|
||||
237
server/enterprise/message_export/common_export/common_export_test.go
Обычный файл
237
server/enterprise/message_export/common_export/common_export_test.go
Обычный файл
@@ -0,0 +1,237 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.enterprise for license information.
|
||||
|
||||
package common_export
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/mattermost/mattermost/server/public/model"
|
||||
)
|
||||
|
||||
func TestUpdateMetadata(t *testing.T) {
|
||||
metadata := Metadata{
|
||||
Channels: map[string]MetadataChannel{},
|
||||
MessagesCount: 0,
|
||||
AttachmentsCount: 0,
|
||||
StartTime: 0,
|
||||
EndTime: 0,
|
||||
}
|
||||
|
||||
testString := "test"
|
||||
chanTypeDirect := model.ChannelTypeDirect
|
||||
createdAt := int64(12345)
|
||||
|
||||
post := model.MessageExport{
|
||||
TeamId: &testString,
|
||||
TeamName: &testString,
|
||||
TeamDisplayName: &testString,
|
||||
|
||||
ChannelId: &testString,
|
||||
ChannelName: &testString,
|
||||
ChannelDisplayName: &testString,
|
||||
ChannelType: &chanTypeDirect,
|
||||
|
||||
UserId: &testString,
|
||||
UserEmail: &testString,
|
||||
Username: &testString,
|
||||
|
||||
PostId: &testString,
|
||||
PostCreateAt: &createdAt,
|
||||
PostMessage: &testString,
|
||||
PostType: &testString,
|
||||
PostOriginalId: &testString,
|
||||
PostFileIds: []string{},
|
||||
}
|
||||
metadata.Update(&post, 2)
|
||||
|
||||
assert.Len(t, metadata.Channels, 1)
|
||||
assert.Equal(t, 1, metadata.Channels["test"].MessagesCount)
|
||||
assert.Equal(t, 2, metadata.Channels["test"].AttachmentsCount)
|
||||
assert.Equal(t, 1, metadata.MessagesCount)
|
||||
assert.Equal(t, 2, metadata.AttachmentsCount)
|
||||
|
||||
metadata.Update(&post, 2)
|
||||
|
||||
assert.Len(t, metadata.Channels, 1)
|
||||
assert.Equal(t, 2, metadata.Channels["test"].MessagesCount)
|
||||
assert.Equal(t, 4, metadata.Channels["test"].AttachmentsCount)
|
||||
assert.Equal(t, 2, metadata.MessagesCount)
|
||||
assert.Equal(t, 4, metadata.AttachmentsCount)
|
||||
|
||||
testString2 := "test2"
|
||||
post.ChannelId = &testString2
|
||||
|
||||
metadata.Update(&post, 2)
|
||||
|
||||
assert.Len(t, metadata.Channels, 2)
|
||||
assert.Equal(t, 2, metadata.Channels["test"].MessagesCount)
|
||||
assert.Equal(t, 4, metadata.Channels["test"].AttachmentsCount)
|
||||
assert.Equal(t, 1, metadata.Channels["test2"].MessagesCount)
|
||||
assert.Equal(t, 2, metadata.Channels["test2"].AttachmentsCount)
|
||||
assert.Equal(t, 3, metadata.MessagesCount)
|
||||
assert.Equal(t, 6, metadata.AttachmentsCount)
|
||||
}
|
||||
|
||||
func TestGetJoinsAndLeavesForChannel(t *testing.T) {
|
||||
channel := MetadataChannel{
|
||||
StartTime: 100,
|
||||
EndTime: 200,
|
||||
ChannelId: "good-request-1",
|
||||
TeamId: model.NewPointer("test"),
|
||||
TeamName: model.NewPointer("test"),
|
||||
TeamDisplayName: model.NewPointer("test"),
|
||||
ChannelName: "test",
|
||||
ChannelDisplayName: "test",
|
||||
ChannelType: "O",
|
||||
}
|
||||
|
||||
tt := []struct {
|
||||
name string
|
||||
channel MetadataChannel
|
||||
membersHistory []*model.ChannelMemberHistoryResult
|
||||
usersInPosts ChannelMembers
|
||||
expectedJoins int
|
||||
expectedLeaves int
|
||||
}{
|
||||
{
|
||||
name: "no-joins-no-leaves",
|
||||
channel: channel,
|
||||
membersHistory: nil,
|
||||
usersInPosts: nil,
|
||||
expectedJoins: 0,
|
||||
expectedLeaves: 0,
|
||||
},
|
||||
{
|
||||
name: "joins-and-leaves-outside-the-range",
|
||||
channel: channel,
|
||||
membersHistory: []*model.ChannelMemberHistoryResult{
|
||||
{JoinTime: 1, LeaveTime: model.NewPointer(int64(10)), UserId: "test", UserEmail: "test", Username: "test"},
|
||||
{JoinTime: 250, LeaveTime: model.NewPointer(int64(260)), UserId: "test", UserEmail: "test", Username: "test"},
|
||||
{JoinTime: 300, UserId: "test", UserEmail: "test", Username: "test"},
|
||||
},
|
||||
usersInPosts: nil,
|
||||
expectedJoins: 0,
|
||||
expectedLeaves: 0,
|
||||
},
|
||||
{
|
||||
name: "join-and-leave-during-the-range",
|
||||
channel: channel,
|
||||
membersHistory: []*model.ChannelMemberHistoryResult{
|
||||
{JoinTime: 100, LeaveTime: model.NewPointer(int64(150)), UserId: "test", UserEmail: "test", Username: "test"},
|
||||
},
|
||||
usersInPosts: nil,
|
||||
expectedJoins: 1,
|
||||
expectedLeaves: 1,
|
||||
},
|
||||
{
|
||||
name: "join-during-and-leave-after-the-range",
|
||||
channel: channel,
|
||||
membersHistory: []*model.ChannelMemberHistoryResult{
|
||||
{JoinTime: 150, LeaveTime: model.NewPointer(int64(300)), UserId: "test", UserEmail: "test", Username: "test"},
|
||||
},
|
||||
usersInPosts: nil,
|
||||
expectedJoins: 1,
|
||||
expectedLeaves: 0,
|
||||
},
|
||||
{
|
||||
name: "join-before-and-leave-during-the-range",
|
||||
channel: channel,
|
||||
membersHistory: []*model.ChannelMemberHistoryResult{
|
||||
{JoinTime: 99, LeaveTime: model.NewPointer(int64(150)), UserId: "test", UserEmail: "test", Username: "test"},
|
||||
},
|
||||
usersInPosts: nil,
|
||||
expectedJoins: 1,
|
||||
expectedLeaves: 1,
|
||||
},
|
||||
{
|
||||
name: "join-before-and-leave-after-the-range",
|
||||
channel: channel,
|
||||
membersHistory: []*model.ChannelMemberHistoryResult{
|
||||
{JoinTime: 99, LeaveTime: model.NewPointer(int64(350)), UserId: "test", UserEmail: "test", Username: "test"},
|
||||
},
|
||||
usersInPosts: nil,
|
||||
expectedJoins: 1,
|
||||
expectedLeaves: 0,
|
||||
},
|
||||
{
|
||||
name: "implicit-joins",
|
||||
channel: channel,
|
||||
membersHistory: nil,
|
||||
usersInPosts: ChannelMembers{
|
||||
"test1": ChannelMember{UserId: "test1", Email: "test1", Username: "test1"},
|
||||
"test2": ChannelMember{UserId: "test2", Email: "test2", Username: "test2"},
|
||||
},
|
||||
expectedJoins: 2,
|
||||
expectedLeaves: 0,
|
||||
},
|
||||
{
|
||||
name: "implicit-joins-with-explicit-joins",
|
||||
channel: channel,
|
||||
membersHistory: []*model.ChannelMemberHistoryResult{
|
||||
{JoinTime: 130, LeaveTime: model.NewPointer(int64(150)), UserId: "test1", UserEmail: "test1", Username: "test1"},
|
||||
{JoinTime: 130, LeaveTime: model.NewPointer(int64(150)), UserId: "test3", UserEmail: "test3", Username: "test3"},
|
||||
},
|
||||
usersInPosts: ChannelMembers{
|
||||
"test1": ChannelMember{UserId: "test1", Email: "test1", Username: "test1"},
|
||||
"test2": ChannelMember{UserId: "test2", Email: "test2", Username: "test2"},
|
||||
},
|
||||
expectedJoins: 3,
|
||||
expectedLeaves: 2,
|
||||
},
|
||||
{
|
||||
name: "join-leave-and-join-again",
|
||||
channel: channel,
|
||||
membersHistory: []*model.ChannelMemberHistoryResult{
|
||||
{JoinTime: 130, LeaveTime: model.NewPointer(int64(150)), UserId: "test1", UserEmail: "test1", Username: "test1"},
|
||||
{JoinTime: 160, LeaveTime: model.NewPointer(int64(180)), UserId: "test1", UserEmail: "test1", Username: "test1"},
|
||||
},
|
||||
usersInPosts: nil,
|
||||
expectedJoins: 2,
|
||||
expectedLeaves: 2,
|
||||
},
|
||||
{
|
||||
name: "deactivated-members-dont-show",
|
||||
channel: channel,
|
||||
membersHistory: []*model.ChannelMemberHistoryResult{
|
||||
{JoinTime: 130, LeaveTime: model.NewPointer(int64(150)), UserId: "test1", UserEmail: "test1", Username: "test1", UserDeleteAt: 50},
|
||||
{JoinTime: 160, LeaveTime: model.NewPointer(int64(180)), UserId: "test1", UserEmail: "test1", Username: "test1", UserDeleteAt: 50},
|
||||
},
|
||||
usersInPosts: nil,
|
||||
expectedJoins: 0,
|
||||
expectedLeaves: 0,
|
||||
},
|
||||
{
|
||||
name: "deactivated-members-show-if-deleted-after-latest-export",
|
||||
channel: channel,
|
||||
membersHistory: []*model.ChannelMemberHistoryResult{
|
||||
{JoinTime: 130, LeaveTime: model.NewPointer(int64(150)), UserId: "test1", UserEmail: "test1", Username: "test1", UserDeleteAt: 150},
|
||||
{JoinTime: 160, LeaveTime: model.NewPointer(int64(180)), UserId: "test1", UserEmail: "test1", Username: "test1", UserDeleteAt: 150},
|
||||
},
|
||||
usersInPosts: nil,
|
||||
expectedJoins: 2,
|
||||
expectedLeaves: 2,
|
||||
},
|
||||
{
|
||||
name: "deactivated-members-show-and-dont-show",
|
||||
channel: channel,
|
||||
membersHistory: []*model.ChannelMemberHistoryResult{
|
||||
{JoinTime: 130, LeaveTime: model.NewPointer(int64(150)), UserId: "test1", UserEmail: "test1", Username: "test1", UserDeleteAt: 50},
|
||||
{JoinTime: 160, LeaveTime: model.NewPointer(int64(180)), UserId: "test1", UserEmail: "test1", Username: "test1", UserDeleteAt: 150},
|
||||
},
|
||||
usersInPosts: nil,
|
||||
expectedJoins: 1,
|
||||
expectedLeaves: 1,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tt {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
joins, leaves := GetJoinsAndLeavesForChannel(tc.channel.StartTime, tc.channel.EndTime, tc.membersHistory, tc.usersInPosts)
|
||||
assert.Len(t, joins, tc.expectedJoins)
|
||||
assert.Len(t, leaves, tc.expectedLeaves)
|
||||
})
|
||||
}
|
||||
}
|
||||
Ссылка в новой задаче
Block a user