mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-11-14 22:23:42 +01:00
Merge pull request #18148 from overleaf/ar-add-output-zip-endpoint-to-clsi
[clsi] Add endpoints to get zip of output files GitOrigin-RevId: a1a935e8170ab5a8d40baa6d96f8e42fe22c2e8c
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
let OutputFileArchiveManager
|
||||
const archiver = require('archiver')
|
||||
const OutputCacheManager = require('./OutputCacheManager')
|
||||
const OutputFileFinder = require('./OutputFileFinder')
|
||||
const Settings = require('@overleaf/settings')
|
||||
const { open } = require('node:fs/promises')
|
||||
const path = require('node:path')
|
||||
const { NotFoundError } = require('./Errors')
|
||||
|
||||
function getContentDir(projectId, userId) {
|
||||
let subDir
|
||||
if (userId != null) {
|
||||
subDir = `${projectId}-${userId}`
|
||||
} else {
|
||||
subDir = projectId
|
||||
}
|
||||
return `${Settings.path.outputDir}/${subDir}/`
|
||||
}
|
||||
|
||||
module.exports = OutputFileArchiveManager = {
|
||||
async archiveFilesForBuild(projectId, userId, build, files = []) {
|
||||
const contentDir = getContentDir(projectId, userId)
|
||||
|
||||
const validFiles = await (files.length > 0
|
||||
? this._getRequestedOutputFiles(projectId, userId, build, files)
|
||||
: this._getAllOutputFiles(projectId, userId, build))
|
||||
|
||||
const archive = archiver('zip')
|
||||
|
||||
const missingFiles = files.filter(
|
||||
file => !validFiles.includes(path.basename(file))
|
||||
)
|
||||
|
||||
for (const file of validFiles) {
|
||||
try {
|
||||
const fileHandle = await open(
|
||||
`${contentDir}${OutputCacheManager.path(build, file)}`
|
||||
)
|
||||
const fileStream = fileHandle.createReadStream()
|
||||
archive.append(fileStream, { name: file })
|
||||
} catch (error) {
|
||||
missingFiles.push(file)
|
||||
}
|
||||
}
|
||||
|
||||
if (missingFiles.length > 0) {
|
||||
archive.append(missingFiles.join('\n'), {
|
||||
name: 'missing_files.txt',
|
||||
})
|
||||
}
|
||||
|
||||
await archive.finalize()
|
||||
|
||||
return archive
|
||||
},
|
||||
|
||||
async _getAllOutputFiles(projectId, userId, build) {
|
||||
const contentDir = getContentDir(projectId, userId)
|
||||
|
||||
try {
|
||||
const { outputFiles } = await OutputFileFinder.promises.findOutputFiles(
|
||||
[],
|
||||
`${contentDir}${OutputCacheManager.path(build, '.')}`
|
||||
)
|
||||
|
||||
return outputFiles.map(({ path }) => path)
|
||||
} catch (error) {
|
||||
if (
|
||||
error.code === 'ENOENT' ||
|
||||
error.code === 'ENOTDIR' ||
|
||||
error.code === 'EACCES'
|
||||
) {
|
||||
throw new NotFoundError('Output files not found')
|
||||
}
|
||||
throw error
|
||||
}
|
||||
},
|
||||
|
||||
async _getRequestedOutputFiles(projectId, userId, build, files) {
|
||||
const outputFiles = new Set(
|
||||
await OutputFileArchiveManager._getAllOutputFiles(
|
||||
projectId,
|
||||
userId,
|
||||
build
|
||||
)
|
||||
)
|
||||
|
||||
return files.filter(file => outputFiles.has(file))
|
||||
},
|
||||
}
|
||||
Reference in New Issue
Block a user