ProjectRootDocManager.coffee 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. ProjectEntityHandler = require "./ProjectEntityHandler"
  2. ProjectEntityUpdateHandler = require "./ProjectEntityUpdateHandler"
  3. ProjectGetter = require "./ProjectGetter"
  4. Path = require "path"
  5. async = require("async")
  6. _ = require("underscore")
  7. module.exports = ProjectRootDocManager =
  8. setRootDocAutomatically: (project_id, callback = (error) ->) ->
  9. ProjectEntityHandler.getAllDocs project_id, (error, docs) ->
  10. return callback(error) if error?
  11. root_doc_id = null
  12. jobs = _.map docs, (doc, path)->
  13. return (cb)->
  14. rootDocId = null
  15. for line in doc.lines || []
  16. # We've had problems with this regex locking up CPU.
  17. # Previously /.*\\documentclass/ would totally lock up on lines of 500kb (data text files :()
  18. # This regex will only look from the start of the line, including whitespace so will return quickly
  19. # regardless of line length.
  20. match = /^\s*\\documentclass/.test(line)
  21. isRootDoc = /\.R?tex$/.test(Path.extname(path)) and match
  22. if isRootDoc
  23. rootDocId = doc?._id
  24. cb(rootDocId)
  25. async.series jobs, (root_doc_id)->
  26. if root_doc_id?
  27. ProjectEntityUpdateHandler.setRootDoc project_id, root_doc_id, callback
  28. else
  29. callback()
  30. setRootDocFromName: (project_id, rootDocName, callback = (error) ->) ->
  31. ProjectEntityHandler.getAllDocPathsFromProjectById project_id, (error, docPaths) ->
  32. return callback(error) if error?
  33. # strip off leading and trailing quotes from rootDocName
  34. rootDocName = rootDocName.replace(/^\'|\'$/g,"")
  35. # prepend a slash for the root folder if not present
  36. rootDocName = "/#{rootDocName}" if rootDocName[0] isnt '/'
  37. # find the root doc from the filename
  38. root_doc_id = null
  39. for doc_id, path of docPaths
  40. # docpaths have a leading / so allow matching "folder/filename" and "/folder/filename"
  41. if path == rootDocName
  42. root_doc_id = doc_id
  43. # try a basename match if there was no match
  44. if !root_doc_id
  45. for doc_id, path of docPaths
  46. if Path.basename(path) == Path.basename(rootDocName)
  47. root_doc_id = doc_id
  48. # set the root doc id if we found a match
  49. if root_doc_id?
  50. ProjectEntityUpdateHandler.setRootDoc project_id, root_doc_id, callback
  51. else
  52. callback()
  53. ensureRootDocumentIsSet: (project_id, callback = (error) ->) ->
  54. ProjectGetter.getProject project_id, rootDoc_id: 1, (error, project) ->
  55. return callback(error) if error?
  56. if !project?
  57. return callback new Error("project not found")
  58. if project.rootDoc_id?
  59. callback()
  60. else
  61. ProjectRootDocManager.setRootDocAutomatically project_id, callback