ProjectController.coffee 8.2 KB

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