_ = 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 files 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