github.com/lologarithm/mattermost-server@v5.3.2-0.20181002060438-c82a84ed765b+incompatible/app/export.go (about) 1 // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. 2 // See License.txt for license information. 3 4 package app 5 6 import ( 7 "encoding/json" 8 "io" 9 "net/http" 10 "strings" 11 12 "github.com/mattermost/mattermost-server/model" 13 ) 14 15 func (a *App) BulkExport(writer io.Writer) *model.AppError { 16 if err := a.ExportVersion(writer); err != nil { 17 return err 18 } 19 20 if err := a.ExportAllTeams(writer); err != nil { 21 return err 22 } 23 24 if err := a.ExportAllChannels(writer); err != nil { 25 return err 26 } 27 28 if err := a.ExportAllUsers(writer); err != nil { 29 return err 30 } 31 32 if err := a.ExportAllPosts(writer); err != nil { 33 return err 34 } 35 36 return nil 37 } 38 39 func (a *App) ExportWriteLine(writer io.Writer, line *LineImportData) *model.AppError { 40 b, err := json.Marshal(line) 41 if err != nil { 42 return model.NewAppError("BulkExport", "app.export.export_write_line.json_marshall.error", nil, "err="+err.Error(), http.StatusBadRequest) 43 } 44 45 if _, err := writer.Write(append(b, '\n')); err != nil { 46 return model.NewAppError("BulkExport", "app.export.export_write_line.io_writer.error", nil, "err="+err.Error(), http.StatusBadRequest) 47 } 48 49 return nil 50 } 51 52 func (a *App) ExportVersion(writer io.Writer) *model.AppError { 53 version := 1 54 versionLine := &LineImportData{ 55 Type: "version", 56 Version: &version, 57 } 58 59 return a.ExportWriteLine(writer, versionLine) 60 } 61 62 func (a *App) ExportAllTeams(writer io.Writer) *model.AppError { 63 afterId := strings.Repeat("0", 26) 64 for { 65 result := <-a.Srv.Store.Team().GetAllForExportAfter(1000, afterId) 66 67 if result.Err != nil { 68 return result.Err 69 } 70 71 teams := result.Data.([]*model.TeamForExport) 72 73 if len(teams) == 0 { 74 break 75 } 76 77 for _, team := range teams { 78 afterId = team.Id 79 80 // Skip deleted. 81 if team.DeleteAt != 0 { 82 continue 83 } 84 85 teamLine := ImportLineFromTeam(team) 86 if err := a.ExportWriteLine(writer, teamLine); err != nil { 87 return err 88 } 89 } 90 } 91 92 return nil 93 } 94 95 func (a *App) ExportAllChannels(writer io.Writer) *model.AppError { 96 afterId := strings.Repeat("0", 26) 97 for { 98 result := <-a.Srv.Store.Channel().GetAllChannelsForExportAfter(1000, afterId) 99 100 if result.Err != nil { 101 return result.Err 102 } 103 104 channels := result.Data.([]*model.ChannelForExport) 105 106 if len(channels) == 0 { 107 break 108 } 109 110 for _, channel := range channels { 111 afterId = channel.Id 112 113 // Skip deleted. 114 if channel.DeleteAt != 0 { 115 continue 116 } 117 118 channelLine := ImportLineFromChannel(channel) 119 if err := a.ExportWriteLine(writer, channelLine); err != nil { 120 return err 121 } 122 } 123 } 124 125 return nil 126 } 127 128 func (a *App) ExportAllUsers(writer io.Writer) *model.AppError { 129 afterId := strings.Repeat("0", 26) 130 for { 131 result := <-a.Srv.Store.User().GetAllAfter(1000, afterId) 132 133 if result.Err != nil { 134 return result.Err 135 } 136 137 users := result.Data.([]*model.User) 138 139 if len(users) == 0 { 140 break 141 } 142 143 for _, user := range users { 144 afterId = user.Id 145 146 // Skip deleted. 147 if user.DeleteAt != 0 { 148 continue 149 } 150 151 userLine := ImportLineFromUser(user) 152 153 // Do the Team Memberships. 154 members, err := a.buildUserTeamAndChannelMemberships(user.Id) 155 if err != nil { 156 return err 157 } 158 159 userLine.User.Teams = members 160 161 if err := a.ExportWriteLine(writer, userLine); err != nil { 162 return err 163 } 164 } 165 } 166 167 return nil 168 } 169 170 func (a *App) buildUserTeamAndChannelMemberships(userId string) (*[]UserTeamImportData, *model.AppError) { 171 var memberships []UserTeamImportData 172 173 result := <-a.Srv.Store.Team().GetTeamMembersForExport(userId) 174 175 if result.Err != nil { 176 return nil, result.Err 177 } 178 179 members := result.Data.([]*model.TeamMemberForExport) 180 181 for _, member := range members { 182 // Skip deleted. 183 if member.DeleteAt != 0 { 184 continue 185 } 186 187 memberData := ImportUserTeamDataFromTeamMember(member) 188 189 // Do the Channel Memberships. 190 channelMembers, err := a.buildUserChannelMemberships(userId, member.TeamId) 191 if err != nil { 192 return nil, err 193 } 194 195 memberData.Channels = channelMembers 196 197 memberships = append(memberships, *memberData) 198 } 199 200 return &memberships, nil 201 } 202 203 func (a *App) buildUserChannelMemberships(userId string, teamId string) (*[]UserChannelImportData, *model.AppError) { 204 var memberships []UserChannelImportData 205 206 result := <-a.Srv.Store.Channel().GetChannelMembersForExport(userId, teamId) 207 208 if result.Err != nil { 209 return nil, result.Err 210 } 211 212 members := result.Data.([]*model.ChannelMemberForExport) 213 214 for _, member := range members { 215 memberships = append(memberships, *ImportUserChannelDataFromChannelMember(member)) 216 } 217 218 return &memberships, nil 219 } 220 221 func (a *App) ExportAllPosts(writer io.Writer) *model.AppError { 222 afterId := strings.Repeat("0", 26) 223 for { 224 result := <-a.Srv.Store.Post().GetParentsForExportAfter(1000, afterId) 225 226 if result.Err != nil { 227 return result.Err 228 } 229 230 posts := result.Data.([]*model.PostForExport) 231 232 if len(posts) == 0 { 233 break 234 } 235 236 for _, post := range posts { 237 afterId = post.Id 238 239 // Skip deleted. 240 if post.DeleteAt != 0 { 241 continue 242 } 243 244 postLine := ImportLineForPost(post) 245 246 // Do the Replies. 247 replies, err := a.buildPostReplies(post.Id) 248 if err != nil { 249 return err 250 } 251 252 postLine.Post.Replies = replies 253 254 if err := a.ExportWriteLine(writer, postLine); err != nil { 255 return err 256 } 257 } 258 } 259 260 return nil 261 } 262 263 func (a *App) buildPostReplies(postId string) (*[]ReplyImportData, *model.AppError) { 264 var replies []ReplyImportData 265 266 result := <-a.Srv.Store.Post().GetRepliesForExport(postId) 267 268 if result.Err != nil { 269 return nil, result.Err 270 } 271 272 replyPosts := result.Data.([]*model.ReplyForExport) 273 274 for _, reply := range replyPosts { 275 replies = append(replies, *ImportReplyFromPost(reply)) 276 } 277 278 return &replies, nil 279 }