ProjectOutputFileAgent.coffee 5.3 KB

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