ProjectOutputFileAgent.coffee 3.7 KB

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