From d9390244afe90ed318ac8c263c19328f16dc2562 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Espino?= Date: Fri, 22 Jun 2018 11:15:19 +0200 Subject: MM-8810: Add CSV Compliance export (#8966) * MM-8810: Add CSV Compliance export * Only allowing to schedule actiances export throught the cli * De-duplicating some code * Fixes on texts * Fixes on translations --- cmd/mattermost/commands/message_export.go | 74 ++++++++++++++++++++++---- cmd/mattermost/commands/message_export_test.go | 8 +-- cmd/mattermost/commands/sampledata.go | 2 +- 3 files changed, 70 insertions(+), 14 deletions(-) (limited to 'cmd') diff --git a/cmd/mattermost/commands/message_export.go b/cmd/mattermost/commands/message_export.go index 41b4fd289..ee1a7ef7f 100644 --- a/cmd/mattermost/commands/message_export.go +++ b/cmd/mattermost/commands/message_export.go @@ -15,21 +15,48 @@ import ( ) var MessageExportCmd = &cobra.Command{ - Use: "export", - Short: "Export data from Mattermost", - Long: "Export data from Mattermost in a format suitable for import into a third-party application", - Example: "export --format=actiance --exportFrom=12345", - RunE: messageExportCmdF, + Use: "export", + Short: "Export data from Mattermost", + Long: "Export data from Mattermost in a format suitable for import into a third-party application", +} + +var ScheduleExportCmd = &cobra.Command{ + Use: "schedule", + Short: "Schedule an export data job in Mattermost", + Long: "Schedule an export data job in Mattermost (this will run asynchronously via a background worker)", + Example: "export schedule --format=actiance --exportFrom=12345 --timeoutSeconds=12345", + RunE: scheduleExportCmdF, +} + +var CsvExportCmd = &cobra.Command{ + Use: "csv", + Short: "Export data from Mattermost in CSV format", + Long: "Export data from Mattermost in CSV format", + Example: "export csv --exportFrom=12345", + RunE: buildExportCmdF("csv"), +} + +var ActianceExportCmd = &cobra.Command{ + Use: "actiance", + Short: "Export data from Mattermost in Actiance format", + Long: "Export data from Mattermost in Actiance format", + Example: "export actiance --exportFrom=12345", + RunE: buildExportCmdF("actiance"), } func init() { - MessageExportCmd.Flags().String("format", "actiance", "The format to export data in") - MessageExportCmd.Flags().Int64("exportFrom", -1, "The timestamp of the earliest post to export, expressed in seconds since the unix epoch.") - MessageExportCmd.Flags().Int("timeoutSeconds", -1, "The maximum number of seconds to wait for the job to complete before timing out.") + ScheduleExportCmd.Flags().String("format", "actiance", "The format to export data") + ScheduleExportCmd.Flags().Int64("exportFrom", -1, "The timestamp of the earliest post to export, expressed in seconds since the unix epoch.") + ScheduleExportCmd.Flags().Int("timeoutSeconds", -1, "The maximum number of seconds to wait for the job to complete before timing out.") + CsvExportCmd.Flags().Int64("exportFrom", -1, "The timestamp of the earliest post to export, expressed in seconds since the unix epoch.") + ActianceExportCmd.Flags().Int64("exportFrom", -1, "The timestamp of the earliest post to export, expressed in seconds since the unix epoch.") + MessageExportCmd.AddCommand(ScheduleExportCmd) + MessageExportCmd.AddCommand(CsvExportCmd) + MessageExportCmd.AddCommand(ActianceExportCmd) RootCmd.AddCommand(MessageExportCmd) } -func messageExportCmdF(command *cobra.Command, args []string) error { +func scheduleExportCmdF(command *cobra.Command, args []string) error { a, err := InitDBCommandContextCobra(command) if err != nil { return err @@ -79,3 +106,32 @@ func messageExportCmdF(command *cobra.Command, args []string) error { return nil } + +func buildExportCmdF(format string) func(command *cobra.Command, args []string) error { + return func(command *cobra.Command, args []string) error { + a, err := InitDBCommandContextCobra(command) + if err != nil { + return err + } + defer a.Shutdown() + + startTime, err := command.Flags().GetInt64("exportFrom") + if err != nil { + return errors.New("exportFrom flag error") + } else if startTime < 0 { + return errors.New("exportFrom must be a positive integer") + } + + if a.MessageExport == nil { + CommandPrettyPrintln("MessageExport feature not available") + } + + err2 := a.MessageExport.RunExport(format, startTime) + if err2 != nil { + return err2 + } + CommandPrettyPrintln("SUCCESS: Your data was exported.") + + return nil + } +} diff --git a/cmd/mattermost/commands/message_export_test.go b/cmd/mattermost/commands/message_export_test.go index 7572d8b48..89ef45a6a 100644 --- a/cmd/mattermost/commands/message_export_test.go +++ b/cmd/mattermost/commands/message_export_test.go @@ -24,7 +24,7 @@ func TestMessageExportNotEnabled(t *testing.T) { defer os.RemoveAll(filepath.Dir(configPath)) // should fail fast because the feature isn't enabled - require.Error(t, RunCommand(t, "--config", configPath, "export")) + require.Error(t, RunCommand(t, "--config", configPath, "export", "schedule")) } func TestMessageExportInvalidFormat(t *testing.T) { @@ -32,7 +32,7 @@ func TestMessageExportInvalidFormat(t *testing.T) { defer os.RemoveAll(filepath.Dir(configPath)) // should fail fast because format isn't supported - require.Error(t, RunCommand(t, "--config", configPath, "--format", "not_actiance", "export")) + require.Error(t, RunCommand(t, "--config", configPath, "--format", "not_actiance", "export", "schedule")) } func TestMessageExportNegativeExportFrom(t *testing.T) { @@ -40,7 +40,7 @@ func TestMessageExportNegativeExportFrom(t *testing.T) { defer os.RemoveAll(filepath.Dir(configPath)) // should fail fast because export from must be a valid timestamp - require.Error(t, RunCommand(t, "--config", configPath, "--format", "actiance", "--exportFrom", "-1", "export")) + require.Error(t, RunCommand(t, "--config", configPath, "--format", "actiance", "--exportFrom", "-1", "export", "schedule")) } func TestMessageExportNegativeTimeoutSeconds(t *testing.T) { @@ -48,7 +48,7 @@ func TestMessageExportNegativeTimeoutSeconds(t *testing.T) { defer os.RemoveAll(filepath.Dir(configPath)) // should fail fast because timeout seconds must be a positive int - require.Error(t, RunCommand(t, "--config", configPath, "--format", "actiance", "--exportFrom", "0", "--timeoutSeconds", "-1", "export")) + require.Error(t, RunCommand(t, "--config", configPath, "--format", "actiance", "--exportFrom", "0", "--timeoutSeconds", "-1", "export", "schedule")) } func writeTempConfig(t *testing.T, isMessageExportEnabled bool) string { diff --git a/cmd/mattermost/commands/sampledata.go b/cmd/mattermost/commands/sampledata.go index 0051679eb..0983ab0df 100644 --- a/cmd/mattermost/commands/sampledata.go +++ b/cmd/mattermost/commands/sampledata.go @@ -56,7 +56,7 @@ func sliceIncludes(vs []string, t string) bool { func randomPastTime(seconds int) int64 { now := time.Now() today := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, time.FixedZone("UTC", 0)) - return today.Unix() - int64(rand.Intn(seconds*1000)) + return (today.Unix() * 1000) - int64(rand.Intn(seconds*1000)) } func randomEmoji() string { -- cgit v1.2.3-1-g7c22