TpdsUpdateHandler.js 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. const UpdateMerger = require('./UpdateMerger')
  2. const logger = require('logger-sharelatex')
  3. const NotificationsBuilder = require('../Notifications/NotificationsBuilder')
  4. const ProjectCreationHandler = require('../Project/ProjectCreationHandler')
  5. const ProjectDeleter = require('../Project/ProjectDeleter')
  6. const ProjectGetter = require('../Project/ProjectGetter')
  7. const ProjectHelper = require('../Project/ProjectHelper')
  8. const ProjectRootDocManager = require('../Project/ProjectRootDocManager')
  9. const FileTypeManager = require('../Uploads/FileTypeManager')
  10. const CooldownManager = require('../Cooldown/CooldownManager')
  11. const Errors = require('../Errors/Errors')
  12. const Modules = require('../../infrastructure/Modules')
  13. const ROOT_DOC_TIMEOUT_LENGTH = 30 * 1000
  14. function newUpdate(userId, projectName, path, updateRequest, source, callback) {
  15. getOrCreateProject(userId, projectName, (err, project) => {
  16. if (err) {
  17. return callback(err)
  18. }
  19. if (project == null) {
  20. return callback()
  21. }
  22. CooldownManager.isProjectOnCooldown(
  23. project._id,
  24. (err, projectIsOnCooldown) => {
  25. if (err) {
  26. return callback(err)
  27. }
  28. if (projectIsOnCooldown) {
  29. return callback(
  30. new Errors.TooManyRequestsError('project on cooldown')
  31. )
  32. }
  33. FileTypeManager.shouldIgnore(path, (err, shouldIgnore) => {
  34. if (err) {
  35. return callback(err)
  36. }
  37. if (shouldIgnore) {
  38. return callback()
  39. }
  40. UpdateMerger.mergeUpdate(
  41. userId,
  42. project._id,
  43. path,
  44. updateRequest,
  45. source,
  46. callback
  47. )
  48. })
  49. }
  50. )
  51. })
  52. }
  53. function deleteUpdate(userId, projectName, path, source, callback) {
  54. logger.debug({ userId, filePath: path }, 'handling delete update from tpds')
  55. ProjectGetter.findUsersProjectsByName(
  56. userId,
  57. projectName,
  58. (err, projects) => {
  59. if (err) {
  60. return callback(err)
  61. }
  62. const activeProjects = projects.filter(
  63. project => !ProjectHelper.isArchivedOrTrashed(project, userId)
  64. )
  65. if (activeProjects.length === 0) {
  66. logger.debug(
  67. { userId, filePath: path, projectName },
  68. 'project not found from tpds update, ignoring folder or project'
  69. )
  70. return callback()
  71. }
  72. if (projects.length > 1) {
  73. // There is more than one project with that name, and one of them is
  74. // active (previous condition)
  75. return handleDuplicateProjects(userId, projectName, callback)
  76. }
  77. const project = activeProjects[0]
  78. if (path === '/') {
  79. logger.debug(
  80. { userId, filePath: path, projectName, project_id: project._id },
  81. 'project found for delete update, path is root so marking project as deleted'
  82. )
  83. ProjectDeleter.markAsDeletedByExternalSource(project._id, callback)
  84. } else {
  85. UpdateMerger.deleteUpdate(userId, project._id, path, source, err => {
  86. callback(err)
  87. })
  88. }
  89. }
  90. )
  91. }
  92. function getOrCreateProject(userId, projectName, callback) {
  93. ProjectGetter.findUsersProjectsByName(
  94. userId,
  95. projectName,
  96. (err, projects) => {
  97. if (err) {
  98. return callback(err)
  99. }
  100. if (projects.length === 0) {
  101. // No project with that name -- active, archived or trashed -- has been
  102. // found. Create one.
  103. return ProjectCreationHandler.createBlankProject(
  104. userId,
  105. projectName,
  106. (err, project) => {
  107. // have a crack at setting the root doc after a while, on creation
  108. // we won't have it yet, but should have been sent it it within 30
  109. // seconds
  110. setTimeout(() => {
  111. ProjectRootDocManager.setRootDocAutomatically(project._id)
  112. }, ROOT_DOC_TIMEOUT_LENGTH)
  113. callback(err, project)
  114. }
  115. )
  116. }
  117. const activeProjects = projects.filter(
  118. project => !ProjectHelper.isArchivedOrTrashed(project, userId)
  119. )
  120. if (activeProjects.length === 0) {
  121. // All projects with that name are archived or trashed. Ignore.
  122. return callback(null, null)
  123. }
  124. if (projects.length > 1) {
  125. // There is more than one project with that name, and one of them is
  126. // active (previous condition)
  127. return handleDuplicateProjects(userId, projectName, err => {
  128. if (err) {
  129. return callback(err)
  130. }
  131. callback(null, null)
  132. })
  133. }
  134. callback(err, activeProjects[0])
  135. }
  136. )
  137. }
  138. function handleDuplicateProjects(userId, projectName, callback) {
  139. Modules.hooks.fire('removeDropbox', userId, 'duplicate-projects', err => {
  140. if (err) {
  141. return callback(err)
  142. }
  143. NotificationsBuilder.dropboxDuplicateProjectNames(userId).create(
  144. projectName,
  145. callback
  146. )
  147. })
  148. }
  149. module.exports = {
  150. newUpdate,
  151. deleteUpdate,
  152. }