Skip to content
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

Add update script and update Firefox schemas to 84 #94

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
173 changes: 173 additions & 0 deletions fetch-firefox-schemas.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
#!/usr/bin/python3

import json
import re
import sys
from concurrent.futures import ThreadPoolExecutor
from operator import itemgetter
from pathlib import Path
from urllib.request import urlopen


BASE_URL = 'https://hg.mozilla.org/releases/mozilla-release/raw-file/'
BROWSER_PATH = '/browser/components/extensions'
TOOLKIT_PATH = '/toolkit/components/extensions'
TMP_SCHEMAS_DIR = Path('./tmp_firefox_schemas/')
# Taken from sidebar at: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API
PUBLIC_APIS = [
"alarms",
"bookmarks",
"browserAction",
"browserSettings",
"browsingData",
"captivePortal",
"clipboard",
"commands",
"contentScripts",
"contextMenus",
"contextualIdentities",
"cookies",
"devtools",
"devtools.inspectedWindow",
"devtools.network",
"devtools.panels",
"dns",
"downloads",
"events",
"extension",
"extensionTypes",
"find",
"history",
"i18n",
"identity",
"idle",
"management",
"menus",
"notifications",
"omnibox",
"pageAction",
"permissions",
"pkcs11",
"privacy",
"proxy",
"runtime",
"search",
"sessions",
"sidebarAction",
"storage",
"tabs",
"theme",
"topSites",
"types",
"userScripts",
"webNavigation",
"webRequest",
"windows",
]


def main():
args = sys.argv
if len(args) == 1 or (len(args) == 2 and args[1] in ('-h', '--help')):
print_usage()
elif len(args) == 3 and args[1] == "download":
download(args[2])
elif len(args) == 2 and args[1] == "merge":
merge()
else:
print("Error: invalid command line", file=sys.stderr)
print_usage()
sys.exit(1)


def print_usage():
print(f"Usage: {sys.argv[0]} [download <REVISION>] [merge]")
print(" <REVISION> Found at https://hg.mozilla.org/releases/mozilla-release/tags")


def download(revision):
browser_url = f"{BASE_URL}{revision}{BROWSER_PATH}/schemas/"
toolkit_url = f"{BASE_URL}{revision}{TOOLKIT_PATH}/schemas/"

print(f"Fetching list of schemas at {browser_url}")
schema_list = fetch_json_links(browser_url)

print(f"Fetching list of schemas at {toolkit_url}")
schema_list.extend(fetch_json_links(toolkit_url))

TMP_SCHEMAS_DIR.mkdir(exist_ok=True)
with ThreadPoolExecutor() as executor:
executor.map(fetch_and_save_json_schema, schema_list)


def fetch_json_links(url):
response = urlopen(url).read().decode('utf-8')
return [
url + entry.split(' ', maxsplit=3)[2]
for entry in response.strip().split('\n')
if entry.endswith('.json')
]


def fetch_and_save_json_schema(url):
file_name = Path(url).name
print(f"Getting {file_name}…")
try:
response = urlopen(url)
(TMP_SCHEMAS_DIR / file_name).write_text(response.read().decode('utf-8'))
except Exception as e:
print(f"Error retrieving {file_name}: ({e})")


def merge():
schema_dict = {}
files = list(TMP_SCHEMAS_DIR.iterdir())
if len(files) == 0:
print("Error: no files to merge. Download schemas files first.", file=sys.stderr)
print_usage()
sys.exit(1)
files.sort()
for file in files:
print(f"Reading {file.name}")
content = json.loads(remove_comments(file.open().read()))
for d in (d for d in content if (namespace := d["namespace"]).split('.')[0] in PUBLIC_APIS):
print(f"> Found namespace: {namespace}")
if namespace in schema_dict:
deep_update(schema_dict[namespace], d)
else:
schema_dict[namespace] = d

print("\nPut this in `readme.md`:")
for schema in schema_dict.values():
ns = schema["namespace"]
print(f"* [browser.{ns}](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/{ns})")
Path("stable-api-ff.json").write_text(get_final_json(schema_dict))


def remove_comments(s):
start_index = s.index('[')
return s[start_index:]


def deep_update(d, u):
for key, val in u.items():
if key not in d:
d[key] = val
elif isinstance(val, dict):
d[key] = update(d[key], val)
elif isinstance(val, list):
if d[key] != val:
d[key].extend(val)
else:
d[key] = val
return d


def get_final_json(schema_dict):
return (json.dumps(list(schema_dict.values()), indent=2)
.replace('''"id": "Setting"''', '''"id": "BrowserSetting"''')
.replace('''"$ref": "types.Setting"''', '''"$ref": "types.BrowserSetting"''')
)


main()
48 changes: 37 additions & 11 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -384,29 +384,55 @@ chrome.registerPlugin(new CookiePlugin());
## Webextensions API

* [browser.alarms](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/alarms)
* [browser.bookmarks](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/bookmarks)
* [browser.browserAction](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/browserAction)
* [browser.browserSettings](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/browserSettings)
* [browser.browsingData](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/browsingData)
* [browser.captivePortal](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/captivePortal)
* [browser.clipboard](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/clipboard)
* [browser.commands](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/commands)
* [browser.contentScripts](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/contentScripts)
* [browser.contextualIdentities](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/contextualIdentities)
* [browser.cookies](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/cookies)
* [browser.devtools](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/devtools)
* [browser.devtools.inspectedWindow](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/devtools.inspectedWindow)
* [browser.devtools.network](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/devtools.network)
* [browser.devtools.panels](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/devtools.panels)
* [browser.dns](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/dns)
* [browser.downloads](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/downloads)
* [browser.events](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/events)
* [browser.manifest](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/manifest)
* [browser.extensionTypes](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/extensionTypes)
* [browser.extension](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/extension)
* [browser.extensionTypes](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/extensionTypes)
* [browser.find](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/find)
* [browser.history](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/history)
* [browser.i18n](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/i18n)
* [browser.identity](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/identity)
* [browser.idle](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/idle)
* [browser.management](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/management)
* [browser.contextMenus](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/contextMenus)
* [browser.menus](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/menus)
* [browser.notifications](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/notifications)
* [browser.omnibox](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/omnibox)
* [browser.pageAction](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/pageAction)
* [browser.permissions](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/permissions)
* [browser.pkcs11](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/pkcs11)
* [browser.privacy](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/privacy)
* [browser.privacy.network](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/privacy.network)
* [browser.privacy.services](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/privacy.services)
* [browser.privacy.websites](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/privacy.websites)
* [browser.proxy](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/proxy)
* [browser.runtime](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/runtime)
* [browser.search](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/search)
* [browser.sessions](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/sessions)
* [browser.sidebarAction](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/sidebarAction)
* [browser.storage](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/storage)
* [browser.test](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/test)
* [browser.tabs](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/tabs)
* [browser.theme](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/theme)
* [browser.topSites](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/topSites)
* [browser.types](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/types)
* [browser.userScripts](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/userScripts)
* [browser.webNavigation](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/webNavigation)
* [browser.webRequest](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/webRequest)
* [browser.bookmarks](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/bookmarks)
* [browser.browserAction](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/browserAction)
* [browser.commands](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/commands)
* [browser.contextMenusInternal](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/contextMenusInternal)
* [browser.contextMenus](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/contextMenus)
* [browser.history](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/history)
* [browser.pageAction](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/pageAction)
* [browser.tabs](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/tabs)
* [browser.windows](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/windows)

# Any questions?
Expand Down
2 changes: 2 additions & 0 deletions src/api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ import StorageArea from '../types/storage-area';

const typeMap = {
'types.ChromeSetting': ChromeSettings,
'types.Setting': ChromeSettings,
'StorageArea': StorageArea,
'StorageAreaSync': StorageArea,
'SourcesPanel': SourcePanel,
'ElementsPanel': ElementsPanel,
'ContentSetting': ContentSettings
Expand Down
Loading