ProjectOutputFileAgent.coffee 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  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. # TODO:
  54. # - Compile project
  55. # - Get output file content
  56. # - Write to disk
  57. # - callback with fs-path
  58. if !ProjectOutputFileAgent._validate(data)
  59. return callback(new BadDataError())
  60. { source_project_id, source_output_file_path } = data
  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 SourceFileNotFoundError
  82. res.status(404).send("Source file not found")
  83. else if error instanceof ProjectNotFoundError
  84. res.status(404).send("Project not found")
  85. else
  86. next(error)
  87. }