2024-04-17 14:29:47 -04:00
|
|
|
/*
|
|
|
|
|
* Vencord, a Discord client mod
|
|
|
|
|
* Copyright (c) 2023 Vendicated and contributors
|
|
|
|
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
import { readdir, readFile, unlink, writeFile } from "node:fs/promises";
|
|
|
|
|
import path from "node:path";
|
|
|
|
|
|
2024-11-18 22:15:50 -05:00
|
|
|
import { Queue } from "@utils/Queue";
|
2024-04-17 14:29:47 -04:00
|
|
|
import { dialog, IpcMainInvokeEvent, shell } from "electron";
|
|
|
|
|
|
2024-11-18 22:15:50 -05:00
|
|
|
import { DATA_DIR } from "../../../main/utils/constants";
|
2024-04-17 14:29:47 -04:00
|
|
|
import { getSettings, saveSettings } from "./settings";
|
2024-11-18 22:15:50 -05:00
|
|
|
import { ensureDirectoryExists, getAttachmentIdFromFilename } from "./utils";
|
2024-04-17 14:29:47 -04:00
|
|
|
|
|
|
|
|
export { getSettings };
|
|
|
|
|
|
|
|
|
|
// so we can filter the native helpers by this key
|
|
|
|
|
export function messageLoggerEnhancedUniqueIdThingyIdkMan() { }
|
|
|
|
|
|
|
|
|
|
// Map<attachmetId, path>()
|
|
|
|
|
const nativeSavedImages = new Map<string, string>();
|
|
|
|
|
export const getNativeSavedImages = () => nativeSavedImages;
|
|
|
|
|
|
|
|
|
|
let logsDir: string;
|
|
|
|
|
let imageCacheDir: string;
|
|
|
|
|
|
|
|
|
|
const getImageCacheDir = async () => imageCacheDir ?? await getDefaultNativeImageDir();
|
|
|
|
|
const getLogsDir = async () => logsDir ?? await getDefaultNativeDataDir();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export async function initDirs() {
|
|
|
|
|
const { logsDir: ld, imageCacheDir: icd } = await getSettings();
|
|
|
|
|
|
|
|
|
|
logsDir = ld || await getDefaultNativeDataDir();
|
|
|
|
|
imageCacheDir = icd || await getDefaultNativeImageDir();
|
|
|
|
|
}
|
|
|
|
|
initDirs();
|
|
|
|
|
|
|
|
|
|
export async function init(_event: IpcMainInvokeEvent) {
|
|
|
|
|
const imageDir = await getImageCacheDir();
|
|
|
|
|
|
|
|
|
|
await ensureDirectoryExists(imageDir);
|
|
|
|
|
const files = await readdir(imageDir);
|
|
|
|
|
for (const filename of files) {
|
|
|
|
|
const attachmentId = getAttachmentIdFromFilename(filename);
|
|
|
|
|
nativeSavedImages.set(attachmentId, path.join(imageDir, filename));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function getImageNative(_event: IpcMainInvokeEvent, attachmentId: string): Promise<Uint8Array | Buffer | null> {
|
|
|
|
|
const imagePath = nativeSavedImages.get(attachmentId);
|
|
|
|
|
if (!imagePath) return null;
|
2024-11-18 22:15:50 -05:00
|
|
|
return await readFile(imagePath);
|
2024-04-17 14:29:47 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function writeImageNative(_event: IpcMainInvokeEvent, filename: string, content: Uint8Array) {
|
|
|
|
|
if (!filename || !content) return;
|
|
|
|
|
const imageDir = await getImageCacheDir();
|
|
|
|
|
|
|
|
|
|
// returns the file name
|
|
|
|
|
// ../../someMalicousPath.png -> someMalicousPath
|
|
|
|
|
const attachmentId = getAttachmentIdFromFilename(filename);
|
|
|
|
|
|
|
|
|
|
const existingImage = nativeSavedImages.get(attachmentId);
|
|
|
|
|
if (existingImage) return;
|
|
|
|
|
|
|
|
|
|
const imagePath = path.join(imageDir, filename);
|
|
|
|
|
await ensureDirectoryExists(imageDir);
|
|
|
|
|
await writeFile(imagePath, content);
|
|
|
|
|
|
|
|
|
|
nativeSavedImages.set(attachmentId, imagePath);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function deleteFileNative(_event: IpcMainInvokeEvent, attachmentId: string) {
|
|
|
|
|
const imagePath = nativeSavedImages.get(attachmentId);
|
|
|
|
|
if (!imagePath) return;
|
|
|
|
|
|
|
|
|
|
await unlink(imagePath);
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-18 22:15:50 -05:00
|
|
|
const LOGS_DATA_FILENAME = "message-logger-logs.json";
|
|
|
|
|
const dataWriteQueue = new Queue();
|
|
|
|
|
|
|
|
|
|
export async function getLogsFromFs(_event: IpcMainInvokeEvent) {
|
|
|
|
|
const logsDir = await getLogsDir();
|
|
|
|
|
|
|
|
|
|
await ensureDirectoryExists(logsDir);
|
|
|
|
|
try {
|
|
|
|
|
return JSON.parse(await readFile(path.join(logsDir, LOGS_DATA_FILENAME), "utf-8"));
|
|
|
|
|
} catch { }
|
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
}
|
2024-04-17 14:29:47 -04:00
|
|
|
|
|
|
|
|
export async function writeLogs(_event: IpcMainInvokeEvent, contents: string) {
|
|
|
|
|
const logsDir = await getLogsDir();
|
|
|
|
|
|
2024-11-18 22:15:50 -05:00
|
|
|
dataWriteQueue.push(() => writeFile(path.join(logsDir, LOGS_DATA_FILENAME), contents));
|
2024-04-17 14:29:47 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export async function getDefaultNativeImageDir(): Promise<string> {
|
|
|
|
|
return path.join(await getDefaultNativeDataDir(), "savedImages");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function getDefaultNativeDataDir(): Promise<string> {
|
|
|
|
|
return path.join(DATA_DIR, "MessageLoggerData");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function chooseDir(event: IpcMainInvokeEvent, logKey: "logsDir" | "imageCacheDir") {
|
|
|
|
|
const settings = await getSettings();
|
|
|
|
|
const defaultPath = settings[logKey] || await getDefaultNativeDataDir();
|
|
|
|
|
|
|
|
|
|
const res = await dialog.showOpenDialog({ properties: ["openDirectory"], defaultPath: defaultPath });
|
|
|
|
|
const dir = res.filePaths[0];
|
|
|
|
|
|
|
|
|
|
if (!dir) throw Error("Invalid Directory");
|
|
|
|
|
|
|
|
|
|
settings[logKey] = dir;
|
|
|
|
|
|
|
|
|
|
await saveSettings(settings);
|
|
|
|
|
|
|
|
|
|
switch (logKey) {
|
|
|
|
|
case "logsDir": logsDir = dir; break;
|
|
|
|
|
case "imageCacheDir": imageCacheDir = dir; break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (logKey === "imageCacheDir")
|
|
|
|
|
await init(event);
|
|
|
|
|
|
|
|
|
|
return dir;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function showItemInFolder(_event: IpcMainInvokeEvent, filePath: string) {
|
|
|
|
|
shell.showItemInFolder(filePath);
|
|
|
|
|
}
|