Created
August 4, 2018 22:47
-
-
Save cryzed/29e6ff9fbf92281f8c3bded50de68836 to your computer and use it in GitHub Desktop.
This file contains 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
import argparse | |
import json | |
import os | |
import posixpath | |
import shutil | |
import subprocess | |
import tempfile | |
import requests | |
EXTENSIONS_PATH = os.path.expanduser('~/.config/chromium/Default/Extensions') | |
LOCAL_STATE_PATH = os.path.expanduser('~/.config/chromium/Local State') | |
MANIFEST_PATH_TEMPLATE = os.path.expanduser('~/.config/chromium/Default/Extensions/{id}/{version}/manifest.json') | |
# https://ungoogled-software.github.io/ungoogled-chromium-wiki/faq#can-i-install-extensions-from-the-chrome-webstore | |
CRX_URL_TEMPLATE = 'https://clients2.google.com/service/update2/crx?response=redirect&prodversion={version}&x=id%3D{id}%26installsource%3Dondemand%26uc' | |
argument_parser = argparse.ArgumentParser() | |
# Chromium 67.0.3396.87 Arch Linux | |
def get_installed_chromium_version(): | |
with open(LOCAL_STATE_PATH, 'rb') as file: | |
data = json.load(file) | |
return data['startup_metric']['last_startup_version'] | |
def get_extension_ids(): | |
ids = set(os.listdir(EXTENSIONS_PATH)) | |
return ids - {'Temp'} | |
def get_installed_version(extension_id): | |
versions = os.listdir(os.path.join(EXTENSIONS_PATH, extension_id)) | |
return sorted(versions, reverse=True)[0] | |
def check_for_update(chromium_version, extension_id, installed_version): | |
crx_url = CRX_URL_TEMPLATE.format(version=chromium_version, id=extension_id) | |
response = requests.get(crx_url, allow_redirects=False, stream=True) | |
location = response.headers['Location'] | |
filename = posixpath.basename(location) | |
version = os.path.splitext(filename)[0].replace('extension_', '', 1) | |
if version.replace('_', '.') != installed_version.replace('_', '.'): | |
return version, location | |
def install_update(crx_path): | |
executable = shutil.which('chromium') | |
subprocess.run([executable, crx_path], stderr=subprocess.DEVNULL, stdout=subprocess.DEVNULL) | |
def load_manifest(extension_id, version): | |
path = MANIFEST_PATH_TEMPLATE.format(id=extension_id, version=version) | |
with open(path, 'rb') as file: | |
return json.load(file) | |
def main(arguments): | |
chromium_version = get_installed_chromium_version() | |
chromium_major_version = '.'.join(chromium_version.split('.', 2)[:-1]) | |
print(f'Detected Chromium version: {chromium_version} (Major: {chromium_major_version})') | |
for extension_id in get_extension_ids(): | |
extension_version = get_installed_version(extension_id) | |
manifest = load_manifest(extension_id, extension_version) | |
print(f'Checking updates for extension {manifest["name"]!r} ({extension_id}) v{manifest["version"]}...') | |
update = check_for_update(chromium_major_version, extension_id, extension_version) | |
if not update: | |
continue | |
version, url = update | |
print(f'Downloading update {version}: {url}...') | |
fd, path = tempfile.mkstemp('.crx') | |
response = requests.get(url) | |
with os.fdopen(fd, 'wb') as file: | |
file.write(response.content) | |
print('Installing update...') | |
install_update(path) | |
if __name__ == '__main__': | |
arguments = argument_parser.parse_args() | |
argument_parser.exit(main(arguments)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment