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
Этот коммит содержится в:
Christopher Poile
2024-10-15 13:03:31 -04:00
коммит произвёл GitHub
родитель 1d04a2292d
Коммит b8e462e198
24 изменённых файлов: 7351 добавлений и 8 удалений

Просмотреть файл

@@ -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]
}

Просмотреть файл

@@ -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)
})
}
}