-
-
Save junkblocker/cd5819a508c60fd6b67e14ea3e6449e5 to your computer and use it in GitHub Desktop.
Interactively download user contributed docsets and cheatsheets for Zeal
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
#!/usr/bin/env python3 | |
"""Download Dash User Docsets and install them in Zeal""" | |
import configparser | |
import json | |
import tarfile | |
import urllib.request | |
from pathlib import Path | |
from sys import platform | |
from typing import Any, Dict, List | |
import easygui | |
USER_DOCSETS_URLS = (('docset', "https://zealusercontributions.now.sh/api/docsets"), | |
('cheatsheet', "https://zealusercontributions.now.sh/api/cheatsheets")) | |
APP_TITLE = "Download Zeal user docsets and cheatsheets" | |
ZEAL_NIX_CONFIG_PATH = Path.home() / ".config" / "Zeal" / "Zeal.conf" | |
ZEAL_NIX_FLATPAK_CONFIG_PATH = Path.home() / ".var" / "app" / "org.zealdocs.Zeal" / "config" / "Zeal" / "Zeal.conf" | |
ZEAL_WIN_DOCSETS_DIR = Path.home() / "AppData" / "Local" / "Zeal" / "Zeal" / "docsets" | |
def get_zeal_docsets_dir() -> Path: | |
if platform == "win32": | |
assert ZEAL_WIN_DOCSETS_DIR.is_dir() | |
return ZEAL_WIN_DOCSETS_DIR | |
else: | |
config = configparser.ConfigParser() | |
config.read([ZEAL_NIX_CONFIG_PATH.resolve(), ZEAL_NIX_FLATPAK_CONFIG_PATH.resolve()]) | |
docsets_dir = Path(config["docsets"]["path"]) | |
assert docsets_dir.is_dir() | |
return docsets_dir | |
def fetch_and_parse_json(url: str) -> List[Dict[Any, Any]]: | |
response = urllib.request.urlopen(url) | |
data = response.read() | |
text = data.decode("utf-8") | |
return json.loads(text) | |
def choose_docsets(user_docsets: List, k: str) -> List: | |
msg = f"Select all the user {k}s you want to install." | |
return easygui.multchoicebox(msg, APP_TITLE, [d["name"] for d in user_docsets]) | |
def download_and_extract_docsets(urls: List, directory: Path): | |
for url in urls: | |
easygui.msgbox( | |
f"Downloading {url} and extracting it in {directory}.\n\n" | |
"Please press OK and wait.", | |
APP_TITLE, | |
) | |
with urllib.request.urlopen(url) as response: | |
try: | |
with tarfile.open(fileobj=response, mode="r:gz") as tar: | |
tar.extractall(directory) | |
except OSError as exception: | |
show_exception(exception) | |
def search_url(choices: List, user_docsets: List) -> List: | |
# return [d["archive"] for d in user_docsets if d["name"] in choices] | |
return [d["urls"][0] for d in user_docsets if d["name"] in choices] | |
def confirm_docset_download(choices: List) -> bool: | |
return easygui.ccbox( | |
f"Docsets {', '.join(choices)} will now be installed", | |
APP_TITLE, | |
) | |
def download_more_docsets(k: str) -> bool: | |
return easygui.ynbox(f"Do you want to install more {k}s?", APP_TITLE, ("Yes", "No")) | |
def exit_message(): | |
easygui.msgbox( | |
"Bye bye.\n\nPlease remember to restart Zeal to refresh the docsets.", | |
APP_TITLE, | |
"Quit", | |
) | |
def get_existing_docsets(docsets_dir: Path) -> List: | |
return [x.stem.lower() for x in docsets_dir.iterdir() if x.is_dir()] | |
def filter_existing_docsets(user_docsets: List[Dict[Any, Any]], | |
existing_docsets: List[Dict[Any, Any]]) -> List[Dict[Any, Any]]: | |
return [x for x in user_docsets if Path(x["archive"]).stem.lower() not in existing_docsets] | |
def show_exception(exception: Exception): | |
easygui.exceptionbox(f"!!! Error: {exception}", APP_TITLE) | |
if __name__ == "__main__": | |
try: | |
docsets_dir = get_zeal_docsets_dir() | |
for k, USER_DOCSETS_URL in USER_DOCSETS_URLS: | |
print(f"Downloading the {k}s list from {USER_DOCSETS_URL}...") | |
user_docsets: List[Dict[Any, Any]] = fetch_and_parse_json(USER_DOCSETS_URL) | |
while True: | |
existing_docsets = get_existing_docsets(docsets_dir) | |
user_docsets = filter_existing_docsets(user_docsets, existing_docsets) | |
user_docsets = sorted(user_docsets, key=lambda x: x["name"].casefold()) | |
choices = choose_docsets(user_docsets, k) | |
if not choices: | |
break | |
docset_urls = search_url(choices, user_docsets) | |
if confirm_docset_download(choices): | |
download_and_extract_docsets(docset_urls, docsets_dir) | |
if not download_more_docsets(k): | |
break | |
exit_message() | |
except Exception as exception: | |
show_exception(exception) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment