[MM-55726] Create batch report worker, add batch report job for exporting users to CSV (#25832)
* Split out migration logic and create generic BatchWorker * WIP * WIP * POC batch reporting * Oops * Job hookup * Working export to file * PR feedback * Merge'd * Fix error handling * Add API to start report, translations, couple fixes * Add DMs to send reports to users * Merge'd * Update types * A bit of cleanup * Some fixes * Add missing API doc * PR feedback * Fix generated * Fix bug with post creation * PR feedback * Add some tests * PR feedback * Fix lint * Some test changes * Fix tests * Add comment to explain why we forcibly stop * Rework of some tests * Batch report test * Restrict batch exports to Pro and Enterprise licenses * Fix erroneous comment --------- Co-authored-by: Mattermost Build <build@mattermost.com>
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
eac9a39677
Коммит
f7446d7443
107
server/channels/jobs/export_users_to_csv/export_users_to_csv.go
Обычный файл
107
server/channels/jobs/export_users_to_csv/export_users_to_csv.go
Обычный файл
@@ -0,0 +1,107 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package export_users_to_csv
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/mattermost/mattermost/server/public/model"
|
||||
"github.com/mattermost/mattermost/server/v8/channels/jobs"
|
||||
"github.com/mattermost/mattermost/server/v8/channels/store"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
timeBetweenBatches = 1 * time.Second
|
||||
)
|
||||
|
||||
type ExportUsersToCSVAppIFace interface {
|
||||
jobs.BatchReportWorkerAppIFace
|
||||
GetUsersForReporting(filter *model.UserReportOptions) ([]*model.UserReport, *model.AppError)
|
||||
}
|
||||
|
||||
// MakeWorker creates a batch report worker to generate CSV user reports.
|
||||
func MakeWorker(jobServer *jobs.JobServer, store store.Store, app ExportUsersToCSVAppIFace) model.Worker {
|
||||
return jobs.MakeBatchReportWorker(
|
||||
jobServer,
|
||||
store,
|
||||
app,
|
||||
timeBetweenBatches,
|
||||
"csv",
|
||||
[]string{
|
||||
"Id",
|
||||
"Username",
|
||||
"Email",
|
||||
"CreateAt",
|
||||
"Name",
|
||||
"Roles",
|
||||
"LastLogin",
|
||||
"LastStatusAt",
|
||||
"LastPostDate",
|
||||
"DaysActive",
|
||||
"TotalPosts",
|
||||
},
|
||||
getData(app),
|
||||
)
|
||||
}
|
||||
|
||||
// parseJobMetadata parses the opaque job metadata to return the information needed to decide which
|
||||
// batch to process next.
|
||||
func parseJobMetadata(data model.StringMap) (*model.UserReportOptions, error) {
|
||||
startAt, err := strconv.ParseInt(data["start_at"], 10, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
endAt, err := strconv.ParseInt(data["end_at"], 10, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
options := model.UserReportOptions{
|
||||
ReportingBaseOptions: model.ReportingBaseOptions{
|
||||
SortColumn: "Username",
|
||||
PageSize: 100,
|
||||
FromColumnValue: data["last_column_value"],
|
||||
FromId: data["last_user_id"],
|
||||
StartAt: startAt,
|
||||
EndAt: endAt,
|
||||
},
|
||||
}
|
||||
|
||||
return &options, nil
|
||||
}
|
||||
|
||||
// makeJobMetadata encodes the information needed to decide which batch to process next back into
|
||||
// the opaque job metadata.
|
||||
func makeJobMetadata(jobData model.StringMap, lastColumnValue string, userID string) model.StringMap {
|
||||
jobData["last_column_value"] = lastColumnValue
|
||||
jobData["last_user_id"] = userID
|
||||
return jobData
|
||||
}
|
||||
|
||||
func getData(app ExportUsersToCSVAppIFace) func(jobData model.StringMap) ([]model.ReportableObject, model.StringMap, bool, error) {
|
||||
return func(jobData model.StringMap) ([]model.ReportableObject, model.StringMap, bool, error) {
|
||||
filter, err := parseJobMetadata(jobData)
|
||||
if err != nil {
|
||||
return nil, nil, false, errors.Wrap(err, "failed to parse job metadata")
|
||||
}
|
||||
|
||||
users, appErr := app.GetUsersForReporting(filter)
|
||||
if appErr != nil {
|
||||
return nil, nil, false, errors.Wrapf(err, "failed to get the next batch (column_value=%v, user_id=%v)", filter.FromColumnValue, filter.FromId)
|
||||
}
|
||||
|
||||
if len(users) == 0 {
|
||||
return nil, nil, true, nil
|
||||
}
|
||||
|
||||
reportableObjects := []model.ReportableObject{}
|
||||
for i := 0; i < len(users); i++ {
|
||||
reportableObjects = append(reportableObjects, users[i])
|
||||
}
|
||||
|
||||
return reportableObjects, makeJobMetadata(jobData, users[len(users)-1].Username, users[len(users)-1].Id), false, nil
|
||||
}
|
||||
}
|
||||
Ссылка в новой задаче
Block a user