MLE: Force PNG

This commit is contained in:
thororen1234 2025-09-20 13:29:36 -04:00
parent 9621aa2224
commit bdff0818e1
No known key found for this signature in database
5 changed files with 27 additions and 162 deletions

View file

@ -10,11 +10,9 @@ import path from "node:path";
import { DATA_DIR } from "@main/utils/constants";
import { dialog, IpcMainInvokeEvent, shell } from "electron";
import { getSettings, saveSettings } from "./settings";
export * from "./updater";
import { LoggedAttachment } from "../types";
import { LOGS_DATA_FILENAME } from "../utils/constants";
import { getSettings, saveSettings } from "./settings";
import { ensureDirectoryExists, getAttachmentIdFromFilename, sleep } from "./utils";
export { getSettings };
@ -72,11 +70,12 @@ export async function writeImageNative(_event: IpcMainInvokeEvent, filename: str
// returns the file name
// ../../someMalicousPath.png -> someMalicousPath
const attachmentId = getAttachmentIdFromFilename(filename);
const safeName = `${attachmentId}.png`;
const existingImage = nativeSavedImages.get(attachmentId);
if (existingImage) return;
const imagePath = path.join(imageDir, filename);
const imagePath = path.join(imageDir, safeName);
await ensureDirectoryExists(imageDir);
await writeFile(imagePath, content);
@ -145,23 +144,23 @@ export async function chooseFile(_event: IpcMainInvokeEvent, title: string, filt
// doing it in native because you can only fetch images from the renderer
// other types of files will cause cors issues
export async function downloadAttachment(_event: IpcMainInvokeEvent, attachemnt: LoggedAttachment, attempts = 0, useOldUrl = false): Promise<{ error: string | null; path: string | null; }> {
export async function downloadAttachment(_event: IpcMainInvokeEvent, attachment: LoggedAttachment, attempts = 0, useOldUrl = false): Promise<{ error: string | null; path: string | null; }> {
try {
if (!attachemnt?.url || !attachemnt.oldUrl || !attachemnt?.id || !attachemnt?.fileExtension)
if (!attachment?.url || !attachment.oldUrl || !attachment?.id || !attachment?.fileExtension)
return { error: "Invalid Attachment", path: null };
if (attachemnt.id.match(/[\\/.]/)) {
if (attachment.id.match(/[\\/.]/)) {
return { error: "Invalid Attachment ID", path: null };
}
const existingImage = nativeSavedImages.get(attachemnt.id);
const existingImage = nativeSavedImages.get(attachment.id);
if (existingImage)
return {
error: null,
path: existingImage
};
const res = await fetch(useOldUrl ? attachemnt.oldUrl : attachemnt.url);
const res = await fetch(useOldUrl ? attachment.oldUrl : attachment.url);
if (res.status !== 200) {
if (res.status === 404 || res.status === 403 || res.status === 415)
@ -170,23 +169,23 @@ export async function downloadAttachment(_event: IpcMainInvokeEvent, attachemnt:
attempts++;
if (attempts > 3) {
return {
error: `Failed to get attachment ${attachemnt.id} for caching. too many attempts, error code ${res.status}`,
error: `Failed to get attachment ${attachment.id} for caching. too many attempts, error code ${res.status}`,
path: null,
};
}
await sleep(1000);
return downloadAttachment(_event, attachemnt, attempts, useOldUrl);
return downloadAttachment(_event, attachment, attempts, useOldUrl);
}
const ab = await res.arrayBuffer();
const imageCacheDir = await getImageCacheDir();
await ensureDirectoryExists(imageCacheDir);
const finalPath = path.join(imageCacheDir, `${attachemnt.id}${attachemnt.fileExtension}`);
const finalPath = path.join(imageCacheDir, `${attachment.id}.png`);
await writeFile(finalPath, Buffer.from(ab));
nativeSavedImages.set(attachemnt.id, finalPath);
nativeSavedImages.set(attachment.id, finalPath);
return {
error: null,

View file

@ -1,134 +0,0 @@
/*
* Vencord, a Discord client mod
* Copyright (c) 2024 Vendicated and contributors
* SPDX-License-Identifier: GPL-3.0-or-later
*/
import { execFile as cpExecFile, ExecFileOptions } from "node:child_process";
import { readdir } from "fs/promises";
import { join } from "path";
import { promisify } from "util";
import type { GitResult } from "../types";
import { memoize } from "../utils/memoize";
const execFile = promisify(cpExecFile);
const isFlatpak = process.platform === "linux" && Boolean(process.env.FLATPAK_ID?.includes("discordapp") || process.env.FLATPAK_ID?.includes("Discord"));
if (process.platform === "darwin") process.env.PATH = `/usr/local/bin:${process.env.PATH}`;
const VENCORD_USER_PLUGIN_DIR = join(__dirname, "..", "src", "userplugins");
const getCwd = memoize(async () => {
const dirs = await readdir(VENCORD_USER_PLUGIN_DIR, { withFileTypes: true });
for (const dir of dirs) {
if (!dir.isDirectory()) continue;
const pluginDir = join(VENCORD_USER_PLUGIN_DIR, dir.name);
const files = await readdir(pluginDir);
if (files.includes("LoggedMessageManager.ts")) return join(VENCORD_USER_PLUGIN_DIR, dir.name);
}
return;
});
async function git(...args: string[]): Promise<GitResult> {
const opts: ExecFileOptions = { cwd: await getCwd(), shell: true };
try {
let result;
if (isFlatpak) {
result = await execFile("flatpak-spawn", ["--host", "git", ...args], opts);
} else {
result = await execFile("git", args, opts);
}
return { value: result.stdout.trim(), stderr: result.stderr, ok: true };
} catch (error: any) {
return {
ok: false,
cmd: error.cmd as string,
message: error.stderr as string,
error
};
}
}
export async function update() {
return await git("pull");
}
export async function getCommitHash() {
return await git("rev-parse", "HEAD");
}
export interface GitInfo {
repo: string;
gitHash: string;
}
export async function getRepoInfo(): Promise<GitResult> {
const res = await git("remote", "get-url", "origin");
if (!res.ok) {
return res;
}
const gitHash = await getCommitHash();
if (!gitHash.ok) {
return gitHash;
}
return {
ok: true,
value: {
repo: res.value
.replace(/git@(.+):/, "https://$1/")
.replace(/\.git$/, ""),
gitHash: gitHash.value
}
};
}
export interface Commit {
hash: string;
longHash: string;
message: string;
author: string;
}
export async function getNewCommits(): Promise<GitResult> {
const branch = await git("branch", "--show-current");
if (!branch.ok) {
return branch;
}
const logFormat = "%H;%an;%s";
const branchRange = `HEAD..origin/${branch.value}`;
try {
await git("fetch");
const logOutput = await git("log", `--format="${logFormat}"`, branchRange);
if (!logOutput.ok) {
return logOutput;
}
if (logOutput.value.trim() === "") {
return { ok: true, value: [] };
}
const commitLines = logOutput.value.trim().split("\n");
const commits: Commit[] = commitLines.map(line => {
const [hash, author, ...rest] = line.split(";");
return { longHash: hash, hash: hash.slice(0, 7), author, message: rest.join(";") } satisfies Commit;
});
return { ok: true, value: commits };
} catch (error: any) {
return { ok: false, cmd: error.cmd, message: error.message, error };
}
}

View file

@ -25,4 +25,8 @@ export function getAttachmentIdFromFilename(filename: string) {
return path.parse(filename).name;
}
export function getAttachmentExtFromFilename(filename: string) {
return path.parse(filename).ext;
}
export const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));

View file

@ -158,10 +158,6 @@ export function getNative(): PluginNative<typeof import("../native")> {
messageLoggerEnhancedUniqueIdThingyIdkMan: async () => { },
showItemInFolder: async () => { },
writeImageNative: async () => { },
getCommitHash: async () => ({ ok: true, value: "" }),
getRepoInfo: async () => ({ ok: true, value: { repo: "", gitHash: "" } }),
getNewCommits: async () => ({ ok: true, value: [] }),
update: async () => ({ ok: true, value: "" }),
chooseFile: async () => "",
downloadAttachment: async () => ({ error: "web", path: null }),
} satisfies PluginNative<typeof import("../native")>;

View file

@ -60,12 +60,12 @@ export async function getImage(attachmentId: string, fileExt?: string | null): P
return await Native.getImageNative(attachmentId);
}
export async function downloadAttachment(attachemnt: LoggedAttachment): Promise<string | undefined> {
export async function downloadAttachment(attachment: LoggedAttachment): Promise<string | undefined> {
if (IS_WEB) {
return await downloadAttachmentWeb(attachemnt);
return await downloadAttachmentWeb(attachment);
}
const { path, error } = await Native.downloadAttachment(attachemnt);
const { path, error } = await Native.downloadAttachment(attachment);
if (error || !path) {
Flogger.error("Failed to download attachment", error, path);
@ -87,31 +87,31 @@ export async function deleteImage(attachmentId: string): Promise<void> {
}
async function downloadAttachmentWeb(attachemnt: LoggedAttachment, attempts = 0) {
if (!attachemnt?.url || !attachemnt?.id || !attachemnt?.fileExtension) {
Flogger.error("Invalid attachment", attachemnt);
async function downloadAttachmentWeb(attachment: LoggedAttachment, attempts = 0) {
if (!attachment?.url || !attachment?.id || !attachment?.fileExtension) {
Flogger.error("Invalid attachment", attachment);
return;
}
const res = await fetch(attachemnt.url);
const res = await fetch(attachment.url);
if (res.status !== 200) {
if (res.status === 404 || res.status === 403) return;
attempts++;
if (attempts > 3) {
Flogger.warn(`Failed to get attachment ${attachemnt.id} for caching, error code ${res.status}`);
Flogger.warn(`Failed to get attachment ${attachment.id} for caching, error code ${res.status}`);
return;
}
await sleep(1000);
return downloadAttachmentWeb(attachemnt, attempts);
return downloadAttachmentWeb(attachment, attempts);
}
const ab = await res.arrayBuffer();
const path = `${DEFAULT_IMAGE_CACHE_DIR}/${attachemnt.id}${attachemnt.fileExtension}`;
const path = `${DEFAULT_IMAGE_CACHE_DIR}/${attachment.id}${attachment.fileExtension}`;
// await writeImage(imageCacheDir, `${attachmentId}${fileExtension}`, new Uint8Array(ab));
await set(path, new Uint8Array(ab), ImageStore);
idbSavedImages.set(attachemnt.id, { attachmentId: attachemnt.id, path });
idbSavedImages.set(attachment.id, { attachmentId: attachment.id, path });
return path;
}