-
-
Notifications
You must be signed in to change notification settings - Fork 218
feat(chrome_extension): write dom changes to database (using sockets) during openadapt.record #364
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Changes from all commits
Commits
Show all changes
104 commits
Select commit
Hold shift + click to select a range
8ac5676
Added native_chrome_extension folder
5c7f573
Implementing Issue #83
1572d45
Minor changes for the .sh installation script
224f321
Implementing Scrubbing Issue #47
5f3dd57
remove native folder
4912397
add native folder
114b4cc
Add briwer.py, native-manifest.json,
afcb296
remove uneccessary commits
8d65084
Merge branch 'MLDSAI:main' into issue51
KrishPatel13 84ec702
Merge branch 'MLDSAI:main' into issue51
KrishPatel13 4a9cd54
Merge branch 'MLDSAI:main' into issue51
KrishPatel13 1c3544a
Merge branch 'MLDSAI:main' into issue51
KrishPatel13 958efaa
Merge branch 'MLDSAI:main' into issue51
KrishPatel13 10a55f6
Progress on Issue #51
8a2a11f
Add nativemessaging
76e45aa
Merge branch 'MLDSAI:main' into issue51
KrishPatel13 daac09e
remove all
8a719a9
test_extension files
e6b1e9f
browser to chrome
8a86f49
browser -> chrome
bfeb34d
test native applicatoin
7a48fa9
fixes
7fbe220
add bat in antive json
a3dc610
resolving merge conflicts
a0afc90
Merge pull request #7 from MLDSAI/main
KrishPatel13 8e93a83
attempting ping pong example on chrome
34f237c
ping pong example on chrome
bd10fa8
Merge branch 'MLDSAI:main' into test_extension
KrishPatel13 64df009
New Tab Listner
c0e4e48
add content script for accessing document object
b484f7e
remove old code
2847d1a
Now, the extensions sends
aa44f38
Mutation Observer in content.js
3acd453
working DOM Mutation Observer COde
4efc218
Chrome Extension - Progress:
062e5af
add link for the system diagram
3eda05f
Update:
6413463
add ignoreAtributes
0212e32
add hostPermissions
b621923
Now the Extensions sends:
c18f613
before test code
0562292
resolve merge conflicts
5e513dd
Merge pull request #357 from OpenAdaptAI/main
KrishPatel13 3b7f2b7
add serve.py t o show pipe is working normally but not
9a7c29c
working Extension demo with sockets
1dff338
add ToDO
59a1029
add todos
863dee3
add Todos
8b4ad90
format Js files
f761da7
add documentatoin
56a320e
minor changes in formatting
346772e
format multiple files
aea191b
format pylint browser
75b776f
add read_browser_events and browser evnet queues
1efa3e4
add browser writer function
db1c249
changes to the extension
1aade8e
add browser events in multiple files
ba220be
add missing browser events
598ee36
add browser_event_dict in visualize.py
7ec2567
fix: socket_client script on
562d240
add code for sockets.py and make related changes
e59e6a6
merge main to continue_extension
5fc3859
update the sockets.py script
220d796
Merge pull request #382 from OpenAdaptAI/main
KrishPatel13 b4bb984
rename to mock_client
3e68d62
fix: server send message
11bce46
now the extensoin works using the sockets.py
f13f885
update browser.py to use sockets.py
fcd7428
now the browser.py and mock_client
9aec8b9
add mock_client code to record
056087f
try to fix errors during record eith extension
c313199
try to fix communication closed
de76ab1
try to fix error :-
bb1b082
Merge pull request #399 from OpenAdaptAI/main
KrishPatel13 109b620
attempt to observe
06d7ed8
try to fix the infinite running server
c38c6cc
Merge branch 'main' into continue_extension
KrishPatel13 d2e4301
Create browser.sh
0dm b33f6a0
mac version
0dm 14f3bad
merge main
0dm 1d69344
write documentstates to db and visualize
0dm c44ca0a
remove duplicate messages, add exception handling,
0dm 791e3ee
xy + input value + debounce
0dm 09cab02
add nativemessaginghost install script
0dm 781d531
Create view_messages_table.py
0dm ad68e18
add comment
0dm 9f2932e
Update browser.py
0dm c501f62
Merge remote-tracking branch 'upstream/main' into continue_extension
0dm 33718cf
add mutationObserverImplementation
0dm 7dd2188
work on socket
0dm a80004c
fixed socket
0dm 3a468f8
Update browser.py
0dm 478e325
update windows path & clean
0dm 46bff0e
Merge remote-tracking branch 'upstream/main' into continue_extension
0dm 4b8bf27
styling
0dm 1a74aa1
more styling
0dm bc2d6a6
delete init
0dm a5daeb4
rename directory
0dm 59be3e4
disable socket for now
0dm ac1ac8d
use last message
0dm bbc4a3a
add elements
0dm c67975b
progress on recording + db table
0dm 4759725
Create 1a19ce257672_add_browserevent_message.py
0dm cafc053
fix error in browser
0dm File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,6 +15,8 @@ cache | |
| *.db | ||
| *.db-journal | ||
|
|
||
| *.html | ||
|
|
||
| # VSCode | ||
| .VSCode | ||
| .vsCode | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| """add BrowserEvent.message | ||
|
|
||
| Revision ID: 1a19ce257672 | ||
| Revises: 8713b142f5de | ||
| Create Date: 2023-08-28 17:01:07.703670 | ||
|
|
||
| """ | ||
| import sqlalchemy as sa | ||
|
|
||
| from alembic import op | ||
| import openadapt | ||
|
|
||
| # revision identifiers, used by Alembic. | ||
| revision = "1a19ce257672" | ||
| down_revision = "8713b142f5de" | ||
| branch_labels = None | ||
| depends_on = None | ||
|
|
||
|
|
||
| def upgrade() -> None: | ||
| # ### commands auto generated by Alembic - please adjust! ### | ||
| op.create_table( | ||
| "browser_event", | ||
| sa.Column("id", sa.Integer(), nullable=False), | ||
| sa.Column( | ||
| "recording_timestamp", | ||
| openadapt.models.ForceFloat(precision=10, scale=2, asdecimal=False), | ||
| nullable=True, | ||
| ), | ||
| sa.Column("message", sa.JSON(), nullable=True), | ||
| sa.Column( | ||
| "timestamp", | ||
| openadapt.models.ForceFloat(precision=10, scale=2, asdecimal=False), | ||
| nullable=True, | ||
| ), | ||
| sa.ForeignKeyConstraint( | ||
| ["recording_timestamp"], | ||
| ["recording.timestamp"], | ||
| name=op.f("fk_browser_event_recording_timestamp_recording"), | ||
| ), | ||
| sa.PrimaryKeyConstraint("id", name=op.f("pk_browser_event")), | ||
| ) | ||
| # ### end Alembic commands ### | ||
|
|
||
|
|
||
| def downgrade() -> None: | ||
| # ### commands auto generated by Alembic - please adjust! ### | ||
| op.drop_table("browser_event") | ||
| # ### end Alembic commands ### |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| /** | ||
| * @file background.js | ||
| * @description This file is responsible for communicating with the native | ||
| * messaging host and the content script. | ||
| * @see https://docs.google.com/presentation/d/106AXW3sBe7-7E-zIggnMnaUKUXWAj_aAuSxBspTDcGk/edit#slide=id.p | ||
| */ | ||
|
|
||
| const hostName = "openadapt"; | ||
| var port = null; // Native Messaging port | ||
| var lastMsg = null; | ||
|
|
||
| /* | ||
| * Handle received messages from browser.js | ||
| */ | ||
| function onReceived(response) { | ||
| console.log(response); | ||
| } | ||
|
|
||
| function onDisconnected() { | ||
| msg = "Failed to connect: " + chrome.runtime.lastError.message; // silence error | ||
| port = null; | ||
| } | ||
|
|
||
| function connect() { | ||
| port = chrome.runtime.connectNative(hostName); | ||
| port.onMessage.addListener(onReceived); | ||
| port.onDisconnect.addListener(onDisconnected); | ||
| } | ||
|
|
||
| /* | ||
| * Message listener for content script | ||
| */ | ||
| function messageListener(message, sender, sendResponse) { | ||
| const timestampThreshold = 30; // arbitrary threshold in milliseconds | ||
|
|
||
| try { | ||
| if (lastMsg !== null) { | ||
| if ( | ||
| Math.abs(message.timestamp - lastMsg.timestamp) < timestampThreshold && | ||
| message.tagName === lastMsg.tagName && | ||
| message.action === lastMsg.action | ||
| ) { | ||
| return; | ||
| } | ||
| } | ||
| console.log({ message, sender, sendResponse }); | ||
| port.postMessage(message); // send to browser.py (native messaging host) | ||
| lastMsg = message; | ||
| } catch (e) { | ||
| connect(); | ||
| } | ||
| } | ||
| connect(); | ||
| chrome.runtime.onMessage.addListener(messageListener); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| @echo off | ||
|
|
||
| python -u "P:\\OpenAdapt AI - MLDS AI\\cloned_repo\\OpenAdapt\\chrome\\browser.py" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,113 @@ | ||
| #!/usr/bin/env python3 # noqa: D205 | ||
|
|
||
| """Script for communicating with the browser extension. # noqa: D205 D415 | ||
| Usage: | ||
| See `native_chrome_extension/browser.bat`. | ||
| """ | ||
|
|
||
| # Note that running python with the `-u` flag is required on Windows, | ||
| # in order to ensure that stdin and stdout are opened in binary, rather | ||
| # than text, mode. | ||
|
|
||
| import json | ||
| import sqlite3 | ||
| import struct | ||
| import sys | ||
|
|
||
| from openadapt import config, sockets | ||
|
|
||
| SOCKETS = True | ||
| DBG_DATABASE = False | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you please clarify what this is for? |
||
|
|
||
|
|
||
| def get_message() -> dict: | ||
| """Read a message from stdin and decode it. | ||
|
|
||
| Returns: | ||
| A dictionary representing the decoded message. | ||
| """ | ||
| raw_length = sys.stdin.buffer.read(4) | ||
| if len(raw_length) == 0: | ||
| sys.exit(0) | ||
| message_length = struct.unpack("@I", raw_length)[0] | ||
| message = sys.stdin.buffer.read(message_length).decode("utf-8") | ||
| return json.loads(message) | ||
|
|
||
|
|
||
| def encode_message(message_content: any) -> dict: | ||
| """Encode a message for transmission, given its content. | ||
|
|
||
| Args: | ||
| message_content: The content of the message to be encoded. | ||
|
|
||
| Returns: | ||
| A dictionary containing the encoded message. | ||
| """ | ||
| # https://docs.python.org/3/library/json.html#basic-usage | ||
| # To get the most compact JSON representation, you should specify | ||
| # (',', ':') to eliminate whitespace. | ||
| # We want the most compact representation because the browser rejects | ||
| # messages that exceed 1 MB. | ||
| encoded_content = json.dumps(message_content, separators=(",", ":")).encode("utf-8") | ||
| encoded_length = struct.pack("@I", len(encoded_content)) | ||
| return {"length": encoded_length, "content": encoded_content} | ||
|
|
||
|
|
||
| def send_message(encoded_message: dict) -> None: | ||
| """Send an encoded message to stdout. | ||
|
|
||
| Args: | ||
| encoded_message: The encoded message to be sent. | ||
| """ | ||
| sys.stdout.buffer.write(encoded_message["length"]) | ||
| sys.stdout.buffer.write(encoded_message["content"]) | ||
| sys.stdout.buffer.flush() | ||
|
|
||
|
|
||
| def send_message_to_client(conn: sockets.Connection, message: dict) -> None: | ||
| """Send a message to the client. | ||
|
|
||
| Args: | ||
| conn: The connection to the client. | ||
| message: The message to be sent. | ||
| """ | ||
| try: | ||
| conn.send(message) | ||
| except Exception as exc: | ||
| print(f"Error sending message to client: {exc}") | ||
|
|
||
|
|
||
| def main() -> None: | ||
| """Main function.""" | ||
| if DBG_DATABASE: | ||
| db_conn = sqlite3.connect("messages.db") | ||
| c = db_conn.cursor() | ||
| c.execute(""" | ||
| CREATE TABLE IF NOT EXISTS messages ( | ||
| id INTEGER PRIMARY KEY AUTOINCREMENT, | ||
| message TEXT NOT NULL | ||
| ) | ||
| """) | ||
| if SOCKETS: | ||
| conn = sockets.create_server_connection(config.SOCKET_PORT) | ||
| while True: | ||
| if SOCKETS and conn.closed: | ||
| conn = sockets.create_server_connection(config.SOCKET_PORT) | ||
| message = get_message() | ||
|
|
||
| # Log the message to the database | ||
| if DBG_DATABASE: | ||
| c.execute( | ||
| "INSERT INTO messages (message) VALUES (?)", (json.dumps(message),) | ||
| ) | ||
| db_conn.commit() | ||
| response = {"message": "Data received and logged successfully!"} | ||
| if message: | ||
| encoded_response = encode_message(response) | ||
| send_message(encoded_response) | ||
| if SOCKETS: | ||
| send_message_to_client(conn, message) | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| main() | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,124 @@ | ||
| /** | ||
| * @file content.js | ||
| * @description This file is injected into the web page and is responsible for | ||
| * capturing DOM changes and sending them to the background script. | ||
| */ | ||
|
|
||
| let logged = false; | ||
| let ignoreAttributes = new Set(); | ||
| const elements = {}; | ||
|
|
||
| /* | ||
| * Function to send a message to the background script | ||
| */ | ||
| function sendMessageToBackgroundScript(message) { | ||
| chrome.runtime.sendMessage(message); | ||
| } | ||
|
|
||
| /* | ||
| * Function to capture initial document state and | ||
| * send it to the background script | ||
| */ | ||
| function captureDocumentState() { | ||
| const documentBody = document.body.outerHTML; | ||
| const documentHead = document.head.outerHTML; | ||
| const page_url = window.location.href; | ||
|
|
||
| sendMessageToBackgroundScript({ | ||
| action: "captureDocumentState", | ||
| documentBody: documentBody, | ||
| documentHead: documentHead, | ||
| elements: elements, | ||
| url: page_url, | ||
| timestamp: Date.now(), | ||
| }); | ||
| } | ||
|
|
||
| function handleElementClick(event) { | ||
| const element = event.target; | ||
| const tagName = element.tagName; | ||
| const { x, y } = elements[element.id] || {}; | ||
| const value = elements[element.id]?.value || ""; | ||
| const attributes = {}; | ||
|
|
||
| for (const attr of element.attributes) { | ||
| attributes[attr.name] = attr.value; | ||
| } | ||
|
|
||
| sendMessageToBackgroundScript({ | ||
| action: "elementClicked", | ||
| tagName: tagName, | ||
| attributes: attributes, | ||
| x: x, | ||
| y: y, | ||
| value: value, | ||
| url: window.location.href, | ||
| timestamp: Date.now(), | ||
| }); | ||
| } | ||
|
|
||
| function debounce(func, delay) { | ||
| let timerId; | ||
| return function (...args) { | ||
| if (timerId) { | ||
| clearTimeout(timerId); | ||
| } | ||
| timerId = setTimeout(() => { | ||
| func.apply(this, args); | ||
| timerId = null; | ||
| }, delay); | ||
| }; | ||
| } | ||
|
|
||
| function handleDebouncedInput(event) { | ||
| const element = event.target; | ||
| const { x, y } = elements[element.id]; | ||
| const value = elements[element.id].element.value; | ||
| const tagName = element.tagName; | ||
| const attributes = {}; | ||
|
|
||
| for (const attr of element.attributes) { | ||
| attributes[attr.name] = attr.value; | ||
| } | ||
|
|
||
| sendMessageToBackgroundScript({ | ||
| action: "elementInput", | ||
| tagName: tagName, | ||
| attributes: attributes, | ||
| x: x, | ||
| y: y, | ||
| value: value, | ||
| url: window.location.href, | ||
| timestamp: Date.now(), | ||
| }); | ||
| } | ||
|
|
||
| const debouncedInputHandler = debounce(handleDebouncedInput, 500); | ||
|
|
||
| function handleElementInput(event) { | ||
| debouncedInputHandler(event); | ||
| } | ||
|
|
||
| function addElement(element) { | ||
| const rect = element.getBoundingClientRect(); | ||
| const x = rect.left + window.scrollX; | ||
| const y = rect.top + window.scrollY; | ||
| const value = element.value; | ||
| if (!element.id) { | ||
| element.id = element.tagName + "_" + x + "_" + y; | ||
| } | ||
| elements[element.id] = { element, x, y, value }; | ||
| element.addEventListener("click", handleElementClick); | ||
| element.addEventListener("input", debounce(handleDebouncedInput, 500)); | ||
| } | ||
|
|
||
| function addEventListeners() { | ||
| const elements = document.getElementsByTagName("*"); | ||
|
|
||
| for (const element of elements) { | ||
| addElement(element); | ||
| } | ||
| } | ||
|
|
||
| addEventListeners(); | ||
| captureDocumentState(); |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will this ever be False?