ProjectOutputFileAgent.coffee 5.5 KB

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