Created
August 16, 2024 13:36
-
-
Save davidfraser/161a8366cde68d8713109215427e8661 to your computer and use it in GitHub Desktop.
Patch ActivityWatch Web Watcher extensions to include profile names in the bucket they submit events to
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
#!/usr/bin/env python | |
"""Searches all Chrome profiles for a Windows user for the ActivityWatch Web Watcher extension | |
and then patches them to include their profile name in the bucket they submit events to | |
See https://github.com/ActivityWatch/aw-watcher-web/issues/82 | |
""" | |
import os | |
from os.path import abspath, exists, expanduser, isdir, join | |
import json | |
import logging | |
def get_chrome_data_dir(): | |
windows_chrome_data_dir = expanduser("~\\AppData\\Local\\Google\\Chrome\\User Data") | |
if not exists(windows_chrome_data_dir): | |
raise ValueError("Could not find Chrome user data directory") | |
return windows_chrome_data_dir | |
def find_profiles(): | |
chrome_data_dir = get_chrome_data_dir() | |
with open(join(chrome_data_dir, 'Local State')) as f: | |
local_state = json.load(f) | |
profiles_info = local_state.get('profile', {}) | |
profile_keys = profiles_info.get('profiles_order', []) | |
for profile_key in profile_keys: | |
profile_info = profiles_info.get('info_cache', {}).get(profile_key, {}) | |
profile_name = profile_info.get('name') | |
profile_user_name = profile_info.get('user_name') | |
yield {'dir': join(chrome_data_dir, profile_key), 'name': profile_name, 'user_name': profile_user_name} | |
if not profile_keys: | |
for filename in os.listdir(chrome_data_dir): | |
if filename == "Default" or filename.startswith("Profile "): | |
yield {'dir': join(chrome_data_dir, filename), 'name': filename, 'user_name': None} | |
def patch_profile_aw_web_watcher(profile_info): | |
extensions_dir = join(profile_info['dir'], 'Extensions') | |
profile_name = profile_info.get('name') | |
watcher_suffix = profile_info.get('name').replace(' ', '-').lower() | |
search_js = '"aw-watcher-web-" + browserName.toLowerCase()' | |
logging.info(f"Searching for ActivityWatch Web Watcher extensions under Chrome profile {profile_name}...") | |
for extension_key in os.listdir(extensions_dir): | |
extension_dir = join(extensions_dir, extension_key) | |
if not isdir(extension_dir): | |
continue | |
for version in os.listdir(extension_dir): | |
manifest_file = join(extension_dir, version, 'manifest.json') | |
if not exists(manifest_file): | |
continue | |
manifest = json.load(open(manifest_file)) | |
extension_name = manifest.get('name') | |
if extension_name == 'ActivityWatch Web Watcher': | |
app_js_file = join(extension_dir, version, 'out', 'app.js') | |
if exists(app_js_file): | |
add_js = f' + "{watcher_suffix}"' | |
app_js_src = open(app_js_file).read() | |
if add_js in app_js_src: | |
logging.info(f"Found {extension_name} for {profile_name}; already patched, so leaving") | |
elif (search_js + ';') in app_js_src: | |
logging.info(f"Found {extension_name} for {profile_name}; patching") | |
app_js_src = app_js_src.replace(search_js, search_js + add_js) | |
with open(app_js_file, 'w') as f: | |
f.write(app_js_src) | |
return | |
if __name__ == '__main__': | |
logging.getLogger().setLevel(logging.INFO) | |
for profile_info in find_profiles(): | |
patch_profile_aw_web_watcher(profile_info) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment