Przeglądaj źródła

WIP: Add ProjectFileAgent

Shane Kilkelly 8 lat temu
rodzic
commit
5cb85c0332

+ 3 - 2
services/web/app/coffee/Features/LinkedFiles/LinkedFilesController.coffee

@@ -5,7 +5,8 @@ logger = require 'logger-sharelatex'
 
 module.exports = LinkedFilesController = {
 	Agents: {
-		url: require('./UrlAgent')
+		url: require('./UrlAgent'),
+		project_file: require('./ProjectFileAgent')
 	}
 
 	createLinkedFile: (req, res, next) ->
@@ -29,4 +30,4 @@ module.exports = LinkedFilesController = {
 			EditorController.upsertFile project_id, parent_folder_id, name, fsPath, linkedFileData, "upload", user_id, (error) ->
 				return next(error) if error?
 				res.send(204) # created
-}
+}

+ 70 - 0
services/web/app/coffee/Features/LinkedFiles/ProjectFileAgent.coffee

@@ -0,0 +1,70 @@
+FileWriter = require('../../infrastructure/FileWriter')
+AuthorizationManager = require('../Authorization/AuthorizationManager')
+ProjectLocator = require('../Project/ProjectLocator')
+DocstoreManager = require('../Docstore/DocstoreManager')
+FileStoreHandler = require('../FileStore/FileStoreHandler')
+FileWriter = require('../../infrastructure/FileWriter')
+_ = require "underscore"
+Settings = require 'settings-sharelatex'
+
+
+AccessDeniedError = (message) ->
+	error = new Error(message)
+	error.name = 'AccessDenied'
+	error.__proto__ = AccessDeniedError.prototype
+	return error
+AccessDeniedError.prototype.__proto__ = Error.prototype
+
+BadEntityTypeError = (message) ->
+	error = new Error(message)
+	error.name = 'BadEntityType'
+	error.__proto__ = BadEntityTypeError.prototype
+	return error
+BadEntityTypeError.prototype.__proto__ = Error.prototype
+
+
+module.exports = ProjectFileAgent =
+
+	sanitizeData: (data) ->
+		# TODO:
+		#   - Nothing?
+		return data
+
+	writeIncomingFileToDisk:
+		(project_id, data, current_user_id, callback = (error, fsPath) ->) ->
+			callback = _.once(callback)
+			{source_project_id, source_entity_path} = data
+			AuthorizationManager.canUserReadProject current_user_id, source_project_id,
+				null, (err, canRead) ->
+					return callback(err) if err?
+					return callback(new AccessDeniedError()) if !canRead
+					ProjectLocator.findElementByPath {
+						project_id: source_project_id,
+						path: source_entity_path
+					}, (err, entity, type) ->
+						return callback(err) if err?  # also applies when file not found
+						ProjectFileAgent._writeEntityToDisk source_project_id, entity._id, type, callback
+
+	_writeEntityToDisk: (project_id, entity_id, type, callback=(err, location)->) ->
+		callback = _.once(callback)
+		if type == 'doc'
+			DocstoreManager.getDoc project_id, entity_id, (err, lines) ->
+				return callback(err) if err?
+				FileWriter.writeLinesToDisk entity_id, lines, callback
+		else if type == 'file'
+			FileStoreHandler.getFileStream project_id, entity_id, (err, fileStream) ->
+				return callback(err) if err?
+				FileWriter.writeStreamToDisk entity_id, fileStream, callback
+		else
+			callback(new BadEntityTypeError())
+
+	handleError: (error, req, res, next) ->
+		if error instanceof AccessDeniedError
+			res.status(403).send("You do not have access to this project")
+		else if error instanceof FileNotFoundError
+			res.status(404).send("The file does not exist")
+		else if error instanceof BadEntityTypeError
+			res.status(404).send("The file is the wrong type")  # TODO: better error message
+		else
+			next(error)
+		next()

+ 13 - 1
services/web/app/coffee/infrastructure/FileWriter.coffee

@@ -6,6 +6,18 @@ Settings = require 'settings-sharelatex'
 request = require 'request'
 
 module.exports = FileWriter =
+
+	writeLinesToDisk: (identifier, lines, callback = (error, fsPath)->) ->
+		callback = _.once(callback)
+		fsPath = "#{Settings.path.dumpFolder}/#{identifier}_#{uuid.v4()}"
+		fs.mkdir Settings.path.dumpFolder, (error) ->
+			if error? and error.code != 'EEXIST'
+				# Ignore error about already existing
+				return callback(error)
+			fs.writeFile fsPath, lines.join('\n'), (error) ->
+				return callback(error) if error?
+				callback(null, fsPath)
+
 	writeStreamToDisk: (identifier, stream, callback = (error, fsPath) ->) ->
 		callback = _.once(callback)
 		fsPath = "#{Settings.path.dumpFolder}/#{identifier}_#{uuid.v4()}"
@@ -39,4 +51,4 @@ module.exports = FileWriter =
 			else
 				err = new Error("bad response from url: #{response.statusCode}")
 				logger.err {err, identifier, url}, err.message
-				callback(err)
+				callback(err)

+ 12 - 0
services/web/public/coffee/ide/file-tree/FileTreeManager.coffee

@@ -25,6 +25,18 @@ define [
 			$(document).on "click", =>
 				@clearMultiSelectedEntities()
 				@$scope.$digest()
+			window.doLinkedFileImportFromProject = (project, path, name) =>
+				parent_folder = @getCurrentFolder()
+				@ide.$http.post "/project/#{@ide.project_id}/linked_file", {
+					name: name,
+					parent_folder_id: parent_folder?.id
+					provider: 'project_file',
+					data: {
+						source_project_id: project,
+						source_entity_path: path
+					},
+					_csrf: window.csrfToken
+				}
 
 		_bindToSocketEvents: () ->
 			@ide.socket.on "reciveNewDoc", (parent_folder_id, doc) =>