ProjectController.coffee 8.3 KB

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