ProjectOutputFileAgent.coffee 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. AuthorizationManager = require('../Authorization/AuthorizationManager')
  2. ProjectGetter = require('../Project/ProjectGetter')
  3. Settings = require 'settings-sharelatex'
  4. CompileManager = require '../Compile/CompileManager'
  5. ClsiManager = require '../Compile/ClsiManager'
  6. ProjectFileAgent = require './ProjectFileAgent'
  7. _ = require "underscore"
  8. {
  9. BadDataError,
  10. AccessDeniedError,
  11. BadEntityTypeError,
  12. OutputFileFetchFailedError
  13. } = require './LinkedFilesErrors'
  14. LinkedFilesHandler = require './LinkedFilesHandler'
  15. logger = require 'logger-sharelatex'
  16. module.exports = ProjectOutputFileAgent = {
  17. _prepare: (project_id, linkedFileData, user_id, callback=(err, linkedFileData)->) ->
  18. @_checkAuth project_id, linkedFileData, user_id, (err, allowed) =>
  19. return callback(err) if err?
  20. return callback(new AccessDeniedError()) if !allowed
  21. @_decorateLinkedFileData linkedFileData, (err, newLinkedFileData) =>
  22. return callback(err) if err?
  23. if !@_validate(newLinkedFileData)
  24. return callback(new BadDataError())
  25. callback(null, newLinkedFileData)
  26. createLinkedFile: (project_id, linkedFileData, name, parent_folder_id, user_id, callback) ->
  27. if !@_canCreate(linkedFileData)
  28. return callback(new AccessDeniedError())
  29. linkedFileData = @_sanitizeData(linkedFileData)
  30. @_prepare project_id, linkedFileData, user_id, (err, linkedFileData) =>
  31. return callback(err) if err?
  32. @_getFileStream linkedFileData, user_id, (err, readStream) =>
  33. return callback(err) if err?
  34. readStream.on "error", callback
  35. readStream.on "response", (response) =>
  36. if 200 <= response.statusCode < 300
  37. readStream.resume()
  38. LinkedFilesHandler.importFromStream project_id,
  39. readStream,
  40. linkedFileData,
  41. name,
  42. parent_folder_id,
  43. user_id,
  44. (err, file) ->
  45. return callback(err) if err?
  46. callback(null, file._id) # Created
  47. else
  48. err = new OutputFileFetchFailedError(
  49. "Output file fetch failed: #{linkedFileData.build_id}, #{linkedFileData.source_output_file_path}"
  50. )
  51. err.statusCode = response.statusCode
  52. callback(err)
  53. refreshLinkedFile: (project_id, linkedFileData, name, parent_folder_id, user_id, callback) ->
  54. @_prepare project_id, linkedFileData, user_id, (err, linkedFileData) =>
  55. return callback(err) if err?
  56. @_compileAndGetFileStream linkedFileData, user_id, (err, readStream, new_build_id) =>
  57. return callback(err) if err?
  58. readStream.on "error", callback
  59. readStream.on "response", (response) =>
  60. if 200 <= response.statusCode < 300
  61. readStream.resume()
  62. linkedFileData.build_id = new_build_id
  63. LinkedFilesHandler.importFromStream project_id,
  64. readStream,
  65. linkedFileData,
  66. name,
  67. parent_folder_id,
  68. user_id,
  69. (err, file) ->
  70. return callback(err) if err?
  71. callback(null, file._id) # Created
  72. else
  73. err = new OutputFileFetchFailedError(
  74. "Output file fetch failed: #{linkedFileData.build_id}, #{linkedFileData.source_output_file_path}"
  75. )
  76. err.statusCode = response.statusCode
  77. callback(err)
  78. _sanitizeData: (data) ->
  79. return {
  80. provider: data.provider,
  81. source_project_id: data.source_project_id,
  82. source_output_file_path: data.source_output_file_path,
  83. build_id: data.build_id
  84. }
  85. _canCreate: ProjectFileAgent._canCreate
  86. _getSourceProject: ProjectFileAgent._getSourceProject
  87. _decorateLinkedFileData: ProjectFileAgent._decorateLinkedFileData
  88. _validate: (data) ->
  89. return (
  90. (data.source_project_id? || data.v1_source_doc_id?) &&
  91. data.source_output_file_path? &&
  92. data.build_id?
  93. )
  94. _checkAuth: (project_id, data, current_user_id, callback = (err, allowed)->) ->
  95. callback = _.once(callback)
  96. if !@_validate(data)
  97. return callback(new BadDataError())
  98. @_getSourceProject data, (err, project) ->
  99. return callback(err) if err?
  100. AuthorizationManager.canUserReadProject current_user_id,
  101. project._id,
  102. null,
  103. (err, canRead) ->
  104. return callback(err) if err?
  105. callback(null, canRead)
  106. _getFileStream: (linkedFileData, user_id, callback=(err, fileStream)->) ->
  107. callback = _.once(callback)
  108. { source_output_file_path, build_id } = linkedFileData
  109. @_getSourceProject linkedFileData, (err, project) ->
  110. return callback(err) if err?
  111. source_project_id = project._id
  112. ClsiManager.getOutputFileStream source_project_id,
  113. user_id,
  114. build_id,
  115. source_output_file_path,
  116. (err, readStream) ->
  117. return callback(err) if err?
  118. readStream.pause()
  119. callback(null, readStream)
  120. _compileAndGetFileStream: (linkedFileData, user_id, callback=(err, stream, build_id)->) ->
  121. callback = _.once(callback)
  122. { source_output_file_path } = linkedFileData
  123. @_getSourceProject linkedFileData, (err, project) ->
  124. return callback(err) if err?
  125. source_project_id = project._id
  126. CompileManager.compile source_project_id,
  127. user_id,
  128. {},
  129. (err, status, outputFiles) ->
  130. return callback(err) if err?
  131. if status != 'success'
  132. return callback(new OutputFileFetchFailedError())
  133. outputFile = _.find(
  134. outputFiles,
  135. (o) => o.path == source_output_file_path
  136. )
  137. if !outputFile?
  138. return callback(new OutputFileFetchFailedError())
  139. build_id = outputFile.build
  140. ClsiManager.getOutputFileStream source_project_id,
  141. user_id,
  142. build_id,
  143. source_output_file_path,
  144. (err, readStream) ->
  145. return callback(err) if err?
  146. readStream.pause()
  147. callback(null, readStream, build_id)
  148. }