ProjectController.coffee 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. async = require("async")
  2. logger = require("logger-sharelatex")
  3. projectDeleter = require("./ProjectDeleter")
  4. projectDuplicator = require("./ProjectDuplicator")
  5. projectCreationHandler = require("./ProjectCreationHandler")
  6. metrics = require('../../infrastructure/Metrics')
  7. sanitize = require('sanitizer')
  8. Project = require('../../models/Project').Project
  9. User = require('../../models/User').User
  10. TagsHandler = require("../Tags/TagsHandler")
  11. SubscriptionLocator = require("../Subscription/SubscriptionLocator")
  12. _ = require("underscore")
  13. Settings = require("settings-sharelatex")
  14. SecurityManager = require("../../managers/SecurityManager")
  15. module.exports =
  16. deleteProject: (req, res)->
  17. project_id = req.params.Project_id
  18. logger.log project_id:project_id, "deleting project"
  19. projectDeleter.deleteProject project_id, (err)->
  20. if err?
  21. res.send 500
  22. else
  23. res.send 200
  24. cloneProject: (req, res)->
  25. metrics.inc "cloned-project"
  26. project_id = req.params.Project_id
  27. projectName = req.body.projectName
  28. logger.log project_id:project_id, projectName:projectName, "cloning project"
  29. if !req.session.user?
  30. return res.send redir:"/register"
  31. projectDuplicator.duplicate req.session.user, project_id, projectName, (err, project)->
  32. if err?
  33. logger.error err:err, project_id: project_id, user_id: req.session.user._id, "error cloning project"
  34. return next(err)
  35. res.send(project_id:project._id)
  36. newProject: (req, res)->
  37. user = req.session.user
  38. projectName = sanitize.escape(req.body.projectName)
  39. template = sanitize.escape(req.body.template)
  40. logger.log user: user, type: template, name: projectName, "creating project"
  41. async.waterfall [
  42. (cb)->
  43. if template == 'example'
  44. projectCreationHandler.createExampleProject user._id, projectName, cb
  45. else
  46. projectCreationHandler.createBasicProject user._id, projectName, cb
  47. ], (err, project)->
  48. if err?
  49. logger.error err: err, project: project, user: user, name: projectName, type: template, "error creating project"
  50. res.send 500
  51. else
  52. logger.log project: project, user: user, name: projectName, type: template, "created project"
  53. res.send {project_id:project._id}
  54. projectListPage: (req, res, next)->
  55. timer = new metrics.Timer("project-list")
  56. user_id = req.session.user._id
  57. async.parallel {
  58. subscription: (cb)->
  59. SubscriptionLocator.getUsersSubscription user_id, cb
  60. tags: (cb)->
  61. TagsHandler.getAllTags user_id, cb
  62. projects: (cb)->
  63. Project.findAllUsersProjects user_id, 'name lastUpdated publicAccesLevel', cb
  64. }, (err, results)->
  65. if err?
  66. logger.err err:err, "error getting data for project list page"
  67. return res.send 500
  68. logger.log results:results, user_id:user_id, "rendering project list"
  69. viewModel = _buildListViewModel results.projects[0], results.projects[1], results.projects[2], results.tags[0], results.tags[1], results.subscription?[0]
  70. res.render 'project/list', viewModel
  71. timer.done()
  72. loadEditor: (req, res)->
  73. timer = new metrics.Timer("load-editor")
  74. if !Settings.editorIsOpen
  75. return res.render("general/closed", {title:"updating site"})
  76. user_id = if req.session.user? then req.session.user._id else 'openUser'
  77. project_id = req.params.Project_id
  78. async.parallel {
  79. project: (cb)->
  80. Project.findPopulatedById project_id, cb
  81. user: (cb)->
  82. User.findById user_id, cb
  83. subscription: (cb)->
  84. SubscriptionLocator.getUsersSubscription user_id, cb
  85. }, (err, results)->
  86. if err?
  87. return res.send 500
  88. project = results.project
  89. user = results.user
  90. subscription = results.subscription
  91. if user_id == 'openUser'
  92. anonymous = true
  93. user = defaultSettingsForAnonymousUser(user_id)
  94. else
  95. anonymous = false
  96. SecurityManager.userCanAccessProject user, project, (canAccess, privilegeLevel)->
  97. if !canAccess
  98. return res.send 401
  99. if subscription? and subscription.freeTrial? and subscription.freeTrial.expiresAt?
  100. allowedFreeTrial = !!subscription.freeTrial.allowed || true
  101. res.render 'project/editor',
  102. title: project.name
  103. priority_title: true
  104. bodyClasses: ["editor"]
  105. project : project
  106. userObject : JSON.stringify({
  107. id : user.id
  108. email : user.email
  109. first_name : user.first_name
  110. last_name : user.last_name
  111. referal_id : user.referal_id
  112. subscription :
  113. freeTrial: {allowed: allowedFreeTrial}
  114. })
  115. userSettingsObject: JSON.stringify({
  116. mode : user.ace.mode
  117. theme : user.ace.theme
  118. project_id : project._id
  119. fontSize : user.ace.fontSize
  120. autoComplete: user.ace.autoComplete
  121. spellCheckLanguage: user.ace.spellCheckLanguage
  122. pdfViewer : user.ace.pdfViewer
  123. docPositions: {}
  124. oldHistory: !!user.featureSwitches?.oldHistory
  125. })
  126. sharelatexObject : JSON.stringify({
  127. siteUrl: Settings.siteUrl,
  128. jsPath: res.locals.jsPath
  129. })
  130. privilegeLevel: privilegeLevel
  131. loadPdfjs: (user.ace.pdfViewer == "pdfjs")
  132. chatUrl: Settings.apis.chat.url
  133. anonymous: anonymous
  134. languages: Settings.languages
  135. timer.done()
  136. defaultSettingsForAnonymousUser = ->
  137. id : user_id
  138. ace:
  139. mode:'none'
  140. theme:'textmate'
  141. fontSize: '12'
  142. autoComplete: true
  143. spellCheckLanguage: ""
  144. pdfViewer: ""
  145. subscription:
  146. freeTrial:
  147. allowed: true
  148. featureSwitches:
  149. dropbox: false
  150. trackChanges: false
  151. _buildListViewModel = (projects, collabertions, readOnlyProjects, tags, tagsGroupedByProject, subscription)->
  152. # TODO: Remove this one month after the ability to start free trials was removed
  153. if subscription? and subscription.freeTrial? and subscription.freeTrial.expiresAt?
  154. freeTrial =
  155. expired: !!subscription.freeTrial.downgraded
  156. expiresAt: SubscriptionFormatters.formatDate(subscription.freeTrial.expiresAt)
  157. for project in projects
  158. project.accessLevel = "owner"
  159. for project in collabertions
  160. project.accessLevel = "readWrite"
  161. for project in readOnlyProjects
  162. project.accessLevel = "readOnly"
  163. projects = projects.concat(collabertions).concat(readOnlyProjects)
  164. projects = projects.map (project)->
  165. project.tags = tagsGroupedByProject[project._id] || []
  166. return project
  167. tags = _.sortBy tags, (tag)->
  168. -tag.project_ids.length
  169. sortedProjects = _.sortBy projects, (project)->
  170. return - project.lastUpdated
  171. return {
  172. title:'Your Projects'
  173. priority_title: true
  174. projects: sortedProjects
  175. freeTrial: freeTrial
  176. tags:tags
  177. projectTabActive: true
  178. }