mirror of
https://git.coom.tech/fuckjannies/lolipiss.git
synced 2024-06-26 12:42:38 +00:00
Fix file uploading
This commit is contained in:
parent
56a39a7fbd
commit
39d83ec371
BIN
PEE-chrome.crx
BIN
PEE-chrome.crx
Binary file not shown.
|
@ -23,7 +23,7 @@ Note: 4chanX isn't a hard requirement, just recommended because it's overall a n
|
||||||
## The newer way (WIP)
|
## The newer way (WIP)
|
||||||
|
|
||||||
- [Install 4chanX (recommended)](https://www.4chan-x.net/builds/4chan-X.user.js)
|
- [Install 4chanX (recommended)](https://www.4chan-x.net/builds/4chan-X.user.js)
|
||||||
- Install the correct WebExtension for your Browser ([Firefox](https://git.coom.tech/coomdev/PEE/raw/branch/%E4%B8%AD%E5%87%BA%E3%81%97/pngextraembedder-0.210-an+fx.xpi) or [Chrome-based](https://git.coom.tech/coomdev/PEE/raw/branch/%E4%B8%AD%E5%87%BA%E3%81%97/PEE-chrome.crx))
|
- Install the correct WebExtension for your Browser ([Firefox](https://git.coom.tech/coomdev/PEE/raw/branch/%E4%B8%AD%E5%87%BA%E3%81%97/pngextraembedder-0.211-an+fx.xpi) or [Chrome-based](https://git.coom.tech/coomdev/PEE/raw/branch/%E4%B8%AD%E5%87%BA%E3%81%97/PEE-chrome.crx))
|
||||||
|
|
||||||
How to Build
|
How to Build
|
||||||
============
|
============
|
||||||
|
|
|
@ -133,7 +133,7 @@ const manif = {
|
||||||
define: {
|
define: {
|
||||||
global: 'window',
|
global: 'window',
|
||||||
execution_mode: '"chrome_api"',
|
execution_mode: '"chrome_api"',
|
||||||
isBackground: 'false',
|
isBackground: 'true',
|
||||||
BUILD_VERSION: JSON.stringify([0, rev])
|
BUILD_VERSION: JSON.stringify([0, rev])
|
||||||
},
|
},
|
||||||
inject: ['./esbuild.inject.js'],
|
inject: ['./esbuild.inject.js'],
|
||||||
|
|
|
@ -132,7 +132,7 @@ const manif = {
|
||||||
define: {
|
define: {
|
||||||
global: 'window',
|
global: 'window',
|
||||||
execution_mode: '"ff_api"',
|
execution_mode: '"ff_api"',
|
||||||
isBackground: 'false',
|
isBackground: 'true',
|
||||||
BUILD_VERSION: JSON.stringify([0, rev])
|
BUILD_VERSION: JSON.stringify([0, rev])
|
||||||
},
|
},
|
||||||
inject: ['./esbuild.inject.js'],
|
inject: ['./esbuild.inject.js'],
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"update_url": "https://git.coom.tech/fuckjannies/lolipiss/raw/branch/%E4%B8%AD%E5%87%BA%E3%81%97/chrome_update.xml",
|
"update_url": "https://git.coom.tech/fuckjannies/lolipiss/raw/branch/%E4%B8%AD%E5%87%BA%E3%81%97/chrome_update.xml",
|
||||||
"name": "PngExtraEmbedder",
|
"name": "PngExtraEmbedder",
|
||||||
"description": "Discover embedded files on 4chan and archives!",
|
"description": "Discover embedded files on 4chan and archives!",
|
||||||
"version": "0.210",
|
"version": "0.211",
|
||||||
"icons": {
|
"icons": {
|
||||||
"64": "1449696017588.png"
|
"64": "1449696017588.png"
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version='1.0' encoding='UTF-8'?>
|
<?xml version='1.0' encoding='UTF-8'?>
|
||||||
<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>
|
<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>
|
||||||
<app appid='ilffidhdekahjldemialkgahicnajchb'>
|
<app appid='ilffidhdekahjldemialkgahicnajchb'>
|
||||||
<updatecheck codebase='https://git.coom.tech/coomdev/PEE/raw/branch/%E4%B8%AD%E5%87%BA%E3%81%97/PEE-chrome.crx' version='0.210' prodversionmin='64.0.3242' />
|
<updatecheck codebase='https://git.coom.tech/coomdev/PEE/raw/branch/%E4%B8%AD%E5%87%BA%E3%81%97/PEE-chrome.crx' version='0.211' prodversionmin='64.0.3242' />
|
||||||
</app>
|
</app>
|
||||||
</gupdate>
|
</gupdate>
|
|
@ -7,7 +7,7 @@
|
||||||
},
|
},
|
||||||
"name": "PngExtraEmbedder",
|
"name": "PngExtraEmbedder",
|
||||||
"description": "Discover embedded files on 4chan and archives!",
|
"description": "Discover embedded files on 4chan and archives!",
|
||||||
"version": "0.210",
|
"version": "0.211",
|
||||||
"icons": {
|
"icons": {
|
||||||
"64": "1449696017588.png"
|
"64": "1449696017588.png"
|
||||||
},
|
},
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
{"addons":{"{34ac4994-07f2-44d2-8599-682516a6c6a6}":{"updates":[{"version":"0.210","update_link":"https://git.coom.tech/fuckjannies/lolipiss/raw/branch/%E4%B8%AD%E5%87%BA%E3%81%97/pee-firefox.zip"}]}}}
|
{"addons":{"{34ac4994-07f2-44d2-8599-682516a6c6a6}":{"updates":[{"version":"0.211","update_link":"https://git.coom.tech/fuckjannies/lolipiss/raw/branch/%E4%B8%AD%E5%87%BA%E3%81%97/pee-firefox.zip"}]}}}
|
Binary file not shown.
BIN
pngextraembedder-0.211-an+fx.xpi
Normal file
BIN
pngextraembedder-0.211-an+fx.xpi
Normal file
Binary file not shown.
|
@ -32,9 +32,10 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is an event to signal a change in the container file
|
// This is an event to signal a change in the container file
|
||||||
|
let inhibit = false;
|
||||||
document.addEventListener("PEEFile", async (e) => {
|
document.addEventListener("PEEFile", async (e) => {
|
||||||
let file = (e as any).detail as File;
|
let file = (e as any).detail as File;
|
||||||
if (currentEmbed?.file != file) {
|
if (currentEmbed?.file != file && !inhibit) {
|
||||||
original = file;
|
original = file;
|
||||||
if ($settings.auto_embed && $appState.client) {
|
if ($settings.auto_embed && $appState.client) {
|
||||||
const tags = $settings.auto_tags
|
const tags = $settings.auto_tags
|
||||||
|
@ -49,6 +50,8 @@
|
||||||
const nlinks = await uploadFiles(files);
|
const nlinks = await uploadFiles(files);
|
||||||
links = [...links, ...nlinks];
|
links = [...links, ...nlinks];
|
||||||
}
|
}
|
||||||
|
inhibit = true;
|
||||||
|
setTimeout(() => inhibit = false, 500); // hack around 4chan(X)(?) inconsistent getFile
|
||||||
embedContent(e);
|
embedContent(e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -102,6 +102,38 @@ obj.webRequest.onBeforeRequest.addListener((details) => {
|
||||||
}, filts, ['blocking']);
|
}, filts, ['blocking']);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
async function deserialize(src: any): Promise<any> {
|
||||||
|
switch (src.cls) {
|
||||||
|
case 'FormData': {
|
||||||
|
const ret = new FormData();
|
||||||
|
for (const [key, items] of src.value) {
|
||||||
|
for (const item of items) {
|
||||||
|
ret.append(key, await deserialize(item));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
case 'File': {
|
||||||
|
return new File([await (await fetch(src.value)).blob()], src.name, {
|
||||||
|
lastModified: src.lastModified,
|
||||||
|
type: src.type
|
||||||
|
});
|
||||||
|
}
|
||||||
|
case 'Blob': {
|
||||||
|
return new Blob([await (await fetch(src.value)).blob()], {
|
||||||
|
type: src.type
|
||||||
|
});
|
||||||
|
}
|
||||||
|
case 'Object': {
|
||||||
|
const ret = {} as any;
|
||||||
|
for (const prop in src.value) {
|
||||||
|
ret[prop] = await deserialize(src.value[prop]);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const pendingFetches = new Map<browser.runtime.Port, { [id in number]: { fetchFully: boolean } }>();
|
const pendingFetches = new Map<browser.runtime.Port, { [id in number]: { fetchFully: boolean } }>();
|
||||||
|
|
||||||
const bgCorsFetch = async (c: browser.runtime.Port, id: number, input: string, init?: RequestInit) => {
|
const bgCorsFetch = async (c: browser.runtime.Port, id: number, input: string, init?: RequestInit) => {
|
||||||
|
@ -113,6 +145,8 @@ const bgCorsFetch = async (c: browser.runtime.Port, id: number, input: string, i
|
||||||
|
|
||||||
if (input.startsWith('//')) // wtf fireshit??
|
if (input.startsWith('//')) // wtf fireshit??
|
||||||
input = 'https:' + input;
|
input = 'https:' + input;
|
||||||
|
if (init?.body && execution_mode == "chrome_api")
|
||||||
|
init.body = await deserialize(init.body);
|
||||||
const k = await fetch(input, init);
|
const k = await fetch(input, init);
|
||||||
let headersStr = '';
|
let headersStr = '';
|
||||||
const headerObj = {} as any;
|
const headerObj = {} as any;
|
||||||
|
|
22
src/main.ts
22
src/main.ts
|
@ -422,18 +422,20 @@ const startup = async (is4chanX = true) => {
|
||||||
registerPlugin('quote', postQuote);
|
registerPlugin('quote', postQuote);
|
||||||
|
|
||||||
if (!is4chanX && location.host.startsWith('boards.4chan')) {
|
if (!is4chanX && location.host.startsWith('boards.4chan')) {
|
||||||
(async () => {
|
const QRObs = new MutationObserver(rec => {
|
||||||
while (!('QR' in window))
|
rec.forEach(m => {
|
||||||
await new Promise(_ => setTimeout(_, 250));
|
m.addedNodes.forEach(no => {
|
||||||
const qr = QR;
|
if ((no as HTMLElement).id != "quickReply") {
|
||||||
const show = qr.show.bind(qr);
|
return;
|
||||||
qr.show = (...args: any[]) => {
|
}
|
||||||
show(...args);
|
|
||||||
document.dispatchEvent(new CustomEvent("QRDialogCreation", {
|
document.dispatchEvent(new CustomEvent("QRDialogCreation", {
|
||||||
detail: document.getElementById('quickReply')
|
detail: no
|
||||||
}));
|
}));
|
||||||
};
|
});
|
||||||
})();
|
});
|
||||||
|
});
|
||||||
|
// only need immediate children of body
|
||||||
|
QRObs.observe(document.body, { childList: true });
|
||||||
|
|
||||||
document.addEventListener("QRGetFile", (e) => {
|
document.addEventListener("QRGetFile", (e) => {
|
||||||
const qr = document.getElementById('qrFile') as HTMLInputElement | null;
|
const qr = document.getElementById('qrFile') as HTMLInputElement | null;
|
||||||
|
|
|
@ -69,6 +69,42 @@ const extrBlob = async (url: string) => {
|
||||||
return new Uint8Array(ret);
|
return new Uint8Array(ret);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
async function serialize(src: any): Promise<any> {
|
||||||
|
if (src instanceof FormData) {
|
||||||
|
const value = [];
|
||||||
|
for (const kv of src)
|
||||||
|
value.push([kv[0], await Promise.all(src.getAll(kv[0]).map(serialize))]);
|
||||||
|
return {
|
||||||
|
cls: 'FormData', value,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (src instanceof File) {
|
||||||
|
const { name, type, lastModified } = src;
|
||||||
|
const value = URL.createObjectURL(src);
|
||||||
|
return {
|
||||||
|
cls: 'File',
|
||||||
|
name, type, lastModified, value,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (src instanceof Blob) {
|
||||||
|
const { type } = src;
|
||||||
|
const value = URL.createObjectURL(src);
|
||||||
|
return {
|
||||||
|
cls: 'Blob', type, value,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (src === null || src === undefined || typeof src != "object")
|
||||||
|
return src;
|
||||||
|
const ret = {
|
||||||
|
cls: 'Object',
|
||||||
|
value: {}
|
||||||
|
} as any;
|
||||||
|
for (const prop in src) {
|
||||||
|
ret.value[prop] = await serialize(src[prop]);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
export const corsFetch = async (input: string, init?: RequestInit, lsn?: EventTarget) => {
|
export const corsFetch = async (input: string, init?: RequestInit, lsn?: EventTarget) => {
|
||||||
const id = gid++;
|
const id = gid++;
|
||||||
|
|
||||||
|
@ -82,6 +118,13 @@ export const corsFetch = async (input: string, init?: RequestInit, lsn?: EventTa
|
||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
|
if (init?.body) {
|
||||||
|
// Chrom* can't pass around FormData and File/Blobs between
|
||||||
|
// the content and bg scripts, so the data is passed through bloburls
|
||||||
|
if (execution_mode == "chrome_api")
|
||||||
|
init.body = await serialize(init.body);
|
||||||
|
}
|
||||||
|
|
||||||
const prom = new Promise<Awaited<ReturnType<typeof fetch>>>((_, rej) => {
|
const prom = new Promise<Awaited<ReturnType<typeof fetch>>>((_, rej) => {
|
||||||
let gcontroller: ReadableStreamController<Uint8Array> | undefined;
|
let gcontroller: ReadableStreamController<Uint8Array> | undefined;
|
||||||
let buffer: Uint8Array[] = [];
|
let buffer: Uint8Array[] = [];
|
||||||
|
|
36
src/utils.ts
36
src/utils.ts
|
@ -63,7 +63,37 @@ const generateThumbnail = async (f: File): Promise<Buffer> => {
|
||||||
return Buffer.from(await blob.arrayBuffer());
|
return Buffer.from(await blob.arrayBuffer());
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const buildPeeFileFF = async (f: File) => {
|
||||||
|
let thumbnail = new Uint8Array();
|
||||||
|
const te = new TextEncoder();
|
||||||
|
thumbnail = await generateThumbnail(f);
|
||||||
|
const namebuf = te.encode(f.name);
|
||||||
|
const ret = new Uint8Array(4 /* Magic */ +
|
||||||
|
1 /* Flags */ + namebuf.byteLength + 1 +
|
||||||
|
(thumbnail.byteLength != 0 ? (4 + thumbnail.byteLength) : 0) /* TSize + Thumbnail */ +
|
||||||
|
f.size /*Teh file*/);
|
||||||
|
const ret32 = new DataView(ret.buffer);
|
||||||
|
let ptr = 0;
|
||||||
|
ret.set(te.encode('PEE\0'), 0);
|
||||||
|
ptr += 4;
|
||||||
|
ret[ptr++] = 1 | ((+(thumbnail.length != 0)) << 2);
|
||||||
|
ret.set(namebuf, ptr);
|
||||||
|
ptr += namebuf.byteLength;
|
||||||
|
ret[ptr++] = 0;
|
||||||
|
if (thumbnail.length > 0) {
|
||||||
|
ret32.setUint32(ptr, thumbnail.byteLength, true);
|
||||||
|
ptr += 4;
|
||||||
|
ret.set(thumbnail, ptr);
|
||||||
|
ptr += thumbnail.byteLength;
|
||||||
|
}
|
||||||
|
const content = await f.arrayBuffer();
|
||||||
|
ret.set(new Uint8Array(content), ptr);
|
||||||
|
return new Blob([ret]);
|
||||||
|
};
|
||||||
|
|
||||||
export const buildPeeFile = async (f: File) => {
|
export const buildPeeFile = async (f: File) => {
|
||||||
|
if (execution_mode == "ff_api")
|
||||||
|
return buildPeeFileFF(f);
|
||||||
//const isMemeBrowser = navigator.userAgent.indexOf("Chrome") == -1;
|
//const isMemeBrowser = navigator.userAgent.indexOf("Chrome") == -1;
|
||||||
let thumbnail = Buffer.alloc(0);
|
let thumbnail = Buffer.alloc(0);
|
||||||
thumbnail = await generateThumbnail(f);
|
thumbnail = await generateThumbnail(f);
|
||||||
|
@ -85,7 +115,8 @@ export const buildPeeFile = async (f: File) => {
|
||||||
thumbnail.copy(ret, ptr);
|
thumbnail.copy(ret, ptr);
|
||||||
ptr += thumbnail.byteLength;
|
ptr += thumbnail.byteLength;
|
||||||
}
|
}
|
||||||
Buffer.from(await f.arrayBuffer()).copy(ret, ptr);
|
const content = await f.arrayBuffer();
|
||||||
|
Buffer.from(content).copy(ret, ptr);
|
||||||
return new Blob([ret]);
|
return new Blob([ret]);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -200,7 +231,8 @@ export const uploadFiles = async (injs: File[]) => {
|
||||||
let total = 0;
|
let total = 0;
|
||||||
fireNotification('info', `Uploading ${injs.length} files...`);
|
fireNotification('info', `Uploading ${injs.length} files...`);
|
||||||
return await Promise.all(injs.map(async inj => {
|
return await Promise.all(injs.map(async inj => {
|
||||||
const ret = await filehosts[csettings.fhost || 0].uploadFile(await buildPeeFile(inj));
|
const peefile = await buildPeeFile(inj);
|
||||||
|
const ret = await filehosts[csettings.fhost || 0].uploadFile(peefile);
|
||||||
fireNotification('info', `Uploaded files [${++total}/${injs.length}] ${ret}`);
|
fireNotification('info', `Uploaded files [${++total}/${injs.length}] ${ret}`);
|
||||||
return ret;
|
return ret;
|
||||||
}));
|
}));
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
<?xml version='1.0' encoding='UTF-8'?>
|
|
||||||
<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>
|
|
||||||
<app appid='ilffidhdekahjldemialkgahicnajchb'>
|
|
||||||
<updatecheck codebase='http://localhost:8000/myExtension.crx' version='0.208' prodversionmin='64.0.3242' />
|
|
||||||
</app>
|
|
||||||
</gupdate>
|
|
Loading…
Reference in New Issue
Block a user