Browse Source

Fix file uploading

pull/46/head
coomdev 2 years ago
parent
commit
39d83ec371
  1. BIN
      PEE-chrome.crx
  2. 2
      README.md
  3. 2
      build-chrome.js
  4. 2
      build-ff.js
  5. 2
      chrome/manifest.json
  6. 2
      chrome_update.xml
  7. 2
      firefox/manifest.json
  8. 2
      firefox_update.json
  9. BIN
      pngextraembedder-0.210-an+fx.xpi
  10. BIN
      pngextraembedder-0.211-an+fx.xpi
  11. 5
      src/Components/PostOptions.svelte
  12. 34
      src/background.ts
  13. 26
      src/main.ts
  14. 43
      src/platform.ts
  15. 36
      src/utils.ts
  16. 6
      update.xml

BIN
PEE-chrome.crx

Binary file not shown.

2
README.md

@ -23,7 +23,7 @@ Note: 4chanX isn't a hard requirement, just recommended because it's overall a n
## The newer way (WIP)
- [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
============

2
build-chrome.js

@ -133,7 +133,7 @@ const manif = {
define: {
global: 'window',
execution_mode: '"chrome_api"',
isBackground: 'false',
isBackground: 'true',
BUILD_VERSION: JSON.stringify([0, rev])
},
inject: ['./esbuild.inject.js'],

2
build-ff.js

@ -132,7 +132,7 @@ const manif = {
define: {
global: 'window',
execution_mode: '"ff_api"',
isBackground: 'false',
isBackground: 'true',
BUILD_VERSION: JSON.stringify([0, rev])
},
inject: ['./esbuild.inject.js'],

2
chrome/manifest.json

@ -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",
"name": "PngExtraEmbedder",
"description": "Discover embedded files on 4chan and archives!",
"version": "0.210",
"version": "0.211",
"icons": {
"64": "1449696017588.png"
},

2
chrome_update.xml

@ -1,6 +1,6 @@
<?xml version='1.0' encoding='UTF-8'?>
<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>
<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>
</gupdate>

2
firefox/manifest.json

@ -7,7 +7,7 @@
},
"name": "PngExtraEmbedder",
"description": "Discover embedded files on 4chan and archives!",
"version": "0.210",
"version": "0.211",
"icons": {
"64": "1449696017588.png"
},

2
firefox_update.json

@ -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"}]}}}

BIN
pngextraembedder-0.210-an+fx.xpi

Binary file not shown.

BIN
pngextraembedder-0.211-an+fx.xpi

Binary file not shown.

5
src/Components/PostOptions.svelte

@ -32,9 +32,10 @@
}
// This is an event to signal a change in the container file
let inhibit = false;
document.addEventListener("PEEFile", async (e) => {
let file = (e as any).detail as File;
if (currentEmbed?.file != file) {
if (currentEmbed?.file != file && !inhibit) {
original = file;
if ($settings.auto_embed && $appState.client) {
const tags = $settings.auto_tags
@ -49,6 +50,8 @@
const nlinks = await uploadFiles(files);
links = [...links, ...nlinks];
}
inhibit = true;
setTimeout(() => inhibit = false, 500); // hack around 4chan(X)(?) inconsistent getFile
embedContent(e);
}
});

34
src/background.ts

@ -102,6 +102,38 @@ obj.webRequest.onBeforeRequest.addListener((details) => {
}, 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 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??
input = 'https:' + input;
if (init?.body && execution_mode == "chrome_api")
init.body = await deserialize(init.body);
const k = await fetch(input, init);
let headersStr = '';
const headerObj = {} as any;

26
src/main.ts

@ -422,18 +422,20 @@ const startup = async (is4chanX = true) => {
registerPlugin('quote', postQuote);
if (!is4chanX && location.host.startsWith('boards.4chan')) {
(async () => {
while (!('QR' in window))
await new Promise(_ => setTimeout(_, 250));
const qr = QR;
const show = qr.show.bind(qr);
qr.show = (...args: any[]) => {
show(...args);
document.dispatchEvent(new CustomEvent("QRDialogCreation", {
detail: document.getElementById('quickReply')
}));
};
})();
const QRObs = new MutationObserver(rec => {
rec.forEach(m => {
m.addedNodes.forEach(no => {
if ((no as HTMLElement).id != "quickReply") {
return;
}
document.dispatchEvent(new CustomEvent("QRDialogCreation", {
detail: no
}));
});
});
});
// only need immediate children of body
QRObs.observe(document.body, { childList: true });
document.addEventListener("QRGetFile", (e) => {
const qr = document.getElementById('qrFile') as HTMLInputElement | null;

43
src/platform.ts

@ -69,6 +69,42 @@ const extrBlob = async (url: string) => {
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) => {
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) => {
let gcontroller: ReadableStreamController<Uint8Array> | undefined;
let buffer: Uint8Array[] = [];

36
src/utils.ts

@ -63,7 +63,37 @@ const generateThumbnail = async (f: File): Promise<Buffer> => {
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) => {
if (execution_mode == "ff_api")
return buildPeeFileFF(f);
//const isMemeBrowser = navigator.userAgent.indexOf("Chrome") == -1;
let thumbnail = Buffer.alloc(0);
thumbnail = await generateThumbnail(f);
@ -85,7 +115,8 @@ export const buildPeeFile = async (f: File) => {
thumbnail.copy(ret, ptr);
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]);
};
@ -200,7 +231,8 @@ export const uploadFiles = async (injs: File[]) => {
let total = 0;
fireNotification('info', `Uploading ${injs.length} files...`);
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}`);
return ret;
}));

6
update.xml

@ -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…
Cancel
Save