mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
b4b369fea5
[clsi] replace fs-extra to avoid excess syscalls GitOrigin-RevId: cbc8ec01b8ac9fd973e86a6d763c8f599323db94
82 lines
2.3 KiB
JavaScript
82 lines
2.3 KiB
JavaScript
/* eslint-disable
|
|
no-return-assign,
|
|
*/
|
|
// TODO: This file was created by bulk-decaffeinate.
|
|
// Fix any style issues and re-enable lint.
|
|
/*
|
|
* decaffeinate suggestions:
|
|
* DS101: Remove unnecessary use of Array.from
|
|
* 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
|
|
*/
|
|
const UrlFetcher = require('./UrlFetcher')
|
|
const Settings = require('@overleaf/settings')
|
|
const fs = require('fs')
|
|
const Path = require('path')
|
|
const { callbackify } = require('util')
|
|
|
|
const PENDING_DOWNLOADS = new Map()
|
|
|
|
function getProjectDir(projectId) {
|
|
return Path.join(Settings.path.clsiCacheDir, projectId)
|
|
}
|
|
|
|
function getCachePath(projectId, url, lastModified) {
|
|
// The url is a filestore URL.
|
|
// It is sufficient to look at the path and mtime for uniqueness.
|
|
const mtime = (lastModified && lastModified.getTime()) || 0
|
|
const key = new URL(url).pathname.replace(/\//g, '-') + '-' + mtime
|
|
return Path.join(getProjectDir(projectId), key)
|
|
}
|
|
|
|
async function clearProject(projectId) {
|
|
await fs.promises.rm(getProjectDir(projectId), {
|
|
force: true,
|
|
recursive: true,
|
|
})
|
|
}
|
|
|
|
async function createProjectDir(projectId) {
|
|
await fs.promises.mkdir(getProjectDir(projectId), { recursive: true })
|
|
}
|
|
|
|
async function downloadUrlToFile(projectId, url, destPath, lastModified) {
|
|
const cachePath = getCachePath(projectId, url, lastModified)
|
|
try {
|
|
await fs.promises.copyFile(cachePath, destPath)
|
|
return
|
|
} catch (e) {
|
|
if (e.code !== 'ENOENT') {
|
|
throw e
|
|
}
|
|
}
|
|
await download(url, cachePath)
|
|
await fs.promises.copyFile(cachePath, destPath)
|
|
}
|
|
|
|
async function download(url, cachePath) {
|
|
let pending = PENDING_DOWNLOADS.get(cachePath)
|
|
if (pending) {
|
|
return pending
|
|
}
|
|
|
|
pending = UrlFetcher.promises.pipeUrlToFileWithRetry(url, cachePath)
|
|
PENDING_DOWNLOADS.set(cachePath, pending)
|
|
try {
|
|
await pending
|
|
} finally {
|
|
PENDING_DOWNLOADS.delete(cachePath)
|
|
}
|
|
}
|
|
|
|
module.exports = {
|
|
clearProject: callbackify(clearProject),
|
|
createProjectDir: callbackify(createProjectDir),
|
|
downloadUrlToFile: callbackify(downloadUrlToFile),
|
|
promises: {
|
|
clearProject,
|
|
createProjectDir,
|
|
downloadUrlToFile,
|
|
},
|
|
}
|