github.com/levb/mattermost-server@v5.3.1+incompatible/cmd/mattermost/commands/message_export.go (about)

     1  // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
     2  // See License.txt for license information.
     3  
     4  package commands
     5  
     6  import (
     7  	"errors"
     8  
     9  	"context"
    10  
    11  	"time"
    12  
    13  	"github.com/mattermost/mattermost-server/model"
    14  	"github.com/spf13/cobra"
    15  )
    16  
    17  var MessageExportCmd = &cobra.Command{
    18  	Use:   "export",
    19  	Short: "Export data from Mattermost",
    20  	Long:  "Export data from Mattermost in a format suitable for import into a third-party application",
    21  }
    22  
    23  var ScheduleExportCmd = &cobra.Command{
    24  	Use:     "schedule",
    25  	Short:   "Schedule an export data job in Mattermost",
    26  	Long:    "Schedule an export data job in Mattermost (this will run asynchronously via a background worker)",
    27  	Example: "export schedule --format=actiance --exportFrom=12345 --timeoutSeconds=12345",
    28  	RunE:    scheduleExportCmdF,
    29  }
    30  
    31  var CsvExportCmd = &cobra.Command{
    32  	Use:     "csv",
    33  	Short:   "Export data from Mattermost in CSV format",
    34  	Long:    "Export data from Mattermost in CSV format",
    35  	Example: "export csv --exportFrom=12345",
    36  	RunE:    buildExportCmdF("csv"),
    37  }
    38  
    39  var ActianceExportCmd = &cobra.Command{
    40  	Use:     "actiance",
    41  	Short:   "Export data from Mattermost in Actiance format",
    42  	Long:    "Export data from Mattermost in Actiance format",
    43  	Example: "export actiance --exportFrom=12345",
    44  	RunE:    buildExportCmdF("actiance"),
    45  }
    46  
    47  func init() {
    48  	ScheduleExportCmd.Flags().String("format", "actiance", "The format to export data")
    49  	ScheduleExportCmd.Flags().Int64("exportFrom", -1, "The timestamp of the earliest post to export, expressed in seconds since the unix epoch.")
    50  	ScheduleExportCmd.Flags().Int("timeoutSeconds", -1, "The maximum number of seconds to wait for the job to complete before timing out.")
    51  	CsvExportCmd.Flags().Int64("exportFrom", -1, "The timestamp of the earliest post to export, expressed in seconds since the unix epoch.")
    52  	ActianceExportCmd.Flags().Int64("exportFrom", -1, "The timestamp of the earliest post to export, expressed in seconds since the unix epoch.")
    53  	MessageExportCmd.AddCommand(ScheduleExportCmd)
    54  	MessageExportCmd.AddCommand(CsvExportCmd)
    55  	MessageExportCmd.AddCommand(ActianceExportCmd)
    56  	RootCmd.AddCommand(MessageExportCmd)
    57  }
    58  
    59  func scheduleExportCmdF(command *cobra.Command, args []string) error {
    60  	a, err := InitDBCommandContextCobra(command)
    61  	if err != nil {
    62  		return err
    63  	}
    64  	defer a.Shutdown()
    65  
    66  	if !*a.Config().MessageExportSettings.EnableExport {
    67  		return errors.New("ERROR: The message export feature is not enabled")
    68  	}
    69  
    70  	// for now, format is hard-coded to actiance. In time, we'll have to support other formats and inject them into job data
    71  	format, err := command.Flags().GetString("format")
    72  	if err != nil {
    73  		return errors.New("format flag error")
    74  	}
    75  	if format != "actiance" {
    76  		return errors.New("unsupported export format")
    77  	}
    78  
    79  	startTime, err := command.Flags().GetInt64("exportFrom")
    80  	if err != nil {
    81  		return errors.New("exportFrom flag error")
    82  	}
    83  	if startTime < 0 {
    84  		return errors.New("exportFrom must be a positive integer")
    85  	}
    86  
    87  	timeoutSeconds, err := command.Flags().GetInt("timeoutSeconds")
    88  	if err != nil {
    89  		return errors.New("timeoutSeconds error")
    90  	}
    91  	if timeoutSeconds < 0 {
    92  		return errors.New("timeoutSeconds must be a positive integer")
    93  	}
    94  
    95  	if messageExportI := a.MessageExport; messageExportI != nil {
    96  		ctx := context.Background()
    97  		if timeoutSeconds > 0 {
    98  			var cancel context.CancelFunc
    99  			ctx, cancel = context.WithTimeout(ctx, time.Second*time.Duration(timeoutSeconds))
   100  			defer cancel()
   101  		}
   102  
   103  		job, err := messageExportI.StartSynchronizeJob(ctx, startTime)
   104  		if err != nil || job.Status == model.JOB_STATUS_ERROR || job.Status == model.JOB_STATUS_CANCELED {
   105  			CommandPrintErrorln("ERROR: Message export job failed. Please check the server logs")
   106  		} else {
   107  			CommandPrettyPrintln("SUCCESS: Message export job complete")
   108  		}
   109  	}
   110  
   111  	return nil
   112  }
   113  
   114  func buildExportCmdF(format string) func(command *cobra.Command, args []string) error {
   115  	return func(command *cobra.Command, args []string) error {
   116  		a, err := InitDBCommandContextCobra(command)
   117  		if err != nil {
   118  			return err
   119  		}
   120  		defer a.Shutdown()
   121  
   122  		startTime, err := command.Flags().GetInt64("exportFrom")
   123  		if err != nil {
   124  			return errors.New("exportFrom flag error")
   125  		}
   126  		if startTime < 0 {
   127  			return errors.New("exportFrom must be a positive integer")
   128  		}
   129  
   130  		if a.MessageExport == nil {
   131  			CommandPrettyPrintln("MessageExport feature not available")
   132  		}
   133  
   134  		err2 := a.MessageExport.RunExport(format, startTime)
   135  		if err2 != nil {
   136  			return err2
   137  		}
   138  		CommandPrettyPrintln("SUCCESS: Your data was exported.")
   139  
   140  		return nil
   141  	}
   142  }