CompileController.coffee 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. RequestParser = require "./RequestParser"
  2. CompileManager = require "./CompileManager"
  3. Settings = require "settings-sharelatex"
  4. Metrics = require "./Metrics"
  5. ProjectPersistenceManager = require "./ProjectPersistenceManager"
  6. logger = require "logger-sharelatex"
  7. Errors = require "./Errors"
  8. module.exports = CompileController =
  9. compile: (req, res, next = (error) ->) ->
  10. timer = new Metrics.Timer("compile-request")
  11. RequestParser.parse req.body, (error, request) ->
  12. return next(error) if error?
  13. request.project_id = req.params.project_id
  14. request.user_id = req.params.user_id if req.params.user_id?
  15. ProjectPersistenceManager.markProjectAsJustAccessed request.project_id, (error) ->
  16. return next(error) if error?
  17. CompileManager.doCompileWithLock request, (error, outputFiles = []) ->
  18. if error instanceof Errors.AlreadyCompilingError
  19. code = 423 # Http 423 Locked
  20. status = "compile-in-progress"
  21. else if error instanceof Errors.FilesOutOfSyncError
  22. code = 409 # Http 409 Conflict
  23. status = "retry"
  24. else if error?.terminated
  25. status = "terminated"
  26. else if error?.validate
  27. status = "validation-#{error.validate}"
  28. else if error?.timedout
  29. status = "timedout"
  30. logger.log err: error, project_id: request.project_id, "timeout running compile"
  31. else if error?
  32. status = "error"
  33. code = 500
  34. logger.warn err: error, project_id: request.project_id, "error running compile"
  35. else
  36. status = "failure"
  37. for file in outputFiles
  38. if file.path?.match(/output\.pdf$/)
  39. status = "success"
  40. if status == "failure"
  41. logger.warn project_id: request.project_id, outputFiles:outputFiles, "project failed to compile successfully, no output.pdf generated"
  42. # log an error if any core files are found
  43. for file in outputFiles
  44. if file.path is "core"
  45. logger.error project_id:request.project_id, req:req, outputFiles:outputFiles, "core file found in output"
  46. if error?
  47. outputFiles = error.outputFiles || []
  48. timer.done()
  49. res.status(code or 200).send {
  50. compile:
  51. status: status
  52. error: error?.message or error
  53. outputFiles: outputFiles.map (file) ->
  54. url:
  55. "#{Settings.apis.clsi.url}/project/#{request.project_id}" +
  56. (if request.user_id? then "/user/#{request.user_id}" else "") +
  57. (if file.build? then "/build/#{file.build}" else "") +
  58. "/output/#{file.path}"
  59. path: file.path
  60. type: file.type
  61. build: file.build
  62. }
  63. stopCompile: (req, res, next) ->
  64. {project_id, user_id} = req.params
  65. CompileManager.stopCompile project_id, user_id, (error) ->
  66. return next(error) if error?
  67. res.sendStatus(204)
  68. clearCache: (req, res, next = (error) ->) ->
  69. ProjectPersistenceManager.clearProject req.params.project_id, req.params.user_id, (error) ->
  70. return next(error) if error?
  71. res.sendStatus(204) # No content
  72. syncFromCode: (req, res, next = (error) ->) ->
  73. file = req.query.file
  74. line = parseInt(req.query.line, 10)
  75. column = parseInt(req.query.column, 10)
  76. project_id = req.params.project_id
  77. user_id = req.params.user_id
  78. CompileManager.syncFromCode project_id, user_id, file, line, column, (error, pdfPositions) ->
  79. return next(error) if error?
  80. res.json {
  81. pdf: pdfPositions
  82. }
  83. syncFromPdf: (req, res, next = (error) ->) ->
  84. page = parseInt(req.query.page, 10)
  85. h = parseFloat(req.query.h)
  86. v = parseFloat(req.query.v)
  87. project_id = req.params.project_id
  88. user_id = req.params.user_id
  89. CompileManager.syncFromPdf project_id, user_id, page, h, v, (error, codePositions) ->
  90. return next(error) if error?
  91. res.json {
  92. code: codePositions
  93. }
  94. wordcount: (req, res, next = (error) ->) ->
  95. file = req.query.file || "main.tex"
  96. project_id = req.params.project_id
  97. user_id = req.params.user_id
  98. image = req.query.image
  99. logger.log {image, file, project_id}, "word count request"
  100. CompileManager.wordcount project_id, user_id, file, image, (error, result) ->
  101. return next(error) if error?
  102. res.json {
  103. texcount: result
  104. }
  105. status: (req, res, next = (error)-> )->
  106. res.send("OK")