mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-05-23 17:19:37 +02:00
126 lines
3.5 KiB
JavaScript
126 lines
3.5 KiB
JavaScript
import logger from '@overleaf/logger'
|
|
import fs from 'node:fs'
|
|
import Async from 'async'
|
|
import FileHashManager from './FileHashManager.js'
|
|
import HistoryManager from '../History/HistoryManager.mjs'
|
|
import ProjectDetailsHandler from '../Project/ProjectDetailsHandler.mjs'
|
|
import { File } from '../../models/File.js'
|
|
import OError from '@overleaf/o-error'
|
|
import { promisifyAll } from '@overleaf/promise-utils'
|
|
import Modules from '../../infrastructure/Modules.js'
|
|
|
|
const FileStoreHandler = {
|
|
RETRY_ATTEMPTS: 3,
|
|
|
|
uploadFileFromDisk(projectId, fileArgs, fsPath, callback) {
|
|
// Look up the history id for the project if we don't have it already
|
|
ProjectDetailsHandler.getDetails(projectId, function (err, project) {
|
|
if (err) {
|
|
return callback(err)
|
|
}
|
|
const historyId = project.overleaf?.history?.id
|
|
if (!historyId) {
|
|
return callback(new OError('missing history id'))
|
|
}
|
|
FileStoreHandler.uploadFileFromDiskWithHistoryId(
|
|
projectId,
|
|
historyId,
|
|
fileArgs,
|
|
fsPath,
|
|
callback
|
|
)
|
|
})
|
|
},
|
|
|
|
_uploadToHistory(historyId, hash, size, fsPath, callback) {
|
|
Async.retry(
|
|
FileStoreHandler.RETRY_ATTEMPTS,
|
|
cb =>
|
|
HistoryManager.uploadBlobFromDisk(historyId, hash, size, fsPath, cb),
|
|
error => {
|
|
if (error) return callback(error, false)
|
|
callback(null, true)
|
|
}
|
|
)
|
|
},
|
|
|
|
uploadFileFromDiskWithHistoryId(
|
|
projectId,
|
|
historyId,
|
|
fileArgs,
|
|
fsPath,
|
|
callback
|
|
) {
|
|
fs.lstat(fsPath, function (err, stat) {
|
|
if (err) {
|
|
logger.warn({ err, projectId, fileArgs, fsPath }, 'error stating file')
|
|
callback(err)
|
|
}
|
|
if (!stat) {
|
|
logger.warn(
|
|
{ projectId, fileArgs, fsPath },
|
|
'stat is not available, can not check file from disk'
|
|
)
|
|
return callback(new Error('error getting stat, not available'))
|
|
}
|
|
if (!stat.isFile()) {
|
|
logger.debug(
|
|
{ projectId, fileArgs, fsPath },
|
|
'tried to upload symlink, not continuing'
|
|
)
|
|
return callback(new Error('can not upload symlink'))
|
|
}
|
|
const size = stat.size
|
|
Modules.hooks.fire(
|
|
'preUploadFile',
|
|
{ projectId, historyId, fileArgs, fsPath, size },
|
|
preUploadErr => {
|
|
if (preUploadErr) {
|
|
return callback(preUploadErr)
|
|
}
|
|
FileHashManager.computeHash(fsPath, function (err, hash) {
|
|
if (err) {
|
|
return callback(err)
|
|
}
|
|
FileStoreHandler._uploadToHistory(
|
|
historyId,
|
|
hash,
|
|
stat.size,
|
|
fsPath,
|
|
function (err) {
|
|
if (err) {
|
|
return callback(err)
|
|
}
|
|
const fileRef = new File({ ...fileArgs, hash })
|
|
Modules.hooks.fire(
|
|
'postUploadFile',
|
|
{
|
|
projectId,
|
|
fileRef,
|
|
size,
|
|
},
|
|
postUploadErr => {
|
|
if (postUploadErr) {
|
|
return callback(postUploadErr)
|
|
}
|
|
callback(err, fileRef, true, size)
|
|
}
|
|
)
|
|
}
|
|
)
|
|
})
|
|
}
|
|
)
|
|
})
|
|
},
|
|
}
|
|
|
|
FileStoreHandler.promises = promisifyAll(FileStoreHandler, {
|
|
multiResult: {
|
|
uploadFileFromDisk: ['fileRef', 'createdBlob', 'size'],
|
|
uploadFileFromDiskWithHistoryId: ['fileRef', 'createdBlob', 'size'],
|
|
},
|
|
})
|
|
|
|
export default FileStoreHandler
|