overleaf/services/web/app/coffee/Features/Project/ProjectEntityHandler.coffee
2018-03-09 11:11:06 +00:00

133 lines
5.2 KiB
CoffeeScript

_ = require('underscore')
async = require "async"
path = require "path"
logger = require('logger-sharelatex')
DocstoreManager = require "../Docstore/DocstoreManager"
DocumentUpdaterHandler = require('../../Features/DocumentUpdater/DocumentUpdaterHandler')
Errors = require '../Errors/Errors'
Project = require('../../models/Project').Project
ProjectLocator = require('./ProjectLocator')
ProjectGetter = require "./ProjectGetter"
TpdsUpdateSender = require('../ThirdPartyDataStore/TpdsUpdateSender')
module.exports = ProjectEntityHandler = self =
getAllDocs: (project_id, callback) ->
logger.log project_id:project_id, "getting all docs for project"
# We get the path and name info from the project, and the lines and
# version info from the doc store.
DocstoreManager.getAllDocs project_id, (error, docContentsArray) ->
return callback(error) if error?
# Turn array from docstore into a dictionary based on doc id
docContents = {}
for docContent in docContentsArray
docContents[docContent._id] = docContent
self._getAllFolders project_id, (error, folders = {}) ->
return callback(error) if error?
docs = {}
for folderPath, folder of folders
for doc in (folder.docs or [])
content = docContents[doc._id.toString()]
if content?
docs[path.join(folderPath, doc.name)] = {
_id: doc._id
name: doc.name
lines: content.lines
rev: content.rev
}
logger.log count:_.keys(docs).length, project_id:project_id, "returning docs for project"
callback null, docs
getAllFiles: (project_id, callback) ->
logger.log project_id:project_id, "getting all files for project"
self._getAllFolders project_id, (err, folders = {}) ->
return callback(err) if err?
files = {}
for folderPath, folder of folders
for file in (folder.fileRefs or [])
if file?
files[path.join(folderPath, file.name)] = file
callback null, files
getAllEntitiesFromProject: (project, callback) ->
logger.log project:project, "getting all entities for project"
self._getAllFoldersFromProject project, (err, folders = {}) ->
return callback(err) if err?
docs = []
files = []
for folderPath, folder of folders
for doc in (folder.docs or [])
if doc?
docs.push({path: path.join(folderPath, doc.name), doc:doc})
for file in (folder.fileRefs or [])
if file?
files.push({path: path.join(folderPath, file.name), file:file})
callback null, docs, files
getAllDocPathsFromProject: (project, callback) ->
logger.log project:project, "getting all docs for project"
self._getAllFoldersFromProject project, (err, folders = {}) ->
return callback(err) if err?
docPath = {}
for folderPath, folder of folders
for doc in (folder.docs or [])
docPath[doc._id] = path.join(folderPath, doc.name)
logger.log count:_.keys(docPath).length, project_id:project._id, "returning docPaths for project"
callback null, docPath
flushProjectToThirdPartyDataStore: (project_id, callback) ->
logger.log project_id:project_id, "flushing project to tpds"
DocumentUpdaterHandler.flushProjectToMongo project_id, (error) ->
return callback(error) if error?
ProjectGetter.getProject project_id, {name:true}, (error, project) ->
return callback(error) if error?
requests = []
self.getAllDocs project_id, (error, docs) ->
return callback(error) if error?
for docPath, doc of docs
do (docPath, doc) ->
requests.push (cb) ->
TpdsUpdateSender.addDoc {project_id:project_id, doc_id:doc._id, path:docPath, project_name:project.name, rev:doc.rev||0}, cb
self.getAllFiles project_id, (error, files) ->
return callback(error) if error?
for filePath, file of files
do (filePath, file) ->
requests.push (cb) ->
TpdsUpdateSender.addFile {project_id:project_id, file_id:file._id, path:filePath, project_name:project.name, rev:file.rev}, cb
async.series requests, (err) ->
logger.log project_id:project_id, "finished flushing project to tpds"
callback(err)
getDoc: (project_id, doc_id, options = {}, callback = (error, lines, rev) ->) ->
if typeof(options) == "function"
callback = options
options = {}
if options["pathname"]
delete options["pathname"]
ProjectLocator.findElement {project_id: project_id, element_id: doc_id, type: 'doc'}, (error, doc, path) =>
return callback(error) if error?
DocstoreManager.getDoc project_id, doc_id, options, (error, lines, rev, version, ranges) =>
callback(error, lines, rev, version, ranges, path.fileSystem)
else
DocstoreManager.getDoc project_id, doc_id, options, callback
_getAllFolders: (project_id, callback) ->
logger.log project_id:project_id, "getting all folders for project"
ProjectGetter.getProjectWithoutDocLines project_id, (err, project) ->
return callback(err) if err?
return callback(Errors.NotFoundError("no project")) if !project?
self._getAllFoldersFromProject project, callback
_getAllFoldersFromProject: (project, callback) ->
folders = {}
processFolder = (basePath, folder) ->
folders[basePath] = folder
for childFolder in (folder.folders or [])
if childFolder.name?
processFolder path.join(basePath, childFolder.name), childFolder
processFolder "/", project.rootFolder[0]
callback null, folders