github.com/rajatvaryani/mattermost-server@v5.11.1+incompatible/cmd/mattermost/commands/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 "os" 9 10 "context" 11 12 "time" 13 14 "github.com/mattermost/mattermost-server/model" 15 "github.com/spf13/cobra" 16 ) 17 18 var ExportCmd = &cobra.Command{ 19 Use: "export", 20 Short: "Export data from Mattermost", 21 Long: "Export data from Mattermost in a format suitable for import into a third-party application or another Mattermost instance", 22 } 23 24 var ScheduleExportCmd = &cobra.Command{ 25 Use: "schedule", 26 Short: "Schedule an export data job in Mattermost", 27 Long: "Schedule an export data job in Mattermost (this will run asynchronously via a background worker)", 28 Example: "export schedule --format=actiance --exportFrom=12345 --timeoutSeconds=12345", 29 RunE: scheduleExportCmdF, 30 } 31 32 var CsvExportCmd = &cobra.Command{ 33 Use: "csv", 34 Short: "Export data from Mattermost in CSV format", 35 Long: "Export data from Mattermost in CSV format", 36 Example: "export csv --exportFrom=12345", 37 RunE: buildExportCmdF("csv"), 38 } 39 40 var ActianceExportCmd = &cobra.Command{ 41 Use: "actiance", 42 Short: "Export data from Mattermost in Actiance format", 43 Long: "Export data from Mattermost in Actiance format", 44 Example: "export actiance --exportFrom=12345", 45 RunE: buildExportCmdF("actiance"), 46 } 47 48 var BulkExportCmd = &cobra.Command{ 49 Use: "bulk [file]", 50 Short: "Export bulk data.", 51 Long: "Export data to a file compatible with the Mattermost Bulk Import format.", 52 Example: " export bulk bulk_data.json", 53 RunE: bulkExportCmdF, 54 Args: cobra.ExactArgs(1), 55 } 56 57 func init() { 58 ScheduleExportCmd.Flags().String("format", "actiance", "The format to export data") 59 ScheduleExportCmd.Flags().Int64("exportFrom", -1, "The timestamp of the earliest post to export, expressed in seconds since the unix epoch.") 60 ScheduleExportCmd.Flags().Int("timeoutSeconds", -1, "The maximum number of seconds to wait for the job to complete before timing out.") 61 62 CsvExportCmd.Flags().Int64("exportFrom", -1, "The timestamp of the earliest post to export, expressed in seconds since the unix epoch.") 63 64 ActianceExportCmd.Flags().Int64("exportFrom", -1, "The timestamp of the earliest post to export, expressed in seconds since the unix epoch.") 65 66 BulkExportCmd.Flags().Bool("all-teams", false, "Export all teams from the server.") 67 68 ExportCmd.AddCommand(ScheduleExportCmd) 69 ExportCmd.AddCommand(CsvExportCmd) 70 ExportCmd.AddCommand(ActianceExportCmd) 71 ExportCmd.AddCommand(BulkExportCmd) 72 73 RootCmd.AddCommand(ExportCmd) 74 } 75 76 func scheduleExportCmdF(command *cobra.Command, args []string) error { 77 a, err := InitDBCommandContextCobra(command) 78 if err != nil { 79 return err 80 } 81 defer a.Shutdown() 82 83 if !*a.Config().MessageExportSettings.EnableExport { 84 return errors.New("ERROR: The message export feature is not enabled") 85 } 86 87 // for now, format is hard-coded to actiance. In time, we'll have to support other formats and inject them into job data 88 format, err := command.Flags().GetString("format") 89 if err != nil { 90 return errors.New("format flag error") 91 } 92 if format != "actiance" { 93 return errors.New("unsupported export format") 94 } 95 96 startTime, err := command.Flags().GetInt64("exportFrom") 97 if err != nil { 98 return errors.New("exportFrom flag error") 99 } 100 if startTime < 0 { 101 return errors.New("exportFrom must be a positive integer") 102 } 103 104 timeoutSeconds, err := command.Flags().GetInt("timeoutSeconds") 105 if err != nil { 106 return errors.New("timeoutSeconds error") 107 } 108 if timeoutSeconds < 0 { 109 return errors.New("timeoutSeconds must be a positive integer") 110 } 111 112 if messageExportI := a.MessageExport; messageExportI != nil { 113 ctx := context.Background() 114 if timeoutSeconds > 0 { 115 var cancel context.CancelFunc 116 ctx, cancel = context.WithTimeout(ctx, time.Second*time.Duration(timeoutSeconds)) 117 defer cancel() 118 } 119 120 job, err := messageExportI.StartSynchronizeJob(ctx, startTime) 121 if err != nil || job.Status == model.JOB_STATUS_ERROR || job.Status == model.JOB_STATUS_CANCELED { 122 CommandPrintErrorln("ERROR: Message export job failed. Please check the server logs") 123 } else { 124 CommandPrettyPrintln("SUCCESS: Message export job complete") 125 } 126 } 127 128 return nil 129 } 130 131 func buildExportCmdF(format string) func(command *cobra.Command, args []string) error { 132 return func(command *cobra.Command, args []string) error { 133 a, err := InitDBCommandContextCobra(command) 134 if err != nil { 135 return err 136 } 137 defer a.Shutdown() 138 139 startTime, err := command.Flags().GetInt64("exportFrom") 140 if err != nil { 141 return errors.New("exportFrom flag error") 142 } 143 if startTime < 0 { 144 return errors.New("exportFrom must be a positive integer") 145 } 146 147 if a.MessageExport == nil { 148 CommandPrettyPrintln("MessageExport feature not available") 149 } 150 151 err2 := a.MessageExport.RunExport(format, startTime) 152 if err2 != nil { 153 return err2 154 } 155 CommandPrettyPrintln("SUCCESS: Your data was exported.") 156 157 return nil 158 } 159 } 160 161 func bulkExportCmdF(command *cobra.Command, args []string) error { 162 a, err := InitDBCommandContextCobra(command) 163 if err != nil { 164 return err 165 } 166 defer a.Shutdown() 167 168 allTeams, err := command.Flags().GetBool("all-teams") 169 if err != nil { 170 return errors.New("Apply flag error") 171 } 172 173 if !allTeams { 174 return errors.New("Nothing to export. Please specify the --all-teams flag to export all teams.") 175 } 176 177 fileWriter, err := os.Create(args[0]) 178 if err != nil { 179 return err 180 } 181 defer fileWriter.Close() 182 183 // Path to directory of custom emoji 184 pathToEmojiDir := "data/emoji/" 185 186 // Name of the directory to export custom emoji 187 dirNameToExportEmoji := "exported_emoji" 188 189 // args[0] points to the filename/filepath passed with export bulk command 190 if err := a.BulkExport(fileWriter, args[0], pathToEmojiDir, dirNameToExportEmoji); err != nil { 191 CommandPrettyPrintln(err.Error()) 192 return err 193 } 194 195 return nil 196 }