/* eslint-disable camelcase, node/handle-callback-err, max-len, 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 */ let ProjectOutputFileAgent const AuthorizationManager = require('../Authorization/AuthorizationManager') const ProjectGetter = require('../Project/ProjectGetter') const Settings = require('settings-sharelatex') const CompileManager = require('../Compile/CompileManager') const ClsiManager = require('../Compile/ClsiManager') const ProjectFileAgent = require('./ProjectFileAgent') const _ = require('underscore') const { BadDataError, AccessDeniedError, BadEntityTypeError, OutputFileFetchFailedError } = require('./LinkedFilesErrors') const LinkedFilesHandler = require('./LinkedFilesHandler') const logger = require('logger-sharelatex') module.exports = ProjectOutputFileAgent = { _prepare(project_id, linkedFileData, user_id, callback) { if (callback == null) { callback = function(err, linkedFileData) {} } return this._checkAuth( project_id, linkedFileData, user_id, (err, allowed) => { if (err != null) { return callback(err) } if (!allowed) { return callback(new AccessDeniedError()) } if (!this._validate(linkedFileData)) { return callback(new BadDataError()) } return callback(null, linkedFileData) } ) }, createLinkedFile( project_id, linkedFileData, name, parent_folder_id, user_id, callback ) { if (!this._canCreate(linkedFileData)) { return callback(new AccessDeniedError()) } linkedFileData = this._sanitizeData(linkedFileData) return this._prepare( project_id, linkedFileData, user_id, (err, linkedFileData) => { if (err != null) { return callback(err) } return this._getFileStream( linkedFileData, user_id, (err, readStream) => { if (err != null) { return callback(err) } readStream.on('error', callback) return readStream.on('response', response => { if (response.statusCode >= 200 && response.statusCode < 300) { readStream.resume() return LinkedFilesHandler.importFromStream( project_id, readStream, linkedFileData, name, parent_folder_id, user_id, function(err, file) { if (err != null) { return callback(err) } return callback(null, file._id) } ) // Created } else { err = new OutputFileFetchFailedError( `Output file fetch failed: ${linkedFileData.build_id}, ${linkedFileData.source_output_file_path}` ) err.statusCode = response.statusCode return callback(err) } }) } ) } ) }, refreshLinkedFile( project_id, linkedFileData, name, parent_folder_id, user_id, callback ) { return this._prepare( project_id, linkedFileData, user_id, (err, linkedFileData) => { if (err != null) { return callback(err) } return this._compileAndGetFileStream( linkedFileData, user_id, (err, readStream, new_build_id) => { if (err != null) { return callback(err) } readStream.on('error', callback) return readStream.on('response', response => { if (response.statusCode >= 200 && response.statusCode < 300) { readStream.resume() linkedFileData.build_id = new_build_id return LinkedFilesHandler.importFromStream( project_id, readStream, linkedFileData, name, parent_folder_id, user_id, function(err, file) { if (err != null) { return callback(err) } return callback(null, file._id) } ) // Created } else { err = new OutputFileFetchFailedError( `Output file fetch failed: ${linkedFileData.build_id}, ${linkedFileData.source_output_file_path}` ) err.statusCode = response.statusCode return callback(err) } }) } ) } ) }, _sanitizeData(data) { return { provider: data.provider, source_project_id: data.source_project_id, source_output_file_path: data.source_output_file_path, build_id: data.build_id } }, _canCreate: ProjectFileAgent._canCreate, _getSourceProject: LinkedFilesHandler.getSourceProject, _validate(data) { if (data.v1_source_doc_id != null) { return ( data.v1_source_doc_id != null && data.source_output_file_path != null ) } else { return ( data.source_project_id != null && data.source_output_file_path != null && data.build_id != null ) } }, _checkAuth(project_id, data, current_user_id, callback) { if (callback == null) { callback = function(err, allowed) {} } callback = _.once(callback) if (!this._validate(data)) { return callback(new BadDataError()) } return this._getSourceProject(data, function(err, project) { if (err != null) { return callback(err) } return AuthorizationManager.canUserReadProject( current_user_id, project._id, null, function(err, canRead) { if (err != null) { return callback(err) } return callback(null, canRead) } ) }) }, _getFileStream(linkedFileData, user_id, callback) { if (callback == null) { callback = function(err, fileStream) {} } callback = _.once(callback) const { source_output_file_path, build_id } = linkedFileData return this._getSourceProject(linkedFileData, function(err, project) { if (err != null) { return callback(err) } const source_project_id = project._id return ClsiManager.getOutputFileStream( source_project_id, user_id, build_id, source_output_file_path, function(err, readStream) { if (err != null) { return callback(err) } readStream.pause() return callback(null, readStream) } ) }) }, _compileAndGetFileStream(linkedFileData, user_id, callback) { if (callback == null) { callback = function(err, stream, build_id) {} } callback = _.once(callback) const { source_output_file_path } = linkedFileData return this._getSourceProject(linkedFileData, function(err, project) { if (err != null) { return callback(err) } const source_project_id = project._id return CompileManager.compile(source_project_id, user_id, {}, function( err, status, outputFiles ) { if (err != null) { return callback(err) } if (status !== 'success') { return callback(new OutputFileFetchFailedError()) } const outputFile = _.find( outputFiles, o => o.path === source_output_file_path ) if (outputFile == null) { return callback(new OutputFileFetchFailedError()) } const build_id = outputFile.build return ClsiManager.getOutputFileStream( source_project_id, user_id, build_id, source_output_file_path, function(err, readStream) { if (err != null) { return callback(err) } readStream.pause() return callback(null, readStream, build_id) } ) }) }) } }