ProjectZipStreamManager.coffee 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. archiver = require "archiver"
  2. async = require "async"
  3. logger = require "logger-sharelatex"
  4. ProjectEntityHandler = require "../Project/ProjectEntityHandler"
  5. ProjectGetter = require('../Project/ProjectGetter')
  6. FileStoreHandler = require("../FileStore/FileStoreHandler")
  7. module.exports = ProjectZipStreamManager =
  8. createZipStreamForMultipleProjects: (project_ids, callback = (error, stream) ->) ->
  9. # We'll build up a zip file that contains multiple zip files
  10. archive = archiver("zip")
  11. archive.on "error", (err)->
  12. logger.err err:err, project_ids:project_ids, "something went wrong building archive of project"
  13. callback null, archive
  14. logger.log project_ids: project_ids, "creating zip stream of multiple projects"
  15. jobs = []
  16. for project_id in project_ids or []
  17. do (project_id) ->
  18. jobs.push (callback) ->
  19. ProjectGetter.getProject project_id, name: true, (error, project) ->
  20. return callback(error) if error?
  21. logger.log project_id: project_id, name: project.name, "appending project to zip stream"
  22. ProjectZipStreamManager.createZipStreamForProject project_id, (error, stream) ->
  23. return callback(error) if error?
  24. archive.append stream, name: "#{project.name}.zip"
  25. stream.on "end", () ->
  26. logger.log project_id: project_id, name: project.name, "zip stream ended"
  27. callback()
  28. async.series jobs, () ->
  29. logger.log project_ids: project_ids, "finished creating zip stream of multiple projects"
  30. archive.finalize()
  31. createZipStreamForProject: (project_id, callback = (error, stream) ->) ->
  32. archive = archiver("zip")
  33. # return stream immediately before we start adding things to it
  34. archive.on "error", (err)->
  35. logger.err err:err, project_id:project_id, "something went wrong building archive of project"
  36. callback(null, archive)
  37. @addAllDocsToArchive project_id, archive, (error) =>
  38. if error?
  39. logger.error err: error, project_id: project_id, "error adding docs to zip stream"
  40. @addAllFilesToArchive project_id, archive, (error) =>
  41. if error?
  42. logger.error err: error, project_id: project_id, "error adding files to zip stream"
  43. archive.finalize()
  44. addAllDocsToArchive: (project_id, archive, callback = (error) ->) ->
  45. ProjectEntityHandler.getAllDocs project_id, (error, docs) ->
  46. return callback(error) if error?
  47. jobs = []
  48. for path, doc of docs
  49. do (path, doc) ->
  50. path = path.slice(1) if path[0] == "/"
  51. jobs.push (callback) ->
  52. logger.log project_id: project_id, "Adding doc"
  53. archive.append doc.lines.join("\n"), name: path
  54. callback()
  55. async.series jobs, callback
  56. addAllFilesToArchive: (project_id, archive, callback = (error) ->) ->
  57. ProjectEntityHandler.getAllFiles project_id, (error, files) ->
  58. return callback(error) if error?
  59. jobs = []
  60. for path, file of files
  61. do (path, file) ->
  62. jobs.push (callback) ->
  63. FileStoreHandler.getFileStream project_id, file._id, {}, (error, stream) ->
  64. if error?
  65. logger.err err:error, project_id:project_id, file_id:file._id, "something went wrong adding file to zip archive"
  66. return callback(err)
  67. path = path.slice(1) if path[0] == "/"
  68. archive.append stream, name: path
  69. stream.on "end", () ->
  70. callback()
  71. async.parallelLimit jobs, 5, callback