Files
overleaf-cep/services/web/app/src/Features/Editor/EditorController.js
Eric Mc Sween 864394d4ad Merge pull request #2640 from overleaf/em-promisify-project-deleter
Finish promisification of ProjectDeleter

GitOrigin-RevId: a426117c9430e2ee66b297b95f67460062a6a809
2020-03-03 04:21:39 +00:00

684 lines
16 KiB
JavaScript

/* eslint-disable
camelcase,
handle-callback-err,
max-len,
no-dupe-keys,
no-unused-vars,
*/
// TODO: This file was created by bulk-decaffeinate.
// Fix any style issues and re-enable lint.
/*
* decaffeinate suggestions:
* DS102: Remove unnecessary code created because of implicit returns
* DS207: Consider shorter variations of null checks
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
const logger = require('logger-sharelatex')
const Metrics = require('metrics-sharelatex')
const sanitize = require('sanitizer')
const ProjectEntityUpdateHandler = require('../Project/ProjectEntityUpdateHandler')
const ProjectOptionsHandler = require('../Project/ProjectOptionsHandler')
const ProjectDetailsHandler = require('../Project/ProjectDetailsHandler')
const ProjectDeleter = require('../Project/ProjectDeleter')
const DocumentUpdaterHandler = require('../DocumentUpdater/DocumentUpdaterHandler')
const EditorRealTimeController = require('./EditorRealTimeController')
const async = require('async')
const PublicAccessLevels = require('../Authorization/PublicAccessLevels')
const _ = require('underscore')
const { promisifyAll } = require('../../util/promises')
const EditorController = {
addDoc(project_id, folder_id, docName, docLines, source, user_id, callback) {
if (callback == null) {
callback = function(error, doc) {}
}
return EditorController.addDocWithRanges(
project_id,
folder_id,
docName,
docLines,
{},
source,
user_id,
callback
)
},
addDocWithRanges(
project_id,
folder_id,
docName,
docLines,
docRanges,
source,
user_id,
callback
) {
if (callback == null) {
callback = function(error, doc) {}
}
docName = docName.trim()
Metrics.inc('editor.add-doc')
return ProjectEntityUpdateHandler.addDocWithRanges(
project_id,
folder_id,
docName,
docLines,
docRanges,
user_id,
(err, doc, folder_id) => {
if (err != null) {
logger.warn(
{ err, project_id, docName },
'error adding doc without lock'
)
return callback(err)
}
EditorRealTimeController.emitToRoom(
project_id,
'reciveNewDoc',
folder_id,
doc,
source
)
return callback(err, doc)
}
)
},
addFile(
project_id,
folder_id,
fileName,
fsPath,
linkedFileData,
source,
user_id,
callback
) {
if (callback == null) {
callback = function(error, file) {}
}
fileName = fileName.trim()
Metrics.inc('editor.add-file')
return ProjectEntityUpdateHandler.addFile(
project_id,
folder_id,
fileName,
fsPath,
linkedFileData,
user_id,
(err, fileRef, folder_id) => {
if (err != null) {
logger.warn(
{ err, project_id, folder_id, fileName },
'error adding file without lock'
)
return callback(err)
}
EditorRealTimeController.emitToRoom(
project_id,
'reciveNewFile',
folder_id,
fileRef,
source,
linkedFileData
)
return callback(err, fileRef)
}
)
},
upsertDoc(
project_id,
folder_id,
docName,
docLines,
source,
user_id,
callback
) {
if (callback == null) {
callback = function(err) {}
}
return ProjectEntityUpdateHandler.upsertDoc(
project_id,
folder_id,
docName,
docLines,
source,
user_id,
function(err, doc, didAddNewDoc) {
if (didAddNewDoc) {
EditorRealTimeController.emitToRoom(
project_id,
'reciveNewDoc',
folder_id,
doc,
source
)
}
return callback(err, doc)
}
)
},
upsertFile(
project_id,
folder_id,
fileName,
fsPath,
linkedFileData,
source,
user_id,
callback
) {
if (callback == null) {
callback = function(err, file) {}
}
return ProjectEntityUpdateHandler.upsertFile(
project_id,
folder_id,
fileName,
fsPath,
linkedFileData,
user_id,
function(err, newFile, didAddFile, existingFile) {
if (err != null) {
return callback(err)
}
if (!didAddFile) {
// replacement, so remove the existing file from the client
EditorRealTimeController.emitToRoom(
project_id,
'removeEntity',
existingFile._id,
source
)
}
// now add the new file on the client
EditorRealTimeController.emitToRoom(
project_id,
'reciveNewFile',
folder_id,
newFile,
source,
linkedFileData
)
return callback(null, newFile)
}
)
},
upsertDocWithPath(
project_id,
elementPath,
docLines,
source,
user_id,
callback
) {
return ProjectEntityUpdateHandler.upsertDocWithPath(
project_id,
elementPath,
docLines,
source,
user_id,
function(err, doc, didAddNewDoc, newFolders, lastFolder) {
if (err != null) {
return callback(err)
}
return EditorController._notifyProjectUsersOfNewFolders(
project_id,
newFolders,
function(err) {
if (err != null) {
return callback(err)
}
if (didAddNewDoc) {
EditorRealTimeController.emitToRoom(
project_id,
'reciveNewDoc',
lastFolder._id,
doc,
source
)
}
return callback()
}
)
}
)
},
upsertFileWithPath(
project_id,
elementPath,
fsPath,
linkedFileData,
source,
user_id,
callback
) {
return ProjectEntityUpdateHandler.upsertFileWithPath(
project_id,
elementPath,
fsPath,
linkedFileData,
user_id,
function(err, newFile, didAddFile, existingFile, newFolders, lastFolder) {
if (err != null) {
return callback(err)
}
return EditorController._notifyProjectUsersOfNewFolders(
project_id,
newFolders,
function(err) {
if (err != null) {
return callback(err)
}
if (!didAddFile) {
// replacement, so remove the existing file from the client
EditorRealTimeController.emitToRoom(
project_id,
'removeEntity',
existingFile._id,
source
)
}
// now add the new file on the client
EditorRealTimeController.emitToRoom(
project_id,
'reciveNewFile',
lastFolder._id,
newFile,
source,
linkedFileData
)
return callback()
}
)
}
)
},
addFolder(project_id, folder_id, folderName, source, callback) {
if (callback == null) {
callback = function(error, folder) {}
}
folderName = folderName.trim()
Metrics.inc('editor.add-folder')
return ProjectEntityUpdateHandler.addFolder(
project_id,
folder_id,
folderName,
(err, folder, folder_id) => {
if (err != null) {
logger.warn(
{ err, project_id, folder_id, folderName, source },
'could not add folder'
)
return callback(err)
}
return EditorController._notifyProjectUsersOfNewFolder(
project_id,
folder_id,
folder,
function(err) {
if (err != null) {
return callback(err)
}
return callback(null, folder)
}
)
}
)
},
mkdirp(project_id, path, callback) {
if (callback == null) {
callback = function(error, newFolders, lastFolder) {}
}
logger.log({ project_id, path }, "making directories if they don't exist")
return ProjectEntityUpdateHandler.mkdirp(
project_id,
path,
(err, newFolders, lastFolder) => {
if (err != null) {
logger.warn({ err, project_id, path }, 'could not mkdirp')
return callback(err)
}
return EditorController._notifyProjectUsersOfNewFolders(
project_id,
newFolders,
function(err) {
if (err != null) {
return callback(err)
}
return callback(null, newFolders, lastFolder)
}
)
}
)
},
deleteEntity(project_id, entity_id, entityType, source, userId, callback) {
if (callback == null) {
callback = function(error) {}
}
Metrics.inc('editor.delete-entity')
return ProjectEntityUpdateHandler.deleteEntity(
project_id,
entity_id,
entityType,
userId,
function(err) {
if (err != null) {
logger.warn(
{ err, project_id, entity_id, entityType },
'could not delete entity'
)
return callback(err)
}
logger.log(
{ project_id, entity_id, entityType },
'telling users entity has been deleted'
)
EditorRealTimeController.emitToRoom(
project_id,
'removeEntity',
entity_id,
source
)
return callback()
}
)
},
deleteEntityWithPath(project_id, path, source, user_id, callback) {
return ProjectEntityUpdateHandler.deleteEntityWithPath(
project_id,
path,
user_id,
function(err, entity_id) {
if (err != null) {
return callback(err)
}
EditorRealTimeController.emitToRoom(
project_id,
'removeEntity',
entity_id,
source
)
return callback(null, entity_id)
}
)
},
updateProjectDescription(project_id, description, callback) {
if (callback == null) {
callback = function() {}
}
logger.log({ project_id, description }, 'updating project description')
return ProjectDetailsHandler.setProjectDescription(
project_id,
description,
function(err) {
if (err != null) {
logger.warn(
{ err, project_id, description },
'something went wrong setting the project description'
)
return callback(err)
}
EditorRealTimeController.emitToRoom(
project_id,
'projectDescriptionUpdated',
description
)
return callback()
}
)
},
deleteProject(project_id, callback) {
Metrics.inc('editor.delete-project')
return ProjectDeleter.deleteProject(project_id, callback)
},
renameEntity(project_id, entity_id, entityType, newName, userId, callback) {
if (callback == null) {
callback = function(error) {}
}
newName = sanitize.escape(newName)
Metrics.inc('editor.rename-entity')
return ProjectEntityUpdateHandler.renameEntity(
project_id,
entity_id,
entityType,
newName,
userId,
function(err) {
if (err != null) {
logger.warn(
{ err, project_id, entity_id, entityType, newName },
'error renaming entity'
)
return callback(err)
}
if (newName.length > 0) {
EditorRealTimeController.emitToRoom(
project_id,
'reciveEntityRename',
entity_id,
newName
)
}
return callback()
}
)
},
moveEntity(project_id, entity_id, folder_id, entityType, userId, callback) {
if (callback == null) {
callback = function(error) {}
}
Metrics.inc('editor.move-entity')
return ProjectEntityUpdateHandler.moveEntity(
project_id,
entity_id,
folder_id,
entityType,
userId,
function(err) {
if (err != null) {
logger.warn(
{ err, project_id, entity_id, folder_id },
'error moving entity'
)
return callback(err)
}
EditorRealTimeController.emitToRoom(
project_id,
'reciveEntityMove',
entity_id,
folder_id
)
return callback()
}
)
},
renameProject(project_id, newName, callback) {
if (callback == null) {
callback = function(err) {}
}
return ProjectDetailsHandler.renameProject(project_id, newName, function(
err
) {
if (err != null) {
logger.warn({ err, project_id, newName }, 'error renaming project')
return callback(err)
}
EditorRealTimeController.emitToRoom(
project_id,
'projectNameUpdated',
newName
)
return callback()
})
},
setCompiler(project_id, compiler, callback) {
if (callback == null) {
callback = function(err) {}
}
return ProjectOptionsHandler.setCompiler(project_id, compiler, function(
err
) {
if (err != null) {
return callback(err)
}
EditorRealTimeController.emitToRoom(
project_id,
'compilerUpdated',
compiler
)
return callback()
})
},
setImageName(project_id, imageName, callback) {
if (callback == null) {
callback = function(err) {}
}
return ProjectOptionsHandler.setImageName(project_id, imageName, function(
err
) {
if (err != null) {
return callback(err)
}
EditorRealTimeController.emitToRoom(
project_id,
'imageNameUpdated',
imageName
)
return callback()
})
},
setSpellCheckLanguage(project_id, languageCode, callback) {
if (callback == null) {
callback = function(err) {}
}
return ProjectOptionsHandler.setSpellCheckLanguage(
project_id,
languageCode,
function(err) {
if (err != null) {
return callback(err)
}
EditorRealTimeController.emitToRoom(
project_id,
'spellCheckLanguageUpdated',
languageCode
)
return callback()
}
)
},
setPublicAccessLevel(project_id, newAccessLevel, callback) {
if (callback == null) {
callback = function(err) {}
}
return ProjectDetailsHandler.setPublicAccessLevel(
project_id,
newAccessLevel,
function(err) {
if (err != null) {
return callback(err)
}
EditorRealTimeController.emitToRoom(
project_id,
'project:publicAccessLevel:changed',
{ newAccessLevel }
)
if (newAccessLevel === PublicAccessLevels.TOKEN_BASED) {
return ProjectDetailsHandler.ensureTokensArePresent(
project_id,
function(err, tokens) {
if (err != null) {
return callback(err)
}
EditorRealTimeController.emitToRoom(
project_id,
'project:tokens:changed',
{ tokens }
)
return callback()
}
)
} else {
return callback()
}
}
)
},
setRootDoc(project_id, newRootDocID, callback) {
if (callback == null) {
callback = function(err) {}
}
return ProjectEntityUpdateHandler.setRootDoc(
project_id,
newRootDocID,
function(err) {
if (err != null) {
return callback(err)
}
EditorRealTimeController.emitToRoom(
project_id,
'rootDocUpdated',
newRootDocID
)
return callback()
}
)
},
_notifyProjectUsersOfNewFolders(project_id, folders, callback) {
if (callback == null) {
callback = function(error) {}
}
return async.eachSeries(
folders,
(folder, cb) =>
EditorController._notifyProjectUsersOfNewFolder(
project_id,
folder.parentFolder_id,
folder,
cb
),
callback
)
},
_notifyProjectUsersOfNewFolder(project_id, folder_id, folder, callback) {
if (callback == null) {
callback = function(error) {}
}
EditorRealTimeController.emitToRoom(
project_id,
'reciveNewFolder',
folder_id,
folder
)
return callback()
}
}
EditorController.promises = promisifyAll(EditorController)
module.exports = EditorController