UpdateMerger.coffee 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. _ = require('underscore')
  2. projectLocator = require('../Project/ProjectLocator')
  3. editorController = require('../Editor/EditorController')
  4. logger = require('logger-sharelatex')
  5. Settings = require('settings-sharelatex')
  6. slReqIdHelper = require('soa-req-id')
  7. FileTypeManager = require('../Uploads/FileTypeManager')
  8. GuidManager = require '../../managers/GuidManager'
  9. fs = require('fs')
  10. module.exports =
  11. mergeUpdate: (project_id, path, updateRequest, sl_req_id, callback)->
  12. {callback, sl_req_id} = slReqIdHelper.getCallbackAndReqId(callback, sl_req_id)
  13. self = @
  14. logger.log sl_req_id: sl_req_id, project_id:project_id, path:path, "merging update from tpds"
  15. projectLocator.findElementByPath project_id, path, (err, element)=>
  16. logger.log sl_req_id: sl_req_id, project_id:project_id, path:path, "found element by path for merging update from tpds"
  17. elementId = undefined
  18. if element?
  19. elementId = element._id
  20. self.p.writeStreamToDisk project_id, elementId, updateRequest, (err, fsPath)->
  21. FileTypeManager.shouldIgnore path, (err, shouldIgnore)->
  22. if shouldIgnore
  23. return callback()
  24. FileTypeManager.isBinary path, (err, isFile)->
  25. if isFile
  26. self.p.processFile project_id, elementId, fsPath, path, callback #TODO clean up the stream written to disk here
  27. else
  28. self.p.processDoc project_id, elementId, fsPath, path, sl_req_id, callback
  29. deleteUpdate: (project_id, path, sl_req_id, callback)->
  30. {callback, sl_req_id} = slReqIdHelper.getCallbackAndReqId(callback, sl_req_id)
  31. projectLocator.findElementByPath project_id, path, (err, element)->
  32. type = 'file'
  33. if err? || !element?
  34. logger.log sl_req_id: sl_req_id, element:element, project_id:project_id, path:path, "could not find entity for deleting, assuming it was already deleted"
  35. return callback()
  36. if element.lines?
  37. type = 'doc'
  38. else if element.folders?
  39. type = 'folder'
  40. logger.log sl_req_id: sl_req_id, project_id:project_id, path:path, type:type, element:element, "processing update to delete entity from tpds"
  41. editorController.deleteEntity project_id, element._id, type, sl_req_id, (err)->
  42. logger.log sl_req_id: sl_req_id, project_id:project_id, path:path, "finished processing update to delete entity from tpds"
  43. callback()
  44. p:
  45. processDoc: (project_id, doc_id, fsPath, path, sl_req_id, callback)->
  46. {callback, sl_req_id} = slReqIdHelper.getCallbackAndReqId(callback, sl_req_id)
  47. readFileIntoTextArray fsPath, (err, docLines)->
  48. if err?
  49. logger.err project_id:project_id, doc_id:doc_id, fsPath:fsPath, "error reading file into text array for process doc update"
  50. return callback(err)
  51. logger.log docLines:docLines, doc_id:doc_id, project_id:project_id, sl_req_id:sl_req_id, "processing doc update from tpds"
  52. if doc_id?
  53. editorController.setDoc project_id, doc_id, docLines, sl_req_id, (err)->
  54. callback()
  55. else
  56. setupNewEntity project_id, path, (err, folder, fileName)->
  57. editorController.addDoc project_id, folder._id, fileName, docLines, sl_req_id, (err)->
  58. callback()
  59. processFile: (project_id, file_id, fsPath, path, sl_req_id, callback)->
  60. {callback, sl_req_id} = slReqIdHelper.getCallbackAndReqId(callback, sl_req_id)
  61. finish = (err)->
  62. logger.log sl_req_id: sl_req_id, project_id:project_id, file_id:file_id, path:path, "completed processing file update from tpds"
  63. callback(err)
  64. logger.log sl_req_id: sl_req_id, project_id:project_id, file_id:file_id, path:path, "processing file update from tpds"
  65. setupNewEntity project_id, path, (err, folder, fileName) =>
  66. if file_id?
  67. editorController.replaceFile project_id, file_id, fsPath, finish
  68. else
  69. editorController.addFile project_id, folder._id, fileName, fsPath, finish
  70. writeStreamToDisk: (project_id, file_id, stream, callback = (err, fsPath)->)->
  71. if !file_id?
  72. file_id = GuidManager.newGuid()
  73. dumpPath = "#{Settings.path.dumpFolder}/#{project_id}_#{file_id}"
  74. writeStream = fs.createWriteStream(dumpPath)
  75. stream.pipe(writeStream)
  76. stream.on 'error', (err)->
  77. logger.err err:err, project_id:project_id, file_id:file_id, dumpPath:dumpPath,
  78. "something went wrong with incoming tpds update stream"
  79. writeStream.on 'error', (err)->
  80. logger.err err:err, project_id:project_id, file_id:file_id, dumpPath:dumpPath,
  81. "something went wrong with writing tpds update to disk"
  82. stream.on 'end', ->
  83. logger.log project_id:project_id, file_id:file_id, dumpPath:dumpPath, "incoming tpds update stream ended"
  84. writeStream.on "finish", ->
  85. logger.log project_id:project_id, file_id:file_id, dumpPath:dumpPath, "tpds update write stream finished"
  86. callback null, dumpPath
  87. if stream.emitBufferedData?
  88. stream.emitBufferedData()
  89. stream.resume()
  90. readFileIntoTextArray = (path, callback)->
  91. fs.readFile path, "utf8", (error, content = "") ->
  92. if error?
  93. logger.err path:path, "error reading file into text array"
  94. return callback(err)
  95. lines = content.split("\n")
  96. callback error, lines
  97. setupNewEntity = (project_id, path, callback)->
  98. lastIndexOfSlash = path.lastIndexOf("/")
  99. fileName = path[lastIndexOfSlash+1 .. -1]
  100. folderPath = path[0 .. lastIndexOfSlash]
  101. editorController.mkdirp project_id, folderPath, (err, newFolders, lastFolder)->
  102. callback err, lastFolder, fileName