ProjectOutputFileAgent.coffee 3.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. FileWriter = require('../../infrastructure/FileWriter')
  2. AuthorizationManager = require('../Authorization/AuthorizationManager')
  3. ProjectGetter = require('../Project/ProjectGetter')
  4. FileWriter = require('../../infrastructure/FileWriter')
  5. Settings = require 'settings-sharelatex'
  6. CompileManager = require '../Compile/CompileManager'
  7. CompileController = require '../Compile/CompileController'
  8. ClsiCookieManager = require '../Compile/ClsiCookieManager'
  9. _ = require "underscore"
  10. request = require "request"
  11. BadDataError = (message) ->
  12. error = new Error(message)
  13. error.name = 'BadData'
  14. error.__proto__ = BadDataError.prototype
  15. return error
  16. BadDataError.prototype.__proto__ = Error.prototype
  17. ProjectNotFoundError = (message) ->
  18. error = new Error(message)
  19. error.name = 'ProjectNotFound'
  20. error.__proto__ = ProjectNotFoundError.prototype
  21. return error
  22. ProjectNotFoundError.prototype.__proto__ = Error.prototype
  23. OutputFileFetchFailedError = (message) ->
  24. error = new Error(message)
  25. error.name = 'OutputFileFetchFailedError'
  26. error.__proto__ = OutputFileFetchFailedError.prototype
  27. return error
  28. OutputFileFetchFailedError.prototype.__proto__ = Error.prototype
  29. module.exports = ProjectOutputFileAgent = {
  30. sanitizeData: (data) ->
  31. return {
  32. source_project_id: data.source_project_id,
  33. source_output_file_path: data.source_output_file_path
  34. }
  35. canCreate: (data) -> true
  36. decorateLinkedFileData: (data, callback = (err, newData) ->) ->
  37. callback = _.once(callback)
  38. ProjectGetter.getProject data.source_project_id, {name: 1}, (err, project) ->
  39. return callback(err) if err?
  40. if !project?
  41. return callback(new ProjectNotFoundError())
  42. callback(err, _.extend(data, {source_project_display_name: project.name}))
  43. checkAuth: (project_id, data, current_user_id, callback = (error, allowed)->) ->
  44. callback = _.once(callback)
  45. { source_project_id } = data
  46. AuthorizationManager.canUserReadProject current_user_id, source_project_id, null, (err, canRead) ->
  47. return callback(err) if err?
  48. callback(null, canRead)
  49. _validate: (data) ->
  50. data.source_project_id? && data.source_output_file_path?
  51. writeIncomingFileToDisk: (project_id, data, current_user_id, callback = (error, fsPath) ->) ->
  52. callback = _.once(callback)
  53. if !ProjectOutputFileAgent._validate(data)
  54. return callback(new BadDataError())
  55. { source_project_id, source_output_file_path } = data
  56. CompileManager.compile source_project_id, null, {}, (err) ->
  57. return callback(err) if err?
  58. url = "#{Settings.apis.clsi.url}/project/#{source_project_id}/output/#{source_output_file_path}"
  59. ClsiCookieManager.getCookieJar source_project_id, (err, jar)->
  60. return callback(err) if err?
  61. oneMinute = 60 * 1000
  62. # the base request
  63. options = { url: url, method: "GET", timeout: oneMinute, jar : jar }
  64. readStream = request(options)
  65. readStream.on "error", callback
  66. readStream.on "response", (response) ->
  67. if 200 <= response.statusCode < 300
  68. FileWriter.writeStreamToDisk project_id, readStream, callback
  69. else
  70. error = new OutputFileFetchFailedError("Output file fetch failed: #{url}")
  71. error.statusCode = response.statusCode
  72. callback(error)
  73. handleError: (error, req, res, next) ->
  74. if error instanceof BadDataError
  75. res.status(400).send("The submitted data is not valid")
  76. else if error instanceof SourceFileNotFoundError
  77. res.status(404).send("Source file not found")
  78. else if error instanceof ProjectNotFoundError
  79. res.status(404).send("Project not found")
  80. else
  81. next(error)
  82. }