OpenAsar/core/src/app/discord_native/renderer/fileManager.js

167 lines
7.6 KiB
JavaScript

"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "basename", {
enumerable: true,
get: function () {
return _path.basename;
}
});
exports.cleanupTempFiles = cleanupTempFiles;
Object.defineProperty(exports, "dirname", {
enumerable: true,
get: function () {
return _path.dirname;
}
});
Object.defineProperty(exports, "extname", {
enumerable: true,
get: function () {
return _path.extname;
}
});
exports.getModuleDataPathSync = getModuleDataPathSync;
exports.getModulePath = getModulePath;
Object.defineProperty(exports, "join", {
enumerable: true,
get: function () {
return _path.join;
}
});
exports.openFiles = openFiles;
exports.readLogFiles = readLogFiles;
exports.readTimeSeriesLogFiles = readTimeSeriesLogFiles;
exports.saveWithDialog = saveWithDialog;
exports.showItemInFolder = showItemInFolder;
exports.showOpenDialog = showOpenDialog;
var _fs = _interopRequireDefault(require("fs"));
var _originalFs = _interopRequireDefault(require("original-fs"));
var _path = _interopRequireWildcard(require("path"));
var _util = _interopRequireDefault(require("util"));
var _DiscordIPC = require("../common/DiscordIPC");
var _fileutils = require("../common/fileutils");
var _paths = require("../common/paths");
var _files = require("./files");
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/* eslint-disable no-console */
// eslint-disable-line import/no-unresolved
// Reason for original-fs being import/no-unresolved: https://github.com/discord/discord/pull/74159#discussion_r893733771
const INVALID_FILENAME_CHAR_REGEX = /[^a-zA-Z0-9-_.]/g;
const promiseFs = {
readdir: _util.default.promisify(_originalFs.default.readdir),
open: _util.default.promisify(_originalFs.default.open),
fstat: _util.default.promisify(_originalFs.default.fstat),
stat: _util.default.promisify(_originalFs.default.stat),
unlink: _util.default.promisify(_originalFs.default.unlink),
read: _util.default.promisify(_originalFs.default.read),
close: _util.default.promisify(_originalFs.default.close)
};
async function saveWithDialog(fileContents, fileName) {
if (INVALID_FILENAME_CHAR_REGEX.test(fileName)) {
throw new Error('fileName has invalid characters');
}
const defaultPath = _path.default.join(await (0, _paths.getPath)('downloads'), fileName);
const results = await _DiscordIPC.DiscordIPC.renderer.invoke(_DiscordIPC.IPCEvents.FILE_MANAGER_SHOW_SAVE_DIALOG, {
defaultPath
});
if (results != null && results.filePath != null) {
_fs.default.writeFileSync(results.filePath, fileContents);
}
}
async function showOpenDialog({
filters,
properties
}) {
const results = await _DiscordIPC.DiscordIPC.renderer.invoke(_DiscordIPC.IPCEvents.FILE_MANAGER_SHOW_OPEN_DIALOG, {
filters,
properties
});
return results.filePaths;
}
async function readLogFiles(maxSize) {
// MAX_DEBUG_LOG_FILES may need to be increased as more files are added.
const modulePath = await getModulePath();
const voicePath = _path.default.join(modulePath, 'discord_voice');
const hookPath = _path.default.join(modulePath, 'discord_hook');
const utilsPath = _path.default.join(modulePath, 'discord_utils');
const filesToUpload = [_path.default.join(voicePath, 'discord-webrtc_0'), _path.default.join(voicePath, 'discord-webrtc_1'), _path.default.join(voicePath, 'discord-last-webrtc_0'), _path.default.join(voicePath, 'discord-last-webrtc_1'), _path.default.join(voicePath, 'audio_state.json'), _path.default.join(hookPath, 'hook.log'), _path.default.join(utilsPath, 'live_minidump.dmp')];
const crashFiles = await (0, _paths.getCrashFiles)();
if (crashFiles.length > 0) {
filesToUpload.push(crashFiles[0]);
}
return (0, _fileutils.readFulfilledFiles)(filesToUpload, maxSize, false);
}
async function readTimeSeriesLogFiles(maxSize, blindChannelId) {
if (blindChannelId == null) {
console.error('readTimeSeriesLogFiles: blindChannelId missing.');
return [];
}
const modulePath = await getModulePath();
const voicePath = _path.default.join(modulePath, 'discord_voice');
// Example filename: "channel.17812072731293278934.16605628624321906260.tsi"
const filter = new RegExp(`^channel\\.${blindChannelId}\\.\\d+\\.(?:tsi|tsd)$`, 'i');
const filenames = [];
for (const file of await promiseFs.readdir(voicePath)) {
if (filter.test(file)) {
filenames.push(_path.default.join(voicePath, file));
}
}
const allLogFiles = [...filenames];
const maxLogFiles = 10; // 10 is arbitrary but seems reasonable as each would be ~1mb.
if (filenames.length > maxLogFiles) {
console.warn(`readTimeSeriesLogFiles: Exceeded limit of ${maxLogFiles} files, had ${filenames.length}.`);
filenames.splice(maxLogFiles);
}
const readfiles = await (0, _fileutils.readFulfilledFiles)(filenames, maxSize, false);
// Delete the files after they've been read.
await Promise.all(allLogFiles.map(filename => promiseFs.unlink(filename)));
return readfiles;
}
async function cleanupTempFiles() {
// Since this runs on startup, handle and report all errors as cleanly as possible.
try {
const modulePath = await getModulePath();
const voicePath = _path.default.join(modulePath, 'discord_voice');
const deleteAgeTimeSpan = 1 * 24 * 60 * 60 * 1000; // 1 day.
const deleteAge = new Date(Date.now() - deleteAgeTimeSpan);
for (const filename of await promiseFs.readdir(voicePath)) {
if (!(0, _files.isTempFile)(filename)) {
continue;
}
const fullpath = _path.default.join(voicePath, filename);
const stat = await promiseFs.stat(fullpath);
if (!stat.isFile() || stat.mtime > deleteAge) {
continue;
}
console.log(`cleanupTempFiles: Deleting "${fullpath}" due to age.`);
try {
await promiseFs.unlink(fullpath);
} catch (e) {
console.error(`cleanupTempFiles: Failed to unlink ${fullpath}: ${e}`);
}
}
} catch (e) {
console.error(`cleanupTempFiles: Failed ${e}`);
}
}
function showItemInFolder(path) {
_DiscordIPC.DiscordIPC.renderer.invoke(_DiscordIPC.IPCEvents.FILE_MANAGER_SHOW_ITEM_IN_FOLDER, path);
return Promise.resolve();
}
async function openFiles(dialogOptions, maxSize) {
const filenames = await showOpenDialog(dialogOptions);
return (0, _fileutils.readFulfilledFiles)(filenames, maxSize, true);
}
function getModulePath() {
return _DiscordIPC.DiscordIPC.renderer.invoke(_DiscordIPC.IPCEvents.FILE_MANAGER_GET_MODULE_PATH);
}
function getModuleDataPathSync() {
return _DiscordIPC.DiscordIPC.renderer.sendSync(_DiscordIPC.IPCEvents.FILE_MANAGER_GET_MODULE_DATA_PATH_SYNC);
}