diff --git a/plugin.py b/plugin.py index 61209cb..9496481 100644 --- a/plugin.py +++ b/plugin.py @@ -1,13 +1,14 @@ +import json import os import platform import shutil import tarfile import tempfile -import time +import urllib.error +import urllib.request import zipfile from io import UnsupportedOperation -import requests import sublime from LSP.plugin import ( AbstractPlugin, @@ -18,69 +19,17 @@ ) from LSP.plugin.core.typing import Any, Callable, Dict, List, Mapping, Optional -GITHUB_DL_URL = 'https://github.com/valentjn/ltex-ls/releases/download/'\ - + '{0}/ltex-ls-{0}{1}' # Format with Release-Tag -GITHUB_RELEASES_API_URL = 'https://api.github.com/repos/valentjn/ltex-'\ - + 'ls/releases/latest' -SERVER_FOLDER_NAME = 'ltex-ls-{}' # Format with Release-Tag -LATEST_TESTED_RELEASE = '16.0.0' # Latest testet LTEX-LS release +GITHUB_DL_URL = ( + "https://github.com/valentjn/ltex-ls/releases/download/" + "{0}/ltex-ls-{0}{1}" +) # Format with Release-Tag +GITHUB_RELEASES_API_URL = ( + "https://api.github.com/repos/valentjn/ltex-" + "ls/releases/latest" +) +SERVER_FOLDER_NAME = "ltex-ls-{}" # Format with Release-Tag +LATEST_TESTED_RELEASE = "16.0.0" # Latest testet LTEX-LS release LATEST_GITHUB_RELEASE = None -STORAGE_FOLDER_NAME = 'LSP-ltex-ls' -SETTINGS_FILENAME = 'LSP-ltex-ls.sublime-settings' - - -def show_download_progress(finished, total) -> None: - """ - Shows the download progress in the Sublime status bar - - :param finished: A measure how much is finished - :type finished: double or None - :param total: A measure of the total amount to download - :type total: double or None - - :returns: Nothing - :rtype: None - """ - if finished and total: - percent = finished * 100 / total - sublime.status_message('ltex-ls: downloading: {0:2.2f}%' - .format(percent)) - else: - sublime.status_message('ltex-ls: downloading...') - - -def download_file(url, file_name, show_progress) -> None: - """ - Downloads a file and shows the progress. - - :param url: The url to download drom - :type url: string - :param file_name: The path to the file to download to - :type file_name: string - :param show_progress: The show progress - :type show_progress: a function taking to doubles - - :returns: Nothing - :rtype: None - """ - r = requests.get(url, stream=True) - total_length = r.headers.get('content-length') - - with open(file_name, 'wb') as out_file: - if total_length: - finished = 0 - total_length = int(total_length) - last_displayed = 0 - for chunk in r.iter_content(chunk_size=4096): - if last_displayed != int(time.time()): - show_progress(finished, total_length) - last_displayed = int(time.time()) - finished += len(chunk) - out_file.write(chunk) - else: - out_file.write(r.content) - show_progress(None, None) - show_progress(1, 1) +STORAGE_FOLDER_NAME = "LSP-ltex-ls" +SETTINGS_FILENAME = "LSP-ltex-ls.sublime-settings" def fetch_latest_release() -> None: @@ -93,10 +42,10 @@ def fetch_latest_release() -> None: global LATEST_GITHUB_RELEASE if not LATEST_GITHUB_RELEASE: try: - resp = requests.get(GITHUB_RELEASES_API_URL) - data = resp.json() - LATEST_GITHUB_RELEASE = data['tag_name'] - except requests.ConnectionError: + with urllib.request.urlopen(GITHUB_RELEASES_API_URL) as f: + data = json.loads(f.read().decode("utf-8")) + LATEST_GITHUB_RELEASE = data["tag_name"] + except urllib.error.URLError: pass @@ -115,7 +64,7 @@ def code_action_insert_settings(server_setting_key: str, value: dict): :type value: dict """ settings = sublime.load_settings(SETTINGS_FILENAME) - server_settings = settings.get('settings') + server_settings = settings.get("settings") exception_dict = server_settings.get(server_setting_key, {}) for k, val in value.items(): @@ -125,7 +74,7 @@ def code_action_insert_settings(server_setting_key: str, value: dict): exception_dict[k] = new_language_setting server_settings[server_setting_key] = exception_dict - settings.set('settings', server_settings) + settings.set("settings", server_settings) sublime.save_settings(SETTINGS_FILENAME) pass @@ -162,12 +111,12 @@ def serverversion(cls) -> str: :rtype: str """ settings = sublime.load_settings(SETTINGS_FILENAME) - version = settings.get('version') + version = settings.get("version") if version: return version # Use latest tested release by default but allow overwriting the # behavior. - if settings.get('allow_untested') and LATEST_GITHUB_RELEASE: + if settings.get("allow_untested") and LATEST_GITHUB_RELEASE: return LATEST_GITHUB_RELEASE return LATEST_TESTED_RELEASE @@ -184,8 +133,9 @@ def serverdir(cls) -> str: Else None :rtype: str """ - return os.path.join(cls.basedir(), SERVER_FOLDER_NAME - .format(cls.serverversion())) + return os.path.join( + cls.basedir(), SERVER_FOLDER_NAME.format(cls.serverversion()) + ) @classmethod def needs_update_or_installation(cls) -> bool: @@ -196,7 +146,7 @@ def additional_variables(cls) -> Optional[Dict[str, str]]: return { "script": "ltex-ls.bat" if platform.system() == "Windows" else "ltex-ls", "serverdir": cls.serverdir(), - "serverversion": cls.serverversion() + "serverversion": cls.serverversion(), } @classmethod @@ -207,9 +157,9 @@ def install_or_update(cls) -> None: shutil.rmtree(cls.basedir()) os.makedirs(cls.basedir()) with tempfile.TemporaryDirectory() as tempdir: - archive_path = os.path.join(tempdir, 'server.tar.gz') + archive_path = os.path.join(tempdir, "server.tar.gz") - suffix = ".tar.gz" # platform-independent release + suffix = ".tar.gz" # platform-independent release if os.getenv("JAVA_HOME") is None: p = sublime.platform() if p == "osx": @@ -219,10 +169,11 @@ def install_or_update(cls) -> None: elif p == "windows": suffix = "-windows-x64.zip" - download_file(GITHUB_DL_URL.format(cls.serverversion(), suffix), - archive_path, - show_download_progress) - sublime.status_message('ltex-ls: extracting') + sublime.status_message("ltex-ls: downloading") + urllib.request.urlretrieve( + GITHUB_DL_URL.format(cls.serverversion(), suffix), archive_path + ) + sublime.status_message("ltex-ls: extracting") if suffix.endswith("tar.gz"): archive = tarfile.open(archive_path, "r:gz") elif suffix.endswith(".zip"): @@ -231,23 +182,30 @@ def install_or_update(cls) -> None: raise UnsupportedOperation() archive.extractall(tempdir) archive.close() - shutil.move(os.path.join(tempdir, SERVER_FOLDER_NAME - .format(cls.serverversion())), - cls.basedir()) - sublime.status_message('ltex-ls: installed ltex-ls {}'.format( - cls.serverversion())) + shutil.move( + os.path.join(tempdir, SERVER_FOLDER_NAME.format(cls.serverversion())), + cls.basedir(), + ) + sublime.status_message( + "ltex-ls: installed ltex-ls {}".format(cls.serverversion()) + ) @classmethod - def can_start(cls, window: sublime.Window, initiating_view: sublime.View, - workspace_folders: List[WorkspaceFolder], - configuration: ClientConfig) -> Optional[str]: + def can_start( + cls, + window: sublime.Window, + initiating_view: sublime.View, + workspace_folders: List[WorkspaceFolder], + configuration: ClientConfig, + ) -> Optional[str]: if not cls.serverdir(): - return 'Download failed or version could not be determined.' + return "Download failed or version could not be determined." return None # Handle custom commands - def on_pre_server_command(self, command: Mapping[str, Any], - done: Callable[[], None]) -> bool: + def on_pre_server_command( + self, command: Mapping[str, Any], done_callback: Callable[[], None] + ) -> bool: session = self.weaksession() if not session: return False @@ -255,20 +213,23 @@ def on_pre_server_command(self, command: Mapping[str, Any], cmd = command["command"] handled = False if cmd == "_ltex.addToDictionary": - code_action_insert_settings('ltex.dictionary', - command['arguments'][0]['words']) + code_action_insert_settings( + "ltex.dictionary", command["arguments"][0]["words"] + ) handled = True - if cmd == '_ltex.hideFalsePositives': - code_action_insert_settings('ltex.hiddenFalsePositives', - command['arguments'][0]['falsePositives']) # noqa + if cmd == "_ltex.hideFalsePositives": + code_action_insert_settings( + "ltex.hiddenFalsePositives", command["arguments"][0]["falsePositives"] + ) # noqa handled = True - if cmd == '_ltex.disableRules': - code_action_insert_settings('ltex.disabledRules', - command['arguments'][0]['ruleIds']) + if cmd == "_ltex.disableRules": + code_action_insert_settings( + "ltex.disabledRules", command["arguments"][0]["ruleIds"] + ) handled = True if handled: - sublime.set_timeout_async(done) + sublime.set_timeout_async(done_callback) return True return False