overleaf/services/clsi/app/js/UrlCache.js

82 lines
2.2 KiB
JavaScript
Raw Normal View History

/* eslint-disable
camelcase,
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 fse = require('fs-extra')
const Path = require('path')
const { callbackify } = require('util')
2014-02-12 17:27:43 +00:00
const PENDING_DOWNLOADS = new Map()
2014-02-12 17:27:43 +00:00
function getProjectDir(projectId) {
return Path.join(Settings.path.clsiCacheDir, projectId)
}
2014-02-12 17:27:43 +00:00
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)
}
2014-02-12 17:27:43 +00:00
async function clearProject(projectId) {
await fse.remove(getProjectDir(projectId))
}
2014-02-12 17:27:43 +00:00
async function createProjectDir(projectId) {
await fs.promises.mkdir(getProjectDir(projectId), { recursive: true })
}
2014-02-12 17:27:43 +00:00
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)
}
2014-02-12 17:27:43 +00:00
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)
}
}
2014-02-12 17:27:43 +00:00
module.exports = {
clearProject: callbackify(clearProject),
createProjectDir: callbackify(createProjectDir),
downloadUrlToFile: callbackify(downloadUrlToFile),
promises: {
clearProject,
createProjectDir,
downloadUrlToFile,
2021-07-13 11:04:48 +00:00
},
}