Can embed any file in a PNG/WebM/GIF/JPEG and upload it to a third-party host through 4chan
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

93 lines
2.5 KiB

import type { ImageProcessor, WorkerEmbeddedFile } from './processor.worker';
import { Buffer } from "buffer";
2 years ago
import thumbnail from "./assets/hasembed.png";
import { settings } from "./stores";
import { getHeaders, ifetch, Platform } from "./platform";
2 years ago
const sources = [
{ host: 'Catbox', prefix: 'files.catbox.moe/' },
{ host: 'Litter', prefix: 'litter.catbox.moe/' },
{ host: 'Zzzz', prefix: 'z.zz.fo/' }
2 years ago
];
export let csettings: Parameters<typeof settings['set']>[0];
settings.subscribe(b => {
csettings = b;
});
2 years ago
const getExt = (fn: string) => {
// const isDum = fn!.match(/^[a-z0-9]{6}\./i);
const isB64 = fn!.match(/^((?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=))?\.(gif|jpe?g|png|webm)/);
2 years ago
const isExt = fn!.match(/\[.*=(.*)\]/);
let ext;
let source: string | undefined;
try {
if (isB64) {
ext = atob(isB64[1]);
} else if (isExt) {
ext = decodeURIComponent(isExt[1]);
if (ext.startsWith('https://'))
ext = ext.slice('https://'.length);
for (const cs of sources)
if (ext.startsWith(cs.prefix)) {
source = cs.prefix;
ext = ext.slice(cs.prefix.length);
break;
}
}
} catch {
/**/
2 years ago
}
return { ext, source };
2 years ago
};
const extract = async (b: Buffer, fn?: string) => {
if (!csettings)
throw new Error("Settings uninit");
const { ext, source } = getExt(fn!);
2 years ago
let rsource: string;
for (const cs of sources) {
if (source && cs.prefix != source)
continue;
2 years ago
try {
await getHeaders('https://' + cs.prefix + ext);
rsource = 'https://' + cs.prefix + ext;
2 years ago
break;
} catch {
// 404
}
}
return [{
2 years ago
filename: ext,
data: csettings.hotlink ? rsource! : { url: rsource! },
thumbnail: Buffer.from(thumbnail)
} as WorkerEmbeddedFile];
2 years ago
};
const has_embed = async (b: Buffer, fn?: string) => {
const { ext, source } = getExt(fn!);
2 years ago
if (!ext)
return false;
for (const cs of sources) {
if (source && cs.prefix != source)
continue;
2 years ago
try {
const e = await getHeaders('https://' + cs.prefix + ext);
2 years ago
return true;
} catch {
// 404
}
}
2 years ago
return false;
};
export default {
skip: true,
extract,
has_embed,
match: fn => !!getExt(fn)
2 years ago
} as ImageProcessor;