From b3c8645c937d2dd98ffbee717f07c3e221c27b1a Mon Sep 17 00:00:00 2001 From: Ellwood Zwovic Date: Mon, 24 Jul 2017 18:47:21 -0700 Subject: [PATCH] Differentiated between user packages and system packages We usually can't uninstall system packages, so display them differently Also fixed some missing `global`s. --- package_manager/__init__.py | 38 +++++++++++++++++++++++++++++++++---- package_manager/utils.py | 15 +++++++++++++++ 2 files changed, 49 insertions(+), 4 deletions(-) create mode 100644 package_manager/utils.py diff --git a/package_manager/__init__.py b/package_manager/__init__.py index 44162b7..b9b018e 100644 --- a/package_manager/__init__.py +++ b/package_manager/__init__.py @@ -87,7 +87,10 @@ class SubprocMixin: def quit(self): """Signals the state machine to stop this operator from running.""" - self.cancel(bpy.context) + try: + self.cancel(bpy.context) + except AttributeError: + pass self._state = 'QUIT' def invoke(self, context, event): @@ -312,7 +315,7 @@ class PACKAGE_OT_uninstall(SubprocMixin, bpy.types.Operator): import pathlib install_path = pathlib.Path(bpy.utils.user_resource('SCRIPTS', 'addons', create=True)) - # TODO: only drawing-related package data should be stored on the panel. Maybe move this to a global..? + global _packages package = _packages[self.package_name].get_latest_version() proc = multiprocessing.Process(target=subproc.uninstall, @@ -364,6 +367,7 @@ class PACKAGE_OT_refresh_packages(bpy.types.Operator): log = logging.getLogger(__name__ + ".PACKAGE_OT_refresh_packages") def execute(self, context): + global _packages installed_packages = get_packages_from_disk(refresh=True) available_packages = get_packages_from_repo() _packages = build_composite_packagelist(installed_packages, available_packages) @@ -443,6 +447,7 @@ class PACKAGE_OT_refresh_repositories(SubprocMixin, bpy.types.Operator): for pkg in available_packages: pkg.repository = result.repository.name + global _packages _packages = build_composite_packagelist(installed_packages, available_packages) self.report({'INFO'}, 'Package list retrieved successfully') @@ -793,7 +798,12 @@ class USERPREF_PT_packages(bpy.types.Panel): right.operator(PACKAGE_OT_uninstall.bl_idname, text="Uninstall").package_name=pkg.name else: - right.label("Installed") + right.scale_y = 2 + if pkg.user: + right.label("Installed") + else: + l = right.label("System package") + right.enabled = False else: if pkg.url: right.operator(PACKAGE_OT_install.bl_idname, @@ -908,6 +918,26 @@ def build_composite_packagelist(installed: list, available: list) -> OrderedDict return pkg1.version == pkg2.version\ and pkg1.files == pkg2.files + def is_user_package(pkg: Package) -> bool: + """Check if package's install location is in user scripts path or preferences scripts path""" + from pathlib import Path + + user_script_path = bpy.utils.script_path_user() + prefs_script_path = bpy.utils.script_path_pref() + + if user_script_path is not None: + in_user = Path(user_script_path) in Path(pkg.installed_location).parents + else: + in_user = False + + if prefs_script_path is not None: + in_prefs = Path(prefs_script_path) in Path(pkg.installed_location).parents + else: + in_prefs = False + + return in_user or in_prefs + + for pkg in available: pkgname = pkg.bl_info['name'] if pkgname in masterlist: @@ -917,9 +947,9 @@ def build_composite_packagelist(installed: list, available: list) -> OrderedDict for pkg in installed: pkg.installed = True + pkg.user = is_user_package(pkg) if pkg.name in masterlist: for masterpkg in masterlist[pkg.name]: - # log.debug("{} and {} equivilent? {}".format((pkg.name, pkg.version), (masterpkg.name, masterpkg.version), packages_are_equivilent(pkg, masterpkg))) if packages_are_equivilent(pkg, masterpkg): masterpkg.installed = True masterpkg.installed_location = pkg.installed_location diff --git a/package_manager/utils.py b/package_manager/utils.py new file mode 100644 index 0000000..4884b66 --- /dev/null +++ b/package_manager/utils.py @@ -0,0 +1,15 @@ +from pathlib import Path + +def parse_repository_url(url: str) -> str: + """Sanitize repository url""" + from urllib.parse import urlsplit, urlunsplit + parsed_url = urlsplit(url) + new_path = parsed_url.path.rstrip("repo.json") + return urlunsplit((parsed_url.scheme, parsed_url.netloc, new_path, parsed_url.query, parsed_url.fragment)) + +def add_repojson_to_url(url: str) -> str: + """Add repo.json to a url""" + from urllib.parse import urlsplit, urlunsplit + parsed_url = urlsplit(url) + new_path = str(Path(parsed_url.path) / "repo.json") + return urlunsplit((parsed_url.scheme, parsed_url.netloc, new_path, parsed_url.query, parsed_url.fragment))