From 27af62f38d2f0a99af5c34963d27197467fb0141 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Fri, 10 May 2024 21:56:29 -0300 Subject: manual tempdir creation & handling This is mostly for compatibility with devices where the home directory isn't on the same device as the system temporary directory, so locallink and other symlink-based operations get trolled (fail!). This doesn't address the more general issue of e.g. playing music off of an external drive probably fails(!!) - but in those cases locallink isn't appropriate anyway, so they're outta scope of this commit. --- tempdir.js | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 tempdir.js (limited to 'tempdir.js') diff --git a/tempdir.js b/tempdir.js new file mode 100644 index 0000000..9264ffd --- /dev/null +++ b/tempdir.js @@ -0,0 +1,86 @@ +import {mkdirSync, readdirSync, statSync} from 'node:fs' +import * as os from 'node:os' +import * as path from 'node:path' + +import {nanoid} from 'nanoid' +import {rimrafSync} from 'rimraf' + +// Invariably obliterate contents of the rootDirectory upon +// mtui startup if their mtime is older than this duration +// before the current date. +const ancient = 7 * 24 * 60 * 60 * 1000 + +const ourTemporaryDirectories = [] + +const rootDirectory = path.join(os.homedir(), '.mtui', 'tmp') + +function obliterateTemporaryDirectory(tempdir) { + const rel = path.relative(rootDirectory, tempdir) + if (rel.startsWith('/') || rel.startsWith('.')) { + console.trace() + console.error(`Ostensible tempdir located here:`) + console.error(tempdir) + console.error(`Doesn't appear to be located in tempdir root:`) + console.error(rootDirectory) + console.error(`This is a programming error, and possibly dangerous.`) + console.error(`So, exiting now. This should be investigated.`) + process.exit(1) + } + + rimrafSync(tempdir) +} + +function cleanupAncient() { + const fsOp = (fn, ...args) => { + try { + return fn(...args) + } catch (error) { + console.error(error) + console.error(`There was an error preparing the temporary file directory.`) + console.error(`You may be able to resolve this by deleting or moving away`) + console.error(`this path:`) + console.error(rootDirectory) + process.exit(1) + } + } + + fsOp(() => + mkdirSync(rootDirectory, {recursive: true})) + + const tempdirs = + (fsOp(readdirSync, rootDirectory) + .map(dir => path.join(rootDirectory, dir))) + + let first = true + for (const tempdir of tempdirs) { + const stats = fsOp(statSync, tempdir) + + if (Date.now() - stats.mtimeMs > ancient) { + if (first) { + console.log(`One or more tempdirs haven't been modified in a while, removing:`) + first = false + } + console.log(tempdir) + fsOp(obliterateTemporaryDirectory, tempdir) + } + } +} + +// This has to be a sync function, since it'll run on +// the process' 'exit' event. +function cleanupOurs() { + for (const tempdir of ourTemporaryDirectories) { + obliterateTemporaryDirectory(tempdir) + } +} + +cleanupAncient() +process.on('exit', cleanupOurs) + +export default function temporaryDirectory() { + const name = nanoid() + const dir = path.join(rootDirectory, name) + ourTemporaryDirectories.push(dir) + mkdirSync(dir) + return dir +} -- cgit 1.3.0-6-gf8a5