mirror of
https://github.com/osnr/TabFS.git
synced 2024-05-23 16:02:18 +02:00
base64 reads. start working on screenshot stuff.
This commit is contained in:
parent
506751b3d5
commit
22aaeaa9e1
24
README.md
24
README.md
|
@ -51,14 +51,17 @@ $ cat mnt/tabs/by-id/*/text > text.txt
|
||||||
|
|
||||||
## Setup
|
## Setup
|
||||||
|
|
||||||
|
**disclaimer**: security, functionality
|
||||||
|
|
||||||
First, install the browser extension.
|
First, install the browser extension.
|
||||||
|
|
||||||
Then, install the C filesystem.
|
Then, install the C filesystem.
|
||||||
|
|
||||||
### 1. Install the browser extension
|
### 1. Install the browser extension
|
||||||
|
|
||||||
(I think it will work on Edge or Opera or whatever, too. You'll need to
|
(I think it will work on Edge or Opera or whatever, too. You'll need
|
||||||
change the native messaging path in install.sh in those cases.)
|
to change the native messaging path in install.sh in those cases. Not
|
||||||
|
sure about Safari.)
|
||||||
|
|
||||||
#### in Chrome
|
#### in Chrome
|
||||||
|
|
||||||
|
@ -67,7 +70,7 @@ Developer mode (top-right corner).
|
||||||
|
|
||||||
Load-unpacked the `extension/` folder in this repo.
|
Load-unpacked the `extension/` folder in this repo.
|
||||||
|
|
||||||
Make a note of the extension ID. Mine is
|
**Make a note of the extension ID Chrome assigns.** Mine is
|
||||||
`jimpolemfaeckpjijgapgkmolankohgj`. We'll use this later.
|
`jimpolemfaeckpjijgapgkmolankohgj`. We'll use this later.
|
||||||
|
|
||||||
#### in Firefox
|
#### in Firefox
|
||||||
|
@ -134,11 +137,12 @@ operations, even when I don't feel like I'm actually doing anything.)
|
||||||
|
|
||||||
## Design
|
## Design
|
||||||
|
|
||||||
- `extension/`: Browser extension, written in JS
|
|
||||||
- [`background.js`](extension/background.js): **The most interesting file**. Defines all the
|
|
||||||
synthetic files and what browser operations they map to.
|
|
||||||
- `fs/`: Native FUSE filesystem, written in C
|
- `fs/`: Native FUSE filesystem, written in C
|
||||||
- [`tabfs.c`](fs/tabfs.c): Talks to FUSE, implements fs operations, talks to extension.
|
- [`tabfs.c`](fs/tabfs.c): Talks to FUSE, implements fs operations, talks to extension.
|
||||||
|
- `extension/`: Browser extension, written in JS
|
||||||
|
- [`background.js`](extension/background.js): **The most interesting
|
||||||
|
file**. Defines all the synthetic files and what browser
|
||||||
|
operations they invoke behind the scenes.
|
||||||
|
|
||||||
<!-- TODO: concretize this -->
|
<!-- TODO: concretize this -->
|
||||||
|
|
||||||
|
@ -172,6 +176,10 @@ GPLv3
|
||||||
|
|
||||||
## hmm
|
## hmm
|
||||||
|
|
||||||
|
processes as files. the real process is the browser.
|
||||||
|
|
||||||
|
browser and Unix
|
||||||
|
|
||||||
it's way too hard to make an extension. even 'make an extension' is
|
it's way too hard to make an extension. even 'make an extension' is
|
||||||
a bad framing. lightness
|
a bad framing. lightness
|
||||||
|
|
||||||
|
@ -186,9 +194,5 @@ fake filesystems talk
|
||||||
|
|
||||||
Screenotate
|
Screenotate
|
||||||
|
|
||||||
processes as files. the real process is the browser.
|
|
||||||
|
|
||||||
browser and Unix
|
|
||||||
|
|
||||||
rmdir a non-empty directory
|
rmdir a non-empty directory
|
||||||
|
|
||||||
|
|
|
@ -138,6 +138,18 @@ router["/tabs/by-id"] = {
|
||||||
router["/tabs/by-id/*/url"] = withTab(tab => tab.url + "\n");
|
router["/tabs/by-id/*/url"] = withTab(tab => tab.url + "\n");
|
||||||
router["/tabs/by-id/*/title"] = withTab(tab => tab.title + "\n");
|
router["/tabs/by-id/*/title"] = withTab(tab => tab.title + "\n");
|
||||||
router["/tabs/by-id/*/text"] = fromScript(`document.body.innerText`);
|
router["/tabs/by-id/*/text"] = fromScript(`document.body.innerText`);
|
||||||
|
router["/tabs/by-id/*/screenshot.png"] = {
|
||||||
|
async read({path, fh, size, offset}) {
|
||||||
|
const tabId = parseInt(pathComponent(path, -2));
|
||||||
|
await debugTab(tabId);
|
||||||
|
await sendDebuggerCommand(tabId, "Page.enable", {});
|
||||||
|
|
||||||
|
const {data} = await sendDebuggerCommand(tabId, "Page.captureScreenshot");
|
||||||
|
const arr = Uint8Array.from(atob(data), c => c.charCodeAt(0));
|
||||||
|
const slice = arr.slice(offset, offset + size);
|
||||||
|
return { buf: String.fromCharCode(...slice) };
|
||||||
|
}
|
||||||
|
};
|
||||||
router["/tabs/by-id/*/resources"] = {
|
router["/tabs/by-id/*/resources"] = {
|
||||||
async opendir({path}) {
|
async opendir({path}) {
|
||||||
const tabId = parseInt(pathComponent(path, -2));
|
const tabId = parseInt(pathComponent(path, -2));
|
||||||
|
@ -367,6 +379,7 @@ async function onMessage(req) {
|
||||||
try {
|
try {
|
||||||
response = await findRoute(req.path)[req.op](req);
|
response = await findRoute(req.path)[req.op](req);
|
||||||
response.op = req.op;
|
response.op = req.op;
|
||||||
|
if (response.buf) response.buf = btoa(response.buf);
|
||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
{
|
{
|
||||||
"manifest_version": 2,
|
"manifest_version": 2,
|
||||||
|
|
||||||
"name": "TabFS Extension",
|
"name": "TabFS",
|
||||||
"description": "Connects to TabFS filesystem",
|
"description": "Mount your browser tabs as a filesystem",
|
||||||
"version": "1.0",
|
"version": "1.0",
|
||||||
|
|
||||||
"permissions": [
|
"permissions": [
|
||||||
"tabs", "debugger", "nativeMessaging",
|
"tabs", "tabCapture", "debugger", "nativeMessaging",
|
||||||
"unlimitedStorage",
|
"unlimitedStorage",
|
||||||
"*://*/*"
|
"*://*/*"
|
||||||
],
|
],
|
||||||
|
|
13
fs/tabfs.c
13
fs/tabfs.c
|
@ -79,8 +79,9 @@ static int tabfs_getattr(const char *path, struct stat *stbuf) {
|
||||||
static int tabfs_readlink(const char *path, char *buf, size_t size) {
|
static int tabfs_readlink(const char *path, char *buf, size_t size) {
|
||||||
send_request("{op: %Q, path: %Q}", "readlink", path);
|
send_request("{op: %Q, path: %Q}", "readlink", path);
|
||||||
|
|
||||||
char *scan_buf; receive_response("{buf: %Q}", &scan_buf);
|
char *scan_buf; int scan_len;
|
||||||
snprintf(buf, size, "%s", scan_buf); free(scan_buf);
|
receive_response("{buf: %V}", &scan_buf, &scan_len);
|
||||||
|
memcpy(buf, scan_buf, scan_len < size ? scan_len : size); free(scan_buf);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -99,11 +100,11 @@ tabfs_read(const char *path, char *buf, size_t size, off_t offset,
|
||||||
send_request("{op: %Q, path: %Q, size: %d, offset: %d, fh: %d, flags: %d}",
|
send_request("{op: %Q, path: %Q, size: %d, offset: %d, fh: %d, flags: %d}",
|
||||||
"read", path, size, offset, fi->fh, fi->flags);
|
"read", path, size, offset, fi->fh, fi->flags);
|
||||||
|
|
||||||
// FIXME: base64
|
char *scan_buf; int scan_len;
|
||||||
char *scan_buf; receive_response("{buf: %Q}", &scan_buf);
|
receive_response("{buf: %V}", &scan_buf, &scan_len);
|
||||||
snprintf(buf, size, "%s", scan_buf); free(scan_buf);
|
memcpy(buf, scan_buf, scan_len < size ? scan_len : size); free(scan_buf);
|
||||||
|
|
||||||
return strlen(scan_buf);
|
return scan_len;
|
||||||
|
|
||||||
/* MAKE_REQ("read", { */
|
/* MAKE_REQ("read", { */
|
||||||
/* cJSON_AddStringToObject(req, "path", path); */
|
/* cJSON_AddStringToObject(req, "path", path); */
|
||||||
|
|
Loading…
Reference in a new issue