| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 |
- 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
|