Addon Manager: Renaming and cleanup
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# ***************************************************************************
|
||||
# * *
|
||||
# * Copyright (c) 2021 Chris Hennes <chennes@pioneerlibrarysystem.org> *
|
||||
# * Copyright (c) 2022 FreeCAD Project Association *
|
||||
# * *
|
||||
# * This program is free software; you can redistribute it and/or modify *
|
||||
# * it under the terms of the GNU Lesser General Public License (LGPL) *
|
||||
@@ -33,12 +33,12 @@ import addonmanager_utilities as utils
|
||||
translate = FreeCAD.Qt.translate
|
||||
|
||||
|
||||
class AddonManagerRepo:
|
||||
class Addon:
|
||||
"Encapsulate information about a FreeCAD addon"
|
||||
|
||||
from enum import IntEnum
|
||||
|
||||
class RepoType(IntEnum):
|
||||
class Kind(IntEnum):
|
||||
WORKBENCH = 1
|
||||
MACRO = 2
|
||||
PACKAGE = 3
|
||||
@@ -51,7 +51,7 @@ class AddonManagerRepo:
|
||||
elif self.value == 3:
|
||||
return "Package"
|
||||
|
||||
class UpdateStatus(IntEnum):
|
||||
class Status(IntEnum):
|
||||
NOT_INSTALLED = 0
|
||||
UNCHECKED = 1
|
||||
NO_UPDATE_AVAILABLE = 2
|
||||
@@ -91,7 +91,7 @@ class AddonManagerRepo:
|
||||
def __init__(self, msg):
|
||||
super().__init__(msg)
|
||||
|
||||
def __init__(self, name: str, url: str, status: UpdateStatus, branch: str):
|
||||
def __init__(self, name: str, url: str, status: Status, branch: str):
|
||||
self.name = name.strip()
|
||||
self.display_name = self.name
|
||||
self.url = url.strip()
|
||||
@@ -99,7 +99,7 @@ class AddonManagerRepo:
|
||||
self.python2 = False
|
||||
self.obsolete = False
|
||||
self.rejected = False
|
||||
self.repo_type = AddonManagerRepo.RepoType.WORKBENCH
|
||||
self.repo_type = Addon.Kind.WORKBENCH
|
||||
self.description = None
|
||||
self.tags = set() # Just a cache, loaded from Metadata
|
||||
|
||||
@@ -155,12 +155,12 @@ class AddonManagerRepo:
|
||||
@classmethod
|
||||
def from_macro(self, macro: Macro):
|
||||
if macro.is_installed():
|
||||
status = AddonManagerRepo.UpdateStatus.UNCHECKED
|
||||
status = Addon.Status.UNCHECKED
|
||||
else:
|
||||
status = AddonManagerRepo.UpdateStatus.NOT_INSTALLED
|
||||
instance = AddonManagerRepo(macro.name, macro.url, status, "master")
|
||||
status = Addon.Status.NOT_INSTALLED
|
||||
instance = Addon(macro.name, macro.url, status, "master")
|
||||
instance.macro = macro
|
||||
instance.repo_type = AddonManagerRepo.RepoType.MACRO
|
||||
instance.repo_type = Addon.Kind.MACRO
|
||||
instance.description = macro.desc
|
||||
return instance
|
||||
|
||||
@@ -170,18 +170,18 @@ class AddonManagerRepo:
|
||||
|
||||
mod_dir = os.path.join(FreeCAD.getUserAppDataDir(), "Mod", cache_dict["name"])
|
||||
if os.path.isdir(mod_dir):
|
||||
status = AddonManagerRepo.UpdateStatus.UNCHECKED
|
||||
status = Addon.Status.UNCHECKED
|
||||
else:
|
||||
status = AddonManagerRepo.UpdateStatus.NOT_INSTALLED
|
||||
instance = AddonManagerRepo(
|
||||
status = Addon.Status.NOT_INSTALLED
|
||||
instance = Addon(
|
||||
cache_dict["name"], cache_dict["url"], status, cache_dict["branch"]
|
||||
)
|
||||
|
||||
for key, value in cache_dict.items():
|
||||
instance.__dict__[key] = value
|
||||
|
||||
instance.repo_type = AddonManagerRepo.RepoType(cache_dict["repo_type"])
|
||||
if instance.repo_type == AddonManagerRepo.RepoType.PACKAGE:
|
||||
instance.repo_type = Addon.Kind(cache_dict["repo_type"])
|
||||
if instance.repo_type == Addon.Kind.PACKAGE:
|
||||
# There must be a cached metadata file, too
|
||||
cached_package_xml_file = os.path.join(
|
||||
FreeCAD.getUserCachePath(),
|
||||
@@ -232,7 +232,7 @@ class AddonManagerRepo:
|
||||
def set_metadata(self, metadata: FreeCAD.Metadata) -> None:
|
||||
self.metadata = metadata
|
||||
self.display_name = metadata.Name
|
||||
self.repo_type = AddonManagerRepo.RepoType.PACKAGE
|
||||
self.repo_type = Addon.Kind.PACKAGE
|
||||
self.description = metadata.Description
|
||||
for url in metadata.Urls:
|
||||
if "type" in url and url["type"] == "repository":
|
||||
@@ -277,9 +277,9 @@ class AddonManagerRepo:
|
||||
def contains_workbench(self) -> bool:
|
||||
"""Determine if this package contains (or is) a workbench"""
|
||||
|
||||
if self.repo_type == AddonManagerRepo.RepoType.WORKBENCH:
|
||||
if self.repo_type == Addon.Kind.WORKBENCH:
|
||||
return True
|
||||
elif self.repo_type == AddonManagerRepo.RepoType.PACKAGE:
|
||||
elif self.repo_type == Addon.Kind.PACKAGE:
|
||||
if self.metadata is None:
|
||||
FreeCAD.Console.PrintWarning(
|
||||
f"Addon Manager internal error: lost metadata for package {self.name}\n"
|
||||
@@ -298,9 +298,9 @@ class AddonManagerRepo:
|
||||
def contains_macro(self) -> bool:
|
||||
"""Determine if this package contains (or is) a macro"""
|
||||
|
||||
if self.repo_type == AddonManagerRepo.RepoType.MACRO:
|
||||
if self.repo_type == Addon.Kind.MACRO:
|
||||
return True
|
||||
elif self.repo_type == AddonManagerRepo.RepoType.PACKAGE:
|
||||
elif self.repo_type == Addon.Kind.PACKAGE:
|
||||
if self.metadata is None:
|
||||
FreeCAD.Console.PrintWarning(
|
||||
f"Addon Manager internal error: lost metadata for package {self.name}\n"
|
||||
@@ -314,7 +314,7 @@ class AddonManagerRepo:
|
||||
def contains_preference_pack(self) -> bool:
|
||||
"""Determine if this package contains a preference pack"""
|
||||
|
||||
if self.repo_type == AddonManagerRepo.RepoType.PACKAGE:
|
||||
if self.repo_type == Addon.Kind.PACKAGE:
|
||||
if self.metadata is None:
|
||||
FreeCAD.Console.PrintWarning(
|
||||
f"Addon Manager internal error: lost metadata for package {self.name}\n"
|
||||
@@ -4,7 +4,7 @@
|
||||
# ***************************************************************************
|
||||
# * *
|
||||
# * Copyright (c) 2015 Yorik van Havre <yorik@uncreated.net> *
|
||||
# * Copyright (c) 2021 Chris Hennes <chennes@pioneerlibrarysystem.org> *
|
||||
# * Copyright (c) 2022 FreeCAD Project Association *
|
||||
# * *
|
||||
# * This program is free software; you can redistribute it and/or modify *
|
||||
# * it under the terms of the GNU Lesser General Public License (LGPL) *
|
||||
@@ -40,7 +40,7 @@ import addonmanager_utilities as utils
|
||||
import AddonManager_rc
|
||||
from package_list import PackageList, PackageListItemModel
|
||||
from package_details import PackageDetails
|
||||
from AddonManagerRepo import AddonManagerRepo
|
||||
from Addon import Addon
|
||||
from install_to_toolbar import (
|
||||
ask_to_install_toolbar_button,
|
||||
remove_custom_toolbar_button,
|
||||
@@ -496,7 +496,7 @@ class CommandAddonManager:
|
||||
# Write the cache data if it's safe to do so:
|
||||
if not worker_killed:
|
||||
for repo in self.item_model.repos:
|
||||
if repo.repo_type == AddonManagerRepo.RepoType.MACRO:
|
||||
if repo.repo_type == Addon.Kind.MACRO:
|
||||
self.cache_macro(repo)
|
||||
else:
|
||||
self.cache_package(repo)
|
||||
@@ -633,7 +633,7 @@ class CommandAddonManager:
|
||||
) # Link to step 2
|
||||
self.update_worker.start()
|
||||
|
||||
def cache_package(self, repo: AddonManagerRepo):
|
||||
def cache_package(self, repo: Addon):
|
||||
if not hasattr(self, "package_cache"):
|
||||
self.package_cache = {}
|
||||
self.package_cache[repo.name] = repo.to_cache()
|
||||
@@ -671,7 +671,7 @@ class CommandAddonManager:
|
||||
self.macro_worker.finished.connect(self.do_next_startup_phase)
|
||||
self.macro_worker.start()
|
||||
|
||||
def cache_macro(self, repo: AddonManagerRepo):
|
||||
def cache_macro(self, repo: Addon):
|
||||
if not hasattr(self, "macro_cache"):
|
||||
self.macro_cache = []
|
||||
if repo.macro is not None:
|
||||
@@ -724,7 +724,7 @@ class CommandAddonManager:
|
||||
)
|
||||
self.startup()
|
||||
|
||||
def on_package_updated(self, repo: AddonManagerRepo) -> None:
|
||||
def on_package_updated(self, repo: Addon) -> None:
|
||||
"""Called when the named package has either new metadata or a new icon (or both)"""
|
||||
|
||||
with self.lock:
|
||||
@@ -788,12 +788,12 @@ class CommandAddonManager:
|
||||
self.check_worker.start()
|
||||
self.enable_updates(len(self.packages_with_updates))
|
||||
|
||||
def status_updated(self, repo: AddonManagerRepo) -> None:
|
||||
def status_updated(self, repo: Addon) -> None:
|
||||
self.item_model.reload_item(repo)
|
||||
if repo.status() == AddonManagerRepo.UpdateStatus.UPDATE_AVAILABLE:
|
||||
if repo.status() == Addon.Status.UPDATE_AVAILABLE:
|
||||
self.packages_with_updates.append(repo)
|
||||
self.enable_updates(len(self.packages_with_updates))
|
||||
elif repo.status() == AddonManagerRepo.UpdateStatus.PENDING_RESTART:
|
||||
elif repo.status() == Addon.Status.PENDING_RESTART:
|
||||
self.restart_required = True
|
||||
|
||||
def enable_updates(self, number_of_updates: int) -> None:
|
||||
@@ -819,7 +819,7 @@ class CommandAddonManager:
|
||||
self.enable_updates(len(self.packages_with_updates))
|
||||
self.dialog.buttonCheckForUpdates.setEnabled(True)
|
||||
|
||||
def add_addon_repo(self, addon_repo: AddonManagerRepo) -> None:
|
||||
def add_addon_repo(self, addon_repo: Addon) -> None:
|
||||
"""adds a workbench to the list"""
|
||||
|
||||
if addon_repo.icon is None or addon_repo.icon.isNull():
|
||||
@@ -832,17 +832,17 @@ class CommandAddonManager:
|
||||
return
|
||||
self.item_model.append_item(addon_repo)
|
||||
|
||||
def get_icon(self, repo: AddonManagerRepo, update: bool = False) -> QtGui.QIcon:
|
||||
def get_icon(self, repo: Addon, update: bool = False) -> QtGui.QIcon:
|
||||
"""returns an icon for a repo"""
|
||||
|
||||
if not update and repo.icon and not repo.icon.isNull() and repo.icon.isValid():
|
||||
return repo.icon
|
||||
|
||||
path = ":/icons/" + repo.name.replace(" ", "_")
|
||||
if repo.repo_type == AddonManagerRepo.RepoType.WORKBENCH:
|
||||
if repo.repo_type == Addon.Kind.WORKBENCH:
|
||||
path += "_workbench_icon.svg"
|
||||
default_icon = QtGui.QIcon(":/icons/document-package.svg")
|
||||
elif repo.repo_type == AddonManagerRepo.RepoType.MACRO:
|
||||
elif repo.repo_type == Addon.Kind.MACRO:
|
||||
if repo.macro and repo.macro.icon:
|
||||
if os.path.isabs(repo.macro.icon):
|
||||
path = repo.macro.icon
|
||||
@@ -864,7 +864,7 @@ class CommandAddonManager:
|
||||
else:
|
||||
path += "_macro_icon.svg"
|
||||
default_icon = QtGui.QIcon(":/icons/document-python.svg")
|
||||
elif repo.repo_type == AddonManagerRepo.RepoType.PACKAGE:
|
||||
elif repo.repo_type == Addon.Kind.PACKAGE:
|
||||
# The cache might not have been downloaded yet, check to see if it's there...
|
||||
if os.path.isfile(repo.get_cached_icon_filename()):
|
||||
path = repo.get_cached_icon_filename()
|
||||
@@ -885,7 +885,7 @@ class CommandAddonManager:
|
||||
|
||||
return addonicon
|
||||
|
||||
def table_row_activated(self, selected_repo: AddonManagerRepo) -> None:
|
||||
def table_row_activated(self, selected_repo: Addon) -> None:
|
||||
"""a row was activated, show the relevant data"""
|
||||
|
||||
self.packageList.hide()
|
||||
@@ -898,7 +898,7 @@ class CommandAddonManager:
|
||||
self.dialog.labelStatusInfo.setText(message)
|
||||
self.dialog.labelStatusInfo.repaint()
|
||||
|
||||
def show_workbench(self, repo: AddonManagerRepo) -> None:
|
||||
def show_workbench(self, repo: Addon) -> None:
|
||||
self.packageList.hide()
|
||||
self.packageDetails.show()
|
||||
self.packageDetails.show_repo(repo)
|
||||
@@ -907,16 +907,16 @@ class CommandAddonManager:
|
||||
self.packageDetails.hide()
|
||||
self.packageList.show()
|
||||
|
||||
def append_to_repos_list(self, repo: AddonManagerRepo) -> None:
|
||||
def append_to_repos_list(self, repo: Addon) -> None:
|
||||
"""this function allows threads to update the main list of workbenches"""
|
||||
|
||||
self.item_model.append_item(repo)
|
||||
|
||||
def resolve_dependencies(self, repo: AddonManagerRepo) -> None:
|
||||
def resolve_dependencies(self, repo: Addon) -> None:
|
||||
if not repo:
|
||||
return
|
||||
|
||||
deps = AddonManagerRepo.Dependencies()
|
||||
deps = Addon.Dependencies()
|
||||
repo_name_dict = dict()
|
||||
for r in self.item_model.repos:
|
||||
repo_name_dict[repo.name] = r
|
||||
@@ -941,7 +941,7 @@ class CommandAddonManager:
|
||||
|
||||
missing_external_addons = []
|
||||
for dep in deps.required_external_addons:
|
||||
if dep.status() == AddonManagerRepo.UpdateStatus.NOT_INSTALLED:
|
||||
if dep.status() == Addon.Status.NOT_INSTALLED:
|
||||
missing_external_addons.append(dep)
|
||||
|
||||
# Now check the loaded addons to see if we are missing an internal workbench:
|
||||
@@ -1069,7 +1069,7 @@ class CommandAddonManager:
|
||||
else:
|
||||
self.install(repo)
|
||||
|
||||
def dependency_dialog_yes_clicked(self, repo: AddonManagerRepo) -> None:
|
||||
def dependency_dialog_yes_clicked(self, repo: Addon) -> None:
|
||||
# Get the lists out of the dialog:
|
||||
addons = []
|
||||
for row in range(self.dependency_dialog.listWidgetAddons.count()):
|
||||
@@ -1116,7 +1116,7 @@ class CommandAddonManager:
|
||||
self.dependency_installation_dialog.show()
|
||||
self.dependency_installation_worker.start()
|
||||
|
||||
def no_python_exe(self, repo: AddonManagerRepo) -> None:
|
||||
def no_python_exe(self, repo: Addon) -> None:
|
||||
if hasattr(self, "dependency_installation_dialog"):
|
||||
self.dependency_installation_dialog.hide()
|
||||
result = QtWidgets.QMessageBox.critical(
|
||||
@@ -1136,7 +1136,7 @@ class CommandAddonManager:
|
||||
if result == QtWidgets.QMessageBox.Yes:
|
||||
self.install(repo)
|
||||
|
||||
def no_pip(self, command: str, repo: AddonManagerRepo) -> None:
|
||||
def no_pip(self, command: str, repo: Addon) -> None:
|
||||
if hasattr(self, "dependency_installation_dialog"):
|
||||
self.dependency_installation_dialog.hide()
|
||||
result = QtWidgets.QMessageBox.critical(
|
||||
@@ -1169,7 +1169,7 @@ class CommandAddonManager:
|
||||
QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No,
|
||||
)
|
||||
|
||||
def dependency_dialog_ignore_clicked(self, repo: AddonManagerRepo) -> None:
|
||||
def dependency_dialog_ignore_clicked(self, repo: Addon) -> None:
|
||||
self.install(repo)
|
||||
|
||||
def cancel_dependency_installation(self) -> None:
|
||||
@@ -1177,7 +1177,7 @@ class CommandAddonManager:
|
||||
self.dependency_installation_worker.requestInterruption()
|
||||
self.dependency_installation_dialog.hide()
|
||||
|
||||
def install(self, repo: AddonManagerRepo) -> None:
|
||||
def install(self, repo: Addon) -> None:
|
||||
"""installs or updates a workbench, macro, or package"""
|
||||
|
||||
if hasattr(self, "install_worker") and self.install_worker:
|
||||
@@ -1191,8 +1191,8 @@ class CommandAddonManager:
|
||||
return
|
||||
|
||||
if (
|
||||
repo.repo_type == AddonManagerRepo.RepoType.WORKBENCH
|
||||
or repo.repo_type == AddonManagerRepo.RepoType.PACKAGE
|
||||
repo.repo_type == Addon.Kind.WORKBENCH
|
||||
or repo.repo_type == Addon.Kind.PACKAGE
|
||||
):
|
||||
self.show_progress_widgets()
|
||||
self.install_worker = InstallWorkbenchWorker(repo)
|
||||
@@ -1203,7 +1203,7 @@ class CommandAddonManager:
|
||||
self.install_worker.success.connect(self.on_package_installed)
|
||||
self.install_worker.failure.connect(self.on_installation_failed)
|
||||
self.install_worker.start()
|
||||
elif repo.repo_type == AddonManagerRepo.RepoType.MACRO:
|
||||
elif repo.repo_type == Addon.Kind.MACRO:
|
||||
macro = repo.macro
|
||||
|
||||
# To try to ensure atomicity, test the installation into a temp directory first,
|
||||
@@ -1238,16 +1238,14 @@ class CommandAddonManager:
|
||||
message += error
|
||||
self.on_installation_failed(repo, message)
|
||||
|
||||
def update(self, repo: AddonManagerRepo) -> None:
|
||||
def update(self, repo: Addon) -> None:
|
||||
self.install(repo)
|
||||
|
||||
def mark_repo_update_available(
|
||||
self, repo: AddonManagerRepo, available: bool
|
||||
) -> None:
|
||||
def mark_repo_update_available(self, repo: Addon, available: bool) -> None:
|
||||
if available:
|
||||
repo.set_status(AddonManagerRepo.UpdateStatus.UPDATE_AVAILABLE)
|
||||
repo.set_status(Addon.Status.UPDATE_AVAILABLE)
|
||||
else:
|
||||
repo.set_status(AddonManagerRepo.UpdateStatus.NO_UPDATE_AVAILABLE)
|
||||
repo.set_status(Addon.Status.NO_UPDATE_AVAILABLE)
|
||||
self.item_model.reload_item(repo)
|
||||
self.packageDetails.show_repo(repo)
|
||||
|
||||
@@ -1279,9 +1277,7 @@ class CommandAddonManager:
|
||||
def on_update_all_completed(self) -> None:
|
||||
self.hide_progress_widgets()
|
||||
|
||||
def get_package_list(
|
||||
message: str, repos: List[AddonManagerRepo], threshold: int
|
||||
):
|
||||
def get_package_list(message: str, repos: List[Addon], threshold: int):
|
||||
"""To ensure that the list doesn't get too long for the dialog, cut it off at some threshold"""
|
||||
num_updates = len(repos)
|
||||
if num_updates < threshold:
|
||||
@@ -1339,11 +1335,9 @@ class CommandAddonManager:
|
||||
for installed_repo in self.subupdates_succeeded:
|
||||
if installed_repo.contains_workbench():
|
||||
self.restart_required = True
|
||||
installed_repo.set_status(AddonManagerRepo.UpdateStatus.PENDING_RESTART)
|
||||
installed_repo.set_status(Addon.Status.PENDING_RESTART)
|
||||
else:
|
||||
installed_repo.set_status(
|
||||
AddonManagerRepo.UpdateStatus.NO_UPDATE_AVAILABLE
|
||||
)
|
||||
installed_repo.set_status(Addon.Status.NO_UPDATE_AVAILABLE)
|
||||
self.item_model.reload_item(installed_repo)
|
||||
for requested_repo in self.packages_with_updates:
|
||||
if installed_repo.name == requested_repo.name:
|
||||
@@ -1407,7 +1401,7 @@ class CommandAddonManager:
|
||||
"AddonManager recaches."
|
||||
)
|
||||
|
||||
def on_package_installed(self, repo: AddonManagerRepo, message: str) -> None:
|
||||
def on_package_installed(self, repo: Addon, message: str) -> None:
|
||||
self.hide_progress_widgets()
|
||||
QtWidgets.QMessageBox.information(
|
||||
None,
|
||||
@@ -1416,16 +1410,16 @@ class CommandAddonManager:
|
||||
QtWidgets.QMessageBox.Close,
|
||||
)
|
||||
if repo.contains_workbench():
|
||||
repo.set_status(AddonManagerRepo.UpdateStatus.PENDING_RESTART)
|
||||
repo.set_status(Addon.Status.PENDING_RESTART)
|
||||
self.restart_required = True
|
||||
else:
|
||||
repo.set_status(AddonManagerRepo.UpdateStatus.NO_UPDATE_AVAILABLE)
|
||||
repo.set_status(Addon.Status.NO_UPDATE_AVAILABLE)
|
||||
self.item_model.reload_item(repo)
|
||||
self.packageDetails.show_repo(repo)
|
||||
if repo.repo_type == AddonManagerRepo.RepoType.MACRO:
|
||||
if repo.repo_type == Addon.Kind.MACRO:
|
||||
ask_to_install_toolbar_button(repo)
|
||||
|
||||
def on_installation_failed(self, _: AddonManagerRepo, message: str) -> None:
|
||||
def on_installation_failed(self, _: Addon, message: str) -> None:
|
||||
self.hide_progress_widgets()
|
||||
QtWidgets.QMessageBox.warning(
|
||||
None,
|
||||
@@ -1434,7 +1428,7 @@ class CommandAddonManager:
|
||||
QtWidgets.QMessageBox.Close,
|
||||
)
|
||||
|
||||
def executemacro(self, repo: AddonManagerRepo) -> None:
|
||||
def executemacro(self, repo: Addon) -> None:
|
||||
"""executes a selected macro"""
|
||||
|
||||
macro = repo.macro
|
||||
@@ -1468,7 +1462,7 @@ class CommandAddonManager:
|
||||
os.chmod(path, stat.S_IWRITE)
|
||||
func(path)
|
||||
|
||||
def remove(self, repo: AddonManagerRepo) -> None:
|
||||
def remove(self, repo: Addon) -> None:
|
||||
"""uninstalls a macro or workbench"""
|
||||
|
||||
confirm = QtWidgets.QMessageBox.question(
|
||||
@@ -1483,8 +1477,8 @@ class CommandAddonManager:
|
||||
return
|
||||
|
||||
if (
|
||||
repo.repo_type == AddonManagerRepo.RepoType.WORKBENCH
|
||||
or repo.repo_type == AddonManagerRepo.RepoType.PACKAGE
|
||||
repo.repo_type == Addon.Kind.WORKBENCH
|
||||
or repo.repo_type == Addon.Kind.PACKAGE
|
||||
):
|
||||
basedir = FreeCAD.getUserAppDataDir()
|
||||
moddir = basedir + os.sep + "Mod"
|
||||
@@ -1535,7 +1529,7 @@ class CommandAddonManager:
|
||||
if os.path.exists(clonedir):
|
||||
shutil.rmtree(clonedir, onerror=self.remove_readonly)
|
||||
self.item_model.update_item_status(
|
||||
repo.name, AddonManagerRepo.UpdateStatus.NOT_INSTALLED
|
||||
repo.name, Addon.Status.NOT_INSTALLED
|
||||
)
|
||||
if repo.contains_workbench():
|
||||
self.restart_required = True
|
||||
@@ -1548,7 +1542,7 @@ class CommandAddonManager:
|
||||
)
|
||||
)
|
||||
|
||||
elif repo.repo_type == AddonManagerRepo.RepoType.MACRO:
|
||||
elif repo.repo_type == Addon.Kind.MACRO:
|
||||
macro = repo.macro
|
||||
if macro.remove():
|
||||
remove_custom_toolbar_button(repo)
|
||||
@@ -1559,7 +1553,7 @@ class CommandAddonManager:
|
||||
+ "\n"
|
||||
)
|
||||
self.item_model.update_item_status(
|
||||
repo.name, AddonManagerRepo.UpdateStatus.NOT_INSTALLED
|
||||
repo.name, Addon.Status.NOT_INSTALLED
|
||||
)
|
||||
self.packageDetails.show_repo(repo)
|
||||
else:
|
||||
|
||||
@@ -26,7 +26,7 @@ import unittest
|
||||
import os
|
||||
import FreeCAD
|
||||
|
||||
from AddonManagerRepo import AddonManagerRepo
|
||||
from Addon import Addon
|
||||
|
||||
from addonmanager_utilities import (
|
||||
recognized_git_location,
|
||||
@@ -51,8 +51,8 @@ class TestUtilities(unittest.TestCase):
|
||||
"https://salsa.debian.org/science-team/freecad",
|
||||
]
|
||||
for url in recognized_urls:
|
||||
repo = AddonManagerRepo(
|
||||
"Test Repo", url, AddonManagerRepo.UpdateStatus.NOT_INSTALLED, "branch"
|
||||
repo = Addon(
|
||||
"Test Repo", url, Addon.Status.NOT_INSTALLED, "branch"
|
||||
)
|
||||
self.assertTrue(
|
||||
recognized_git_location(repo), f"{url} was unexpectedly not recognized"
|
||||
@@ -65,8 +65,8 @@ class TestUtilities(unittest.TestCase):
|
||||
"https://github.com.malware.com/",
|
||||
]
|
||||
for url in unrecognized_urls:
|
||||
repo = AddonManagerRepo(
|
||||
"Test Repo", url, AddonManagerRepo.UpdateStatus.NOT_INSTALLED, "branch"
|
||||
repo = Addon(
|
||||
"Test Repo", url, Addon.Status.NOT_INSTALLED, "branch"
|
||||
)
|
||||
self.assertFalse(
|
||||
recognized_git_location(repo), f"{url} was unexpectedly recognized"
|
||||
@@ -90,8 +90,8 @@ class TestUtilities(unittest.TestCase):
|
||||
for url in github_urls:
|
||||
branch = "branchname"
|
||||
expected_result = f"{url}/raw/{branch}/README.md"
|
||||
repo = AddonManagerRepo(
|
||||
"Test Repo", url, AddonManagerRepo.UpdateStatus.NOT_INSTALLED, branch
|
||||
repo = Addon(
|
||||
"Test Repo", url, Addon.Status.NOT_INSTALLED, branch
|
||||
)
|
||||
actual_result = get_readme_url(repo)
|
||||
self.assertEqual(actual_result, expected_result)
|
||||
@@ -99,8 +99,8 @@ class TestUtilities(unittest.TestCase):
|
||||
for url in gitlab_urls:
|
||||
branch = "branchname"
|
||||
expected_result = f"{url}/-/raw/{branch}/README.md"
|
||||
repo = AddonManagerRepo(
|
||||
"Test Repo", url, AddonManagerRepo.UpdateStatus.NOT_INSTALLED, branch
|
||||
repo = Addon(
|
||||
"Test Repo", url, Addon.Status.NOT_INSTALLED, branch
|
||||
)
|
||||
actual_result = get_readme_url(repo)
|
||||
self.assertEqual(actual_result, expected_result)
|
||||
|
||||
@@ -4,13 +4,13 @@ ENDIF (BUILD_GUI)
|
||||
|
||||
SET(AddonManager_SRCS
|
||||
add_toolbar_button_dialog.ui
|
||||
Addon.py
|
||||
AddonManager.py
|
||||
AddonManager.ui
|
||||
addonmanager_macro.py
|
||||
addonmanager_utilities.py
|
||||
addonmanager_workers.py
|
||||
AddonManagerOptions.ui
|
||||
AddonManagerRepo.py
|
||||
ALLOWED_PYTHON_PACKAGES.txt
|
||||
change_branch.py
|
||||
change_branch.ui
|
||||
|
||||
@@ -4,4 +4,5 @@
|
||||
# License LGPL
|
||||
|
||||
import FreeCAD
|
||||
FreeCAD.__unit_test__ += ["TestAddonManagerApp"]
|
||||
|
||||
FreeCAD.__unit_test__ += ["TestAddonManagerApp"]
|
||||
|
||||
@@ -9,4 +9,5 @@ FreeCADGui.addLanguagePath(":/translations")
|
||||
FreeCADGui.addCommand("Std_AddonMgr", AddonManager.CommandAddonManager())
|
||||
|
||||
import FreeCAD
|
||||
FreeCAD.__unit_test__ += ["TestAddonManagerGui"]
|
||||
|
||||
FreeCAD.__unit_test__ += ["TestAddonManagerGui"]
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
# ***************************************************************************
|
||||
# * *
|
||||
# * Copyright (c) 2022 Chris Hennes <chennes@pioneerlibrarysystem.org> *
|
||||
# * Copyright (c) 2022 FreeCAD Project Association *
|
||||
# * *
|
||||
# * This program is free software; you can redistribute it and/or modify *
|
||||
# * it under the terms of the GNU Lesser General Public License (LGPL) *
|
||||
@@ -163,7 +163,7 @@ if HAVE_QTNETWORK:
|
||||
self.diskCache.setCacheDirectory(qnam_cache)
|
||||
self.QNAM.setCache(self.diskCache)
|
||||
|
||||
self.monitored_connections:List[int] = []
|
||||
self.monitored_connections: List[int] = []
|
||||
|
||||
# Set up the proxy, if necesssary:
|
||||
noProxyCheck = True
|
||||
@@ -269,7 +269,9 @@ if HAVE_QTNETWORK:
|
||||
except queue.Empty:
|
||||
pass
|
||||
|
||||
def __launch_request(self, index:int, request:QtNetwork.QNetworkRequest) -> None:
|
||||
def __launch_request(
|
||||
self, index: int, request: QtNetwork.QNetworkRequest
|
||||
) -> None:
|
||||
reply = self.QNAM.get(request)
|
||||
self.replies[index] = reply
|
||||
|
||||
@@ -281,7 +283,6 @@ if HAVE_QTNETWORK:
|
||||
reply.readyRead.connect(self.__ready_to_read)
|
||||
reply.downloadProgress.connect(self.__download_progress)
|
||||
|
||||
|
||||
def submit_unmonitored_get(self, url: str) -> int:
|
||||
"""Adds this request to the queue, and returns an index that can be used by calling code
|
||||
in conjunction with the completed() signal to handle the results of the call. All data is
|
||||
@@ -437,7 +438,7 @@ if HAVE_QTNETWORK:
|
||||
def __follow_redirect(self, url):
|
||||
sender = self.sender()
|
||||
if sender:
|
||||
for index,reply in self.replies.items():
|
||||
for index, reply in self.replies.items():
|
||||
if reply == sender:
|
||||
current_index = index
|
||||
break
|
||||
@@ -459,11 +460,11 @@ if HAVE_QTNETWORK:
|
||||
for error in errors:
|
||||
print(error)
|
||||
|
||||
def __download_progress(self, bytesReceived:int, bytesTotal:int) -> None:
|
||||
def __download_progress(self, bytesReceived: int, bytesTotal: int) -> None:
|
||||
sender = self.sender()
|
||||
if not sender:
|
||||
return
|
||||
for index,reply in self.replies.items():
|
||||
for index, reply in self.replies.items():
|
||||
if reply == sender:
|
||||
self.progress_made.emit(index, bytesReceived, bytesTotal)
|
||||
return
|
||||
@@ -473,12 +474,12 @@ if HAVE_QTNETWORK:
|
||||
if not sender:
|
||||
return
|
||||
|
||||
for index,reply in self.replies.items():
|
||||
for index, reply in self.replies.items():
|
||||
if reply == sender:
|
||||
self.__data_incoming(index, reply)
|
||||
return
|
||||
|
||||
def __data_incoming(self, index: int, reply:QtNetwork.QNetworkReply) -> None:
|
||||
def __data_incoming(self, index: int, reply: QtNetwork.QNetworkReply) -> None:
|
||||
if not index in self.replies:
|
||||
# We already finished this reply, this is a vestigial signal
|
||||
return
|
||||
@@ -492,28 +493,34 @@ if HAVE_QTNETWORK:
|
||||
f.write(buffer.data())
|
||||
except Exception as e:
|
||||
if HAVE_FREECAD:
|
||||
FreeCAD.Console.PrintError(f"Network Manager internal error: {str(e)}")
|
||||
FreeCAD.Console.PrintError(
|
||||
f"Network Manager internal error: {str(e)}"
|
||||
)
|
||||
else:
|
||||
print (f"Network Manager internal error: {str(e)}")
|
||||
|
||||
print(f"Network Manager internal error: {str(e)}")
|
||||
|
||||
def __reply_finished(self) -> None:
|
||||
reply = self.sender()
|
||||
if not reply:
|
||||
print ("Network Manager Error: __reply_finished not called by a Qt signal")
|
||||
print(
|
||||
"Network Manager Error: __reply_finished not called by a Qt signal"
|
||||
)
|
||||
return
|
||||
|
||||
if reply.error() == QtNetwork.QNetworkReply.NetworkError.OperationCanceledError:
|
||||
if (
|
||||
reply.error()
|
||||
== QtNetwork.QNetworkReply.NetworkError.OperationCanceledError
|
||||
):
|
||||
# Silently do nothing
|
||||
return
|
||||
|
||||
index = None
|
||||
for key,value in self.replies.items():
|
||||
for key, value in self.replies.items():
|
||||
if reply == value:
|
||||
index = key
|
||||
break
|
||||
if index is None:
|
||||
print (f"Lost net request for {reply.url()}")
|
||||
print(f"Lost net request for {reply.url()}")
|
||||
return
|
||||
|
||||
response_code = reply.attribute(
|
||||
@@ -522,7 +529,7 @@ if HAVE_QTNETWORK:
|
||||
self.queue.task_done()
|
||||
if reply.error() == QtNetwork.QNetworkReply.NetworkError.NoError:
|
||||
if index in self.monitored_connections:
|
||||
# Make sure to read any remaining data
|
||||
# Make sure to read any remaining data
|
||||
self.__data_incoming(index, reply)
|
||||
self.monitored_connections.remove(index)
|
||||
f = self.file_buffers[index]
|
||||
|
||||
@@ -23,7 +23,9 @@
|
||||
# ***************************************************************************
|
||||
|
||||
# Unit test for the Addon Manager module
|
||||
from AddonManagerTest.app.test_utilities import TestUtilities as AddonManagerTestUtilities
|
||||
from AddonManagerTest.app.test_utilities import (
|
||||
TestUtilities as AddonManagerTestUtilities,
|
||||
)
|
||||
|
||||
# dummy usage to get flake8 and lgtm quiet
|
||||
False if AddonManagerTestUtilities.__name__ else True
|
||||
|
||||
@@ -276,13 +276,13 @@ def attention_color_string() -> str:
|
||||
return "rgb(255,179,64)" if is_darkmode() else "rgb(255,149,0)"
|
||||
|
||||
|
||||
def get_assigned_string_literal(line:str) -> Optional[str]:
|
||||
def get_assigned_string_literal(line: str) -> Optional[str]:
|
||||
"""Look for a line of the form my_var = "A string literal" and return the string literal.
|
||||
If the assignment is of a floating point value, that value is converted to a string
|
||||
and returned. If neither is true, returns None."""
|
||||
|
||||
string_search_regex = re.compile(r"\s*(['\"])(.*)\1")
|
||||
_,_,after_equals = line.partition("=")
|
||||
_, _, after_equals = line.partition("=")
|
||||
match = re.match(string_search_regex, after_equals)
|
||||
if match:
|
||||
return str(match.group(2))
|
||||
@@ -290,9 +290,10 @@ def get_assigned_string_literal(line:str) -> Optional[str]:
|
||||
return str(after_equals).strip()
|
||||
return None
|
||||
|
||||
|
||||
def get_macro_version_from_file(filename: str) -> str:
|
||||
""" Get the version of the macro from a local macro file. Supports strings, ints, and floats, as
|
||||
well as a reference to __date__ """
|
||||
"""Get the version of the macro from a local macro file. Supports strings, ints, and floats, as
|
||||
well as a reference to __date__"""
|
||||
|
||||
date = ""
|
||||
with open(filename, "r", errors="ignore") as f:
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# ***************************************************************************
|
||||
# * *
|
||||
# * Copyright (c) 2019 Yorik van Havre <yorik@uncreated.net> *
|
||||
# * Copyright (c) 2021 Chris Hennes <chennes@pioneerlibrarysystem.org> *
|
||||
# * Copyright (c) 2022 FreeCAD Project Association *
|
||||
# * *
|
||||
# * This program is free software; you can redistribute it and/or modify *
|
||||
# * it under the terms of the GNU Lesser General Public License (LGPL) *
|
||||
@@ -51,7 +51,7 @@ if FreeCAD.GuiUp:
|
||||
import addonmanager_utilities as utils
|
||||
from addonmanager_macro import Macro
|
||||
|
||||
from AddonManagerRepo import AddonManagerRepo
|
||||
from Addon import Addon
|
||||
import NetworkManager
|
||||
|
||||
translate = FreeCAD.Qt.translate
|
||||
@@ -239,10 +239,10 @@ class UpdateWorker(QtCore.QThread):
|
||||
package_names.append(name)
|
||||
addondir = moddir + os.sep + name
|
||||
if os.path.exists(addondir) and os.listdir(addondir):
|
||||
state = AddonManagerRepo.UpdateStatus.UNCHECKED
|
||||
state = Addon.Status.UNCHECKED
|
||||
else:
|
||||
state = AddonManagerRepo.UpdateStatus.NOT_INSTALLED
|
||||
repo = AddonManagerRepo(name, addon["url"], state, addon["branch"])
|
||||
state = Addon.Status.NOT_INSTALLED
|
||||
repo = Addon(name, addon["url"], state, addon["branch"])
|
||||
md_file = os.path.join(addondir, "package.xml")
|
||||
if os.path.isfile(md_file):
|
||||
repo.load_metadata_file(md_file)
|
||||
@@ -281,10 +281,10 @@ class UpdateWorker(QtCore.QThread):
|
||||
addondir = moddir + os.sep + name
|
||||
if os.path.exists(addondir) and os.listdir(addondir):
|
||||
# make sure the folder exists and it contains files!
|
||||
state = AddonManagerRepo.UpdateStatus.UNCHECKED
|
||||
state = Addon.Status.UNCHECKED
|
||||
else:
|
||||
state = AddonManagerRepo.UpdateStatus.NOT_INSTALLED
|
||||
repo = AddonManagerRepo(name, url, state, branch)
|
||||
state = Addon.Status.NOT_INSTALLED
|
||||
repo = Addon(name, url, state, branch)
|
||||
md_file = os.path.join(addondir, "package.xml")
|
||||
if os.path.isfile(md_file):
|
||||
repo.load_metadata_file(md_file)
|
||||
@@ -323,7 +323,7 @@ class LoadPackagesFromCacheWorker(QtCore.QThread):
|
||||
for item in dict_data.values():
|
||||
if QtCore.QThread.currentThread().isInterruptionRequested():
|
||||
return
|
||||
repo = AddonManagerRepo.from_cache(item)
|
||||
repo = Addon.from_cache(item)
|
||||
repo_metadata_cache_path = os.path.join(
|
||||
metadata_cache_path, repo.name, "package.xml"
|
||||
)
|
||||
@@ -357,7 +357,7 @@ class LoadMacrosFromCacheWorker(QtCore.QThread):
|
||||
if QtCore.QThread.currentThread().isInterruptionRequested():
|
||||
return
|
||||
new_macro = Macro.from_cache(item)
|
||||
repo = AddonManagerRepo.from_macro(new_macro)
|
||||
repo = Addon.from_macro(new_macro)
|
||||
utils.update_macro_installation_details(repo)
|
||||
self.add_macro_signal.emit(repo)
|
||||
|
||||
@@ -368,18 +368,18 @@ class CheckSingleUpdateWorker(QtCore.QObject):
|
||||
|
||||
update_status = QtCore.Signal(int)
|
||||
|
||||
def __init__(self, repo: AddonManagerRepo, parent: QtCore.QObject = None):
|
||||
def __init__(self, repo: Addon, parent: QtCore.QObject = None):
|
||||
super().__init__(parent)
|
||||
self.repo = repo
|
||||
|
||||
def do_work(self):
|
||||
# Borrow the function from another class:
|
||||
checker = UpdateChecker()
|
||||
if self.repo.repo_type == AddonManagerRepo.RepoType.WORKBENCH:
|
||||
if self.repo.repo_type == Addon.Kind.WORKBENCH:
|
||||
checker.check_workbench(self.repo)
|
||||
elif self.repo.repo_type == AddonManagerRepo.RepoType.MACRO:
|
||||
elif self.repo.repo_type == Addon.Kind.MACRO:
|
||||
checker.check_macro(self.repo)
|
||||
elif self.repo.repo_type == AddonManagerRepo.RepoType.PACKAGE:
|
||||
elif self.repo.repo_type == Addon.Kind.PACKAGE:
|
||||
checker.check_package(self.repo)
|
||||
|
||||
self.update_status.emit(self.repo.update_status)
|
||||
@@ -388,10 +388,10 @@ class CheckSingleUpdateWorker(QtCore.QObject):
|
||||
class CheckWorkbenchesForUpdatesWorker(QtCore.QThread):
|
||||
"""This worker checks for available updates for all workbenches"""
|
||||
|
||||
update_status = QtCore.Signal(AddonManagerRepo)
|
||||
update_status = QtCore.Signal(Addon)
|
||||
progress_made = QtCore.Signal(int, int)
|
||||
|
||||
def __init__(self, repos: List[AddonManagerRepo]):
|
||||
def __init__(self, repos: List[Addon]):
|
||||
|
||||
QtCore.QThread.__init__(self)
|
||||
self.repos = repos
|
||||
@@ -408,14 +408,14 @@ class CheckWorkbenchesForUpdatesWorker(QtCore.QThread):
|
||||
return
|
||||
self.progress_made.emit(count, len(self.repos))
|
||||
count += 1
|
||||
if repo.status() == AddonManagerRepo.UpdateStatus.UNCHECKED:
|
||||
if repo.repo_type == AddonManagerRepo.RepoType.WORKBENCH:
|
||||
if repo.status() == Addon.Status.UNCHECKED:
|
||||
if repo.repo_type == Addon.Kind.WORKBENCH:
|
||||
checker.check_workbench(repo)
|
||||
self.update_status.emit(repo)
|
||||
elif repo.repo_type == AddonManagerRepo.RepoType.MACRO:
|
||||
elif repo.repo_type == Addon.Kind.MACRO:
|
||||
checker.check_macro(repo)
|
||||
self.update_status.emit(repo)
|
||||
elif repo.repo_type == AddonManagerRepo.RepoType.PACKAGE:
|
||||
elif repo.repo_type == Addon.Kind.PACKAGE:
|
||||
checker.check_package(repo)
|
||||
self.update_status.emit(repo)
|
||||
|
||||
@@ -427,7 +427,7 @@ class UpdateChecker:
|
||||
|
||||
def check_workbench(self, wb):
|
||||
if not have_git or NOGIT:
|
||||
wb.set_status(AddonManagerRepo.UpdateStatus.CANNOT_CHECK)
|
||||
wb.set_status(Addon.Status.CANNOT_CHECK)
|
||||
return
|
||||
clonedir = self.moddir + os.sep + wb.name
|
||||
if os.path.exists(clonedir):
|
||||
@@ -441,7 +441,7 @@ class UpdateChecker:
|
||||
if gitrepo.head.is_detached:
|
||||
# By definition, in a detached-head state we cannot
|
||||
# update, so don't even bother checking.
|
||||
wb.set_status(AddonManagerRepo.UpdateStatus.NO_UPDATE_AVAILABLE)
|
||||
wb.set_status(Addon.Status.NO_UPDATE_AVAILABLE)
|
||||
if hasattr(gitrepo.head, "ref"):
|
||||
wb.branch = gitrepo.head.ref.name
|
||||
else:
|
||||
@@ -458,17 +458,13 @@ class UpdateChecker:
|
||||
+ "\n"
|
||||
)
|
||||
FreeCAD.Console.PrintWarning(str(e) + "\n")
|
||||
wb.set_status(AddonManagerRepo.UpdateStatus.CANNOT_CHECK)
|
||||
wb.set_status(Addon.Status.CANNOT_CHECK)
|
||||
else:
|
||||
try:
|
||||
if "git pull" in gitrepo.git.status():
|
||||
wb.set_status(
|
||||
AddonManagerRepo.UpdateStatus.UPDATE_AVAILABLE
|
||||
)
|
||||
wb.set_status(Addon.Status.UPDATE_AVAILABLE)
|
||||
else:
|
||||
wb.set_status(
|
||||
AddonManagerRepo.UpdateStatus.NO_UPDATE_AVAILABLE
|
||||
)
|
||||
wb.set_status(Addon.Status.NO_UPDATE_AVAILABLE)
|
||||
except Exception:
|
||||
FreeCAD.Console.PrintWarning(
|
||||
translate(
|
||||
@@ -476,16 +472,16 @@ class UpdateChecker:
|
||||
).format(wb.name)
|
||||
+ "\n"
|
||||
)
|
||||
wb.set_status(AddonManagerRepo.UpdateStatus.CANNOT_CHECK)
|
||||
wb.set_status(Addon.Status.CANNOT_CHECK)
|
||||
|
||||
def check_package(self, package: AddonManagerRepo) -> None:
|
||||
def check_package(self, package: Addon) -> None:
|
||||
clonedir = self.moddir + os.sep + package.name
|
||||
if os.path.exists(clonedir):
|
||||
|
||||
# First, try to just do a git-based update, which will give the most accurate results:
|
||||
if have_git and not NOGIT:
|
||||
self.check_workbench(package)
|
||||
if package.status() != AddonManagerRepo.UpdateStatus.CANNOT_CHECK:
|
||||
if package.status() != Addon.Status.CANNOT_CHECK:
|
||||
# It worked, just exit now
|
||||
return
|
||||
|
||||
@@ -495,7 +491,7 @@ class UpdateChecker:
|
||||
# If there is no package.xml file, then it's because the package author added it after the last time
|
||||
# the local installation was updated. By definition, then, there is an update available, if only to
|
||||
# download the new XML file.
|
||||
package.set_status(AddonManagerRepo.UpdateStatus.UPDATE_AVAILABLE)
|
||||
package.set_status(Addon.Status.UPDATE_AVAILABLE)
|
||||
package.installed_version = None
|
||||
return
|
||||
else:
|
||||
@@ -506,11 +502,9 @@ class UpdateChecker:
|
||||
# Packages are considered up-to-date if the metadata version matches. Authors should update
|
||||
# their version string when they want the addon manager to alert users of a new version.
|
||||
if package.metadata.Version != installed_metadata.Version:
|
||||
package.set_status(AddonManagerRepo.UpdateStatus.UPDATE_AVAILABLE)
|
||||
package.set_status(Addon.Status.UPDATE_AVAILABLE)
|
||||
else:
|
||||
package.set_status(
|
||||
AddonManagerRepo.UpdateStatus.NO_UPDATE_AVAILABLE
|
||||
)
|
||||
package.set_status(Addon.Status.NO_UPDATE_AVAILABLE)
|
||||
except Exception:
|
||||
FreeCAD.Console.PrintWarning(
|
||||
translate(
|
||||
@@ -519,9 +513,9 @@ class UpdateChecker:
|
||||
).format(name=installed_metadata_file)
|
||||
+ "\n"
|
||||
)
|
||||
package.set_status(AddonManagerRepo.UpdateStatus.CANNOT_CHECK)
|
||||
package.set_status(Addon.Status.CANNOT_CHECK)
|
||||
|
||||
def check_macro(self, macro_wrapper: AddonManagerRepo) -> None:
|
||||
def check_macro(self, macro_wrapper: Addon) -> None:
|
||||
# Make sure this macro has its code downloaded:
|
||||
try:
|
||||
if not macro_wrapper.macro.parsed and macro_wrapper.macro.on_git:
|
||||
@@ -542,7 +536,7 @@ class UpdateChecker:
|
||||
).format(name=macro_wrapper.macro.name)
|
||||
+ "\n"
|
||||
)
|
||||
macro_wrapper.set_status(AddonManagerRepo.UpdateStatus.CANNOT_CHECK)
|
||||
macro_wrapper.set_status(Addon.Status.CANNOT_CHECK)
|
||||
return
|
||||
|
||||
hasher1 = hashlib.sha1()
|
||||
@@ -568,9 +562,9 @@ class UpdateChecker:
|
||||
else:
|
||||
return
|
||||
if new_sha1 == old_sha1:
|
||||
macro_wrapper.set_status(AddonManagerRepo.UpdateStatus.NO_UPDATE_AVAILABLE)
|
||||
macro_wrapper.set_status(Addon.Status.NO_UPDATE_AVAILABLE)
|
||||
else:
|
||||
macro_wrapper.set_status(AddonManagerRepo.UpdateStatus.UPDATE_AVAILABLE)
|
||||
macro_wrapper.set_status(Addon.Status.UPDATE_AVAILABLE)
|
||||
|
||||
|
||||
class FillMacroListWorker(QtCore.QThread):
|
||||
@@ -669,7 +663,7 @@ class FillMacroListWorker(QtCore.QThread):
|
||||
macro = Macro(filename[:-8]) # Remove ".FCMacro".
|
||||
macro.on_git = True
|
||||
macro.src_filename = os.path.join(dirpath, filename)
|
||||
repo = AddonManagerRepo.from_macro(macro)
|
||||
repo = Addon.from_macro(macro)
|
||||
repo.url = "https://github.com/FreeCAD/FreeCAD-macros.git"
|
||||
utils.update_macro_installation_details(repo)
|
||||
self.add_macro_signal.emit(repo)
|
||||
@@ -713,7 +707,7 @@ class FillMacroListWorker(QtCore.QThread):
|
||||
macro_names.append(macname)
|
||||
macro = Macro(macname)
|
||||
macro.on_wiki = True
|
||||
repo = AddonManagerRepo.from_macro(macro)
|
||||
repo = Addon.from_macro(macro)
|
||||
repo.url = "https://wiki.freecad.org/Macros_recipes"
|
||||
utils.update_macro_installation_details(repo)
|
||||
self.add_macro_signal.emit(repo)
|
||||
@@ -723,10 +717,10 @@ class CacheMacroCode(QtCore.QThread):
|
||||
"""Download and cache the macro code, and parse its internal metadata"""
|
||||
|
||||
status_message = QtCore.Signal(str)
|
||||
update_macro = QtCore.Signal(AddonManagerRepo)
|
||||
update_macro = QtCore.Signal(Addon)
|
||||
progress_made = QtCore.Signal(int, int)
|
||||
|
||||
def __init__(self, repos: List[AddonManagerRepo]) -> None:
|
||||
def __init__(self, repos: List[Addon]) -> None:
|
||||
QtCore.QThread.__init__(self)
|
||||
self.repos = repos
|
||||
self.workers = []
|
||||
@@ -797,7 +791,7 @@ class CacheMacroCode(QtCore.QThread):
|
||||
).format(num_macros=num_macros, num_failed=num_failed)
|
||||
)
|
||||
|
||||
def update_and_advance(self, repo: AddonManagerRepo) -> None:
|
||||
def update_and_advance(self, repo: Addon) -> None:
|
||||
if repo is not None:
|
||||
if repo.macro.name not in self.failed:
|
||||
self.update_macro.emit(repo)
|
||||
@@ -906,10 +900,10 @@ class InstallWorkbenchWorker(QtCore.QThread):
|
||||
|
||||
status_message = QtCore.Signal(str)
|
||||
progress_made = QtCore.Signal(int, int)
|
||||
success = QtCore.Signal(AddonManagerRepo, str)
|
||||
failure = QtCore.Signal(AddonManagerRepo, str)
|
||||
success = QtCore.Signal(Addon, str)
|
||||
failure = QtCore.Signal(Addon, str)
|
||||
|
||||
def __init__(self, repo: AddonManagerRepo):
|
||||
def __init__(self, repo: Addon):
|
||||
|
||||
QtCore.QThread.__init__(self)
|
||||
self.repo = repo
|
||||
@@ -1094,7 +1088,7 @@ class InstallWorkbenchWorker(QtCore.QThread):
|
||||
"Addon successfully installed.",
|
||||
)
|
||||
|
||||
if self.repo.repo_type == AddonManagerRepo.RepoType.WORKBENCH:
|
||||
if self.repo.repo_type == Addon.Kind.WORKBENCH:
|
||||
# symlink any macro contained in the module to the macros folder
|
||||
macro_dir = FreeCAD.getUserMacroDir(True)
|
||||
if not os.path.exists(macro_dir):
|
||||
@@ -1375,7 +1369,7 @@ class UpdateMetadataCacheWorker(QtCore.QThread):
|
||||
|
||||
status_message = QtCore.Signal(str)
|
||||
progress_made = QtCore.Signal(int, int)
|
||||
package_updated = QtCore.Signal(AddonManagerRepo)
|
||||
package_updated = QtCore.Signal(Addon)
|
||||
|
||||
class RequestType(Enum):
|
||||
PACKAGE_XML = auto()
|
||||
@@ -1387,9 +1381,7 @@ class UpdateMetadataCacheWorker(QtCore.QThread):
|
||||
|
||||
QtCore.QThread.__init__(self)
|
||||
self.repos = repos
|
||||
self.requests: Dict[
|
||||
int, (AddonManagerRepo, UpdateMetadataCacheWorker.RequestType)
|
||||
] = {}
|
||||
self.requests: Dict[int, (Addon, UpdateMetadataCacheWorker.RequestType)] = {}
|
||||
NetworkManager.AM_NETWORK_MANAGER.completed.connect(self.download_completed)
|
||||
self.requests_completed = 0
|
||||
self.total_requests = 0
|
||||
@@ -1470,8 +1462,8 @@ class UpdateMetadataCacheWorker(QtCore.QThread):
|
||||
elif request[1] == UpdateMetadataCacheWorker.RequestType.ICON:
|
||||
self.process_icon(request[0], data)
|
||||
|
||||
def process_package_xml(self, repo: AddonManagerRepo, data: QtCore.QByteArray):
|
||||
repo.repo_type = AddonManagerRepo.RepoType.PACKAGE # By definition
|
||||
def process_package_xml(self, repo: Addon, data: QtCore.QByteArray):
|
||||
repo.repo_type = Addon.Kind.PACKAGE # By definition
|
||||
package_cache_directory = os.path.join(self.store, repo.name)
|
||||
if not os.path.exists(package_cache_directory):
|
||||
os.makedirs(package_cache_directory)
|
||||
@@ -1509,7 +1501,7 @@ class UpdateMetadataCacheWorker(QtCore.QThread):
|
||||
self.requests[index] = (repo, UpdateMetadataCacheWorker.RequestType.ICON)
|
||||
self.total_requests += 1
|
||||
|
||||
def process_metadata_txt(self, repo: AddonManagerRepo, data: QtCore.QByteArray):
|
||||
def process_metadata_txt(self, repo: Addon, data: QtCore.QByteArray):
|
||||
self.status_message.emit(
|
||||
translate("AddonsInstaller", "Downloaded metadata.txt for {}").format(
|
||||
repo.display_name
|
||||
@@ -1557,7 +1549,7 @@ class UpdateMetadataCacheWorker(QtCore.QThread):
|
||||
with open(new_xml_file, "wb") as f:
|
||||
f.write(data.data())
|
||||
|
||||
def process_requirements_txt(self, repo: AddonManagerRepo, data: QtCore.QByteArray):
|
||||
def process_requirements_txt(self, repo: Addon, data: QtCore.QByteArray):
|
||||
self.status_message.emit(
|
||||
translate(
|
||||
"AddonsInstaller",
|
||||
@@ -1583,7 +1575,7 @@ class UpdateMetadataCacheWorker(QtCore.QThread):
|
||||
with open(new_xml_file, "wb") as f:
|
||||
f.write(data.data())
|
||||
|
||||
def process_icon(self, repo: AddonManagerRepo, data: QtCore.QByteArray):
|
||||
def process_icon(self, repo: Addon, data: QtCore.QByteArray):
|
||||
self.status_message.emit(
|
||||
translate("AddonsInstaller", "Downloaded icon for {}").format(
|
||||
repo.display_name
|
||||
@@ -1625,8 +1617,8 @@ class UpdateAllWorker(QtCore.QThread):
|
||||
|
||||
progress_made = QtCore.Signal(int, int)
|
||||
status_message = QtCore.Signal(str)
|
||||
success = QtCore.Signal(AddonManagerRepo)
|
||||
failure = QtCore.Signal(AddonManagerRepo)
|
||||
success = QtCore.Signal(Addon)
|
||||
failure = QtCore.Signal(Addon)
|
||||
|
||||
def __init__(self, repos):
|
||||
super().__init__()
|
||||
@@ -1664,13 +1656,13 @@ class UpdateAllWorker(QtCore.QThread):
|
||||
for worker in workers:
|
||||
worker.wait()
|
||||
|
||||
def on_success(self, repo: AddonManagerRepo) -> None:
|
||||
def on_success(self, repo: Addon) -> None:
|
||||
self.progress_made.emit(
|
||||
len(self.repos) - self.repo_queue.qsize(), len(self.repos)
|
||||
)
|
||||
self.success.emit(repo)
|
||||
|
||||
def on_failure(self, repo: AddonManagerRepo) -> None:
|
||||
def on_failure(self, repo: Addon) -> None:
|
||||
self.progress_made.emit(
|
||||
len(self.repos) - self.repo_queue.qsize(), len(self.repos)
|
||||
)
|
||||
@@ -1678,8 +1670,8 @@ class UpdateAllWorker(QtCore.QThread):
|
||||
|
||||
|
||||
class UpdateSingleWorker(QtCore.QThread):
|
||||
success = QtCore.Signal(AddonManagerRepo)
|
||||
failure = QtCore.Signal(AddonManagerRepo)
|
||||
success = QtCore.Signal(Addon)
|
||||
failure = QtCore.Signal(Addon)
|
||||
|
||||
def __init__(self, repo_queue: queue.Queue):
|
||||
super().__init__()
|
||||
@@ -1694,13 +1686,13 @@ class UpdateSingleWorker(QtCore.QThread):
|
||||
repo = self.repo_queue.get_nowait()
|
||||
except queue.Empty:
|
||||
return
|
||||
if repo.repo_type == AddonManagerRepo.RepoType.MACRO:
|
||||
if repo.repo_type == Addon.Kind.MACRO:
|
||||
self.update_macro(repo)
|
||||
else:
|
||||
self.update_package(repo)
|
||||
self.repo_queue.task_done()
|
||||
|
||||
def update_macro(self, repo: AddonManagerRepo):
|
||||
def update_macro(self, repo: Addon):
|
||||
"""Updating a macro happens in this function, in the current thread"""
|
||||
|
||||
cache_path = os.path.join(
|
||||
@@ -1718,7 +1710,7 @@ class UpdateSingleWorker(QtCore.QThread):
|
||||
else:
|
||||
self.failure.emit(repo)
|
||||
|
||||
def update_package(self, repo: AddonManagerRepo):
|
||||
def update_package(self, repo: Addon):
|
||||
"""Updating a package re-uses the package installation worker, so actually spawns another thread that we block on"""
|
||||
|
||||
worker = InstallWorkbenchWorker(repo)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
# ***************************************************************************
|
||||
# * *
|
||||
# * Copyright (c) 2022 Chris Hennes <chennes@pioneerlibrarysystem.org> *
|
||||
# * Copyright (c) 2022 FreeCAD Project Association *
|
||||
# * *
|
||||
# * This library is free software; you can redistribute it and/or *
|
||||
# * modify it under the terms of the GNU Lesser General Public *
|
||||
|
||||
@@ -22,14 +22,14 @@
|
||||
import FreeCAD
|
||||
import FreeCADGui
|
||||
from PySide2 import QtCore, QtWidgets
|
||||
import AddonManagerRepo
|
||||
import Addon
|
||||
|
||||
import os
|
||||
|
||||
translate = FreeCAD.Qt.translate
|
||||
|
||||
|
||||
def ask_to_install_toolbar_button(repo: AddonManagerRepo) -> None:
|
||||
def ask_to_install_toolbar_button(repo: Addon) -> None:
|
||||
pref = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Addons")
|
||||
do_not_show_dialog = pref.GetBool("dontShowAddMacroButtonDialog", False)
|
||||
if not do_not_show_dialog:
|
||||
@@ -46,7 +46,7 @@ def ask_to_install_toolbar_button(repo: AddonManagerRepo) -> None:
|
||||
|
||||
|
||||
def ask_for_toolbar(
|
||||
repo: AddonManagerRepo, custom_toolbars
|
||||
repo: Addon, custom_toolbars
|
||||
) -> object: # Returns the pref group for the new toolbar
|
||||
pref = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Addons")
|
||||
|
||||
@@ -158,7 +158,7 @@ def check_for_toolbar(custom_toolbars, toolbar_name: str) -> bool:
|
||||
return False
|
||||
|
||||
|
||||
def install_toolbar_button(repo: AddonManagerRepo) -> None:
|
||||
def install_toolbar_button(repo: Addon) -> None:
|
||||
pref = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Addons")
|
||||
custom_toolbar_name = pref.GetString(
|
||||
"CustomToolbarName", "Auto-Created Macro Toolbar"
|
||||
@@ -206,7 +206,7 @@ def install_toolbar_button(repo: AddonManagerRepo) -> None:
|
||||
)
|
||||
|
||||
|
||||
def install_macro_to_toolbar(repo: AddonManagerRepo, toolbar: object) -> None:
|
||||
def install_macro_to_toolbar(repo: Addon, toolbar: object) -> None:
|
||||
menuText = repo.display_name
|
||||
tooltipText = f"<b>{repo.display_name}</b>"
|
||||
if repo.macro.comment:
|
||||
@@ -254,7 +254,7 @@ def install_macro_to_toolbar(repo: AddonManagerRepo, toolbar: object) -> None:
|
||||
wb.reloadActive()
|
||||
|
||||
|
||||
def remove_custom_toolbar_button(repo: AddonManagerRepo) -> None:
|
||||
def remove_custom_toolbar_button(repo: Addon) -> None:
|
||||
"""If this repo contains a macro, look through the custom commands and
|
||||
see if one is set up for this macro. If so, remove it, including any
|
||||
toolbar entries."""
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
# ***************************************************************************
|
||||
# * *
|
||||
# * Copyright (c) 2021 Chris Hennes <chennes@pioneerlibrarysystem.org> *
|
||||
# * Copyright (c) 2022 FreeCAD Project Association *
|
||||
# * *
|
||||
# * This program is free software; you can redistribute it and/or modify *
|
||||
# * it under the terms of the GNU Lesser General Public License (LGPL) *
|
||||
@@ -34,7 +34,7 @@ import FreeCADGui
|
||||
|
||||
import addonmanager_utilities as utils
|
||||
from addonmanager_workers import GetMacroDetailsWorker, CheckSingleUpdateWorker
|
||||
from AddonManagerRepo import AddonManagerRepo
|
||||
from Addon import Addon
|
||||
import NetworkManager
|
||||
from change_branch import ChangeBranchDialog
|
||||
|
||||
@@ -71,12 +71,12 @@ except Exception:
|
||||
class PackageDetails(QWidget):
|
||||
|
||||
back = Signal()
|
||||
install = Signal(AddonManagerRepo)
|
||||
uninstall = Signal(AddonManagerRepo)
|
||||
update = Signal(AddonManagerRepo)
|
||||
execute = Signal(AddonManagerRepo)
|
||||
update_status = Signal(AddonManagerRepo)
|
||||
check_for_update = Signal(AddonManagerRepo)
|
||||
install = Signal(Addon)
|
||||
uninstall = Signal(Addon)
|
||||
update = Signal(Addon)
|
||||
execute = Signal(Addon)
|
||||
update_status = Signal(Addon)
|
||||
check_for_update = Signal(Addon)
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
@@ -110,7 +110,7 @@ class PackageDetails(QWidget):
|
||||
self.ui.loadingLabel.show()
|
||||
self.ui.webView.hide()
|
||||
|
||||
def show_repo(self, repo: AddonManagerRepo, reload: bool = False) -> None:
|
||||
def show_repo(self, repo: Addon, reload: bool = False) -> None:
|
||||
|
||||
# If this is the same repo we were already showing, we do not have to do the
|
||||
# expensive refetch unless reload is true
|
||||
@@ -136,17 +136,17 @@ class PackageDetails(QWidget):
|
||||
self.worker.requestInterruption()
|
||||
self.worker.wait()
|
||||
|
||||
if repo.repo_type == AddonManagerRepo.RepoType.MACRO:
|
||||
if repo.repo_type == Addon.Kind.MACRO:
|
||||
self.show_macro(repo)
|
||||
self.ui.buttonExecute.show()
|
||||
elif repo.repo_type == AddonManagerRepo.RepoType.WORKBENCH:
|
||||
elif repo.repo_type == Addon.Kind.WORKBENCH:
|
||||
self.show_workbench(repo)
|
||||
self.ui.buttonExecute.hide()
|
||||
elif repo.repo_type == AddonManagerRepo.RepoType.PACKAGE:
|
||||
elif repo.repo_type == Addon.Kind.PACKAGE:
|
||||
self.show_package(repo)
|
||||
self.ui.buttonExecute.hide()
|
||||
|
||||
if repo.status() == AddonManagerRepo.UpdateStatus.UNCHECKED:
|
||||
if repo.status() == Addon.Status.UNCHECKED:
|
||||
if not self.status_update_thread:
|
||||
self.status_update_thread = QThread()
|
||||
self.status_update_worker = CheckSingleUpdateWorker(repo)
|
||||
@@ -165,7 +165,7 @@ class PackageDetails(QWidget):
|
||||
repo = self.repo
|
||||
self.set_change_branch_button_state()
|
||||
self.set_disable_button_state()
|
||||
if status != AddonManagerRepo.UpdateStatus.NOT_INSTALLED:
|
||||
if status != Addon.Status.NOT_INSTALLED:
|
||||
|
||||
version = repo.installed_version
|
||||
date = ""
|
||||
@@ -196,7 +196,7 @@ class PackageDetails(QWidget):
|
||||
translate("AddonsInstaller", "Installed") + ". "
|
||||
)
|
||||
|
||||
if status == AddonManagerRepo.UpdateStatus.UPDATE_AVAILABLE:
|
||||
if status == Addon.Status.UPDATE_AVAILABLE:
|
||||
if repo.metadata:
|
||||
installed_version_string += (
|
||||
"<b>"
|
||||
@@ -225,10 +225,10 @@ class PackageDetails(QWidget):
|
||||
)
|
||||
+ ".</b>"
|
||||
)
|
||||
elif status == AddonManagerRepo.UpdateStatus.NO_UPDATE_AVAILABLE:
|
||||
elif status == Addon.Status.NO_UPDATE_AVAILABLE:
|
||||
detached_head = False
|
||||
branch = repo.branch
|
||||
if have_git and repo.repo_type != AddonManagerRepo.RepoType.MACRO:
|
||||
if have_git and repo.repo_type != Addon.Kind.MACRO:
|
||||
basedir = FreeCAD.getUserAppDataDir()
|
||||
moddir = os.path.join(basedir, "Mod", repo.name)
|
||||
if os.path.exists(os.path.join(moddir, ".git")):
|
||||
@@ -252,14 +252,14 @@ class PackageDetails(QWidget):
|
||||
).format(branch)
|
||||
+ "."
|
||||
)
|
||||
elif status == AddonManagerRepo.UpdateStatus.PENDING_RESTART:
|
||||
elif status == Addon.Status.PENDING_RESTART:
|
||||
installed_version_string += (
|
||||
translate(
|
||||
"AddonsInstaller", "Updated, please restart FreeCAD to use"
|
||||
)
|
||||
+ "."
|
||||
)
|
||||
elif status == AddonManagerRepo.UpdateStatus.UNCHECKED:
|
||||
elif status == Addon.Status.UNCHECKED:
|
||||
|
||||
pref = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Addons")
|
||||
autocheck = pref.GetBool("AutoCheck", False)
|
||||
@@ -275,7 +275,7 @@ class PackageDetails(QWidget):
|
||||
|
||||
installed_version_string += "</h3>"
|
||||
self.ui.labelPackageDetails.setText(installed_version_string)
|
||||
if repo.status() == AddonManagerRepo.UpdateStatus.UPDATE_AVAILABLE:
|
||||
if repo.status() == Addon.Status.UPDATE_AVAILABLE:
|
||||
self.ui.labelPackageDetails.setStyleSheet(
|
||||
"color:" + utils.attention_color_string()
|
||||
)
|
||||
@@ -302,32 +302,32 @@ class PackageDetails(QWidget):
|
||||
self.ui.labelPackageDetails.hide()
|
||||
self.ui.labelInstallationLocation.hide()
|
||||
|
||||
if status == AddonManagerRepo.UpdateStatus.NOT_INSTALLED:
|
||||
if status == Addon.Status.NOT_INSTALLED:
|
||||
self.ui.buttonInstall.show()
|
||||
self.ui.buttonUninstall.hide()
|
||||
self.ui.buttonUpdate.hide()
|
||||
self.ui.buttonCheckForUpdate.hide()
|
||||
elif status == AddonManagerRepo.UpdateStatus.NO_UPDATE_AVAILABLE:
|
||||
elif status == Addon.Status.NO_UPDATE_AVAILABLE:
|
||||
self.ui.buttonInstall.hide()
|
||||
self.ui.buttonUninstall.show()
|
||||
self.ui.buttonUpdate.hide()
|
||||
self.ui.buttonCheckForUpdate.hide()
|
||||
elif status == AddonManagerRepo.UpdateStatus.UPDATE_AVAILABLE:
|
||||
elif status == Addon.Status.UPDATE_AVAILABLE:
|
||||
self.ui.buttonInstall.hide()
|
||||
self.ui.buttonUninstall.show()
|
||||
self.ui.buttonUpdate.show()
|
||||
self.ui.buttonCheckForUpdate.hide()
|
||||
elif status == AddonManagerRepo.UpdateStatus.UNCHECKED:
|
||||
elif status == Addon.Status.UNCHECKED:
|
||||
self.ui.buttonInstall.hide()
|
||||
self.ui.buttonUninstall.show()
|
||||
self.ui.buttonUpdate.hide()
|
||||
self.ui.buttonCheckForUpdate.show()
|
||||
elif status == AddonManagerRepo.UpdateStatus.PENDING_RESTART:
|
||||
elif status == Addon.Status.PENDING_RESTART:
|
||||
self.ui.buttonInstall.hide()
|
||||
self.ui.buttonUninstall.show()
|
||||
self.ui.buttonUpdate.hide()
|
||||
self.ui.buttonCheckForUpdate.hide()
|
||||
elif status == AddonManagerRepo.UpdateStatus.CANNOT_CHECK:
|
||||
elif status == Addon.Status.CANNOT_CHECK:
|
||||
self.ui.buttonInstall.hide()
|
||||
self.ui.buttonUninstall.show()
|
||||
self.ui.buttonUpdate.show()
|
||||
@@ -369,7 +369,10 @@ class PackageDetails(QWidget):
|
||||
self.ui.labelWarningInfo.show()
|
||||
self.ui.labelWarningInfo.setText(
|
||||
"<h2>"
|
||||
+ translate("AddonsInstaller", "WARNING: This addon is currently installed, but disabled. Use the 'enable' button to re-enable.")
|
||||
+ translate(
|
||||
"AddonsInstaller",
|
||||
"WARNING: This addon is currently installed, but disabled. Use the 'enable' button to re-enable.",
|
||||
)
|
||||
+ "</h2>"
|
||||
)
|
||||
self.ui.labelWarningInfo.setStyleSheet(
|
||||
@@ -381,10 +384,7 @@ class PackageDetails(QWidget):
|
||||
|
||||
def requires_newer_freecad(self) -> Optional[str]:
|
||||
# If it's not installed, check to see if it's for a newer version of FreeCAD
|
||||
if (
|
||||
self.repo.status() == AddonManagerRepo.UpdateStatus.NOT_INSTALLED
|
||||
and self.repo.metadata
|
||||
):
|
||||
if self.repo.status() == Addon.Status.NOT_INSTALLED and self.repo.metadata:
|
||||
# Only hide if ALL content items require a newer version, otherwise
|
||||
# it's possible that this package actually provides versions of itself
|
||||
# for newer and older versions
|
||||
@@ -416,11 +416,11 @@ class PackageDetails(QWidget):
|
||||
return
|
||||
|
||||
# Is this repo installed? If not, return.
|
||||
if self.repo.status() == AddonManagerRepo.UpdateStatus.NOT_INSTALLED:
|
||||
if self.repo.status() == Addon.Status.NOT_INSTALLED:
|
||||
return
|
||||
|
||||
# Is it a Macro? If so, return:
|
||||
if self.repo.repo_type == AddonManagerRepo.RepoType.MACRO:
|
||||
if self.repo.repo_type == Addon.Kind.MACRO:
|
||||
return
|
||||
|
||||
# Can we actually switch branches? If not, return.
|
||||
@@ -441,14 +441,14 @@ class PackageDetails(QWidget):
|
||||
self.ui.buttonEnable.hide()
|
||||
self.ui.buttonDisable.hide()
|
||||
status = self.repo.status()
|
||||
if status != AddonManagerRepo.UpdateStatus.NOT_INSTALLED:
|
||||
if status != Addon.Status.NOT_INSTALLED:
|
||||
disabled = self.repo.is_disabled()
|
||||
if disabled:
|
||||
self.ui.buttonEnable.show()
|
||||
else:
|
||||
self.ui.buttonDisable.show()
|
||||
|
||||
def show_workbench(self, repo: AddonManagerRepo) -> None:
|
||||
def show_workbench(self, repo: Addon) -> None:
|
||||
"""loads information of a given workbench"""
|
||||
url = utils.get_readme_html_url(repo)
|
||||
if HAS_QTWEBENGINE:
|
||||
@@ -459,7 +459,7 @@ class PackageDetails(QWidget):
|
||||
text = readme_data.data().decode("utf8")
|
||||
self.ui.textBrowserReadMe.setHtml(text)
|
||||
|
||||
def show_package(self, repo: AddonManagerRepo) -> None:
|
||||
def show_package(self, repo: Addon) -> None:
|
||||
"""Show the details for a package (a repo with a package.xml metadata file)"""
|
||||
|
||||
readme_url = None
|
||||
@@ -479,7 +479,7 @@ class PackageDetails(QWidget):
|
||||
text = readme_data.data().decode("utf8")
|
||||
self.ui.textBrowserReadMe.setHtml(text)
|
||||
|
||||
def show_macro(self, repo: AddonManagerRepo) -> None:
|
||||
def show_macro(self, repo: Addon) -> None:
|
||||
"""loads information of a given macro"""
|
||||
|
||||
if not repo.macro.url:
|
||||
@@ -614,12 +614,13 @@ class PackageDetails(QWidget):
|
||||
self.ui.labelWarningInfo.show()
|
||||
self.ui.labelWarningInfo.setText(
|
||||
"<h3>"
|
||||
+ translate("AddonsInstaller", "This Addon will be enabled next time you restart FreeCAD.")
|
||||
+ translate(
|
||||
"AddonsInstaller",
|
||||
"This Addon will be enabled next time you restart FreeCAD.",
|
||||
)
|
||||
+ "</h3>"
|
||||
)
|
||||
self.ui.labelWarningInfo.setStyleSheet(
|
||||
"color:" + utils.bright_color_string()
|
||||
)
|
||||
self.ui.labelWarningInfo.setStyleSheet("color:" + utils.bright_color_string())
|
||||
|
||||
def disable_clicked(self) -> None:
|
||||
self.repo.disable()
|
||||
@@ -628,7 +629,10 @@ class PackageDetails(QWidget):
|
||||
self.ui.labelWarningInfo.show()
|
||||
self.ui.labelWarningInfo.setText(
|
||||
"<h3>"
|
||||
+ translate("AddonsInstaller", "This Addon will be disabled next time you restart FreeCAD.")
|
||||
+ translate(
|
||||
"AddonsInstaller",
|
||||
"This Addon will be disabled next time you restart FreeCAD.",
|
||||
)
|
||||
+ "</h3>"
|
||||
)
|
||||
self.ui.labelWarningInfo.setStyleSheet(
|
||||
@@ -651,12 +655,12 @@ class PackageDetails(QWidget):
|
||||
self.repo.load_metadata_file(path_to_metadata)
|
||||
self.repo.installed_version = self.repo.metadata.Version
|
||||
else:
|
||||
self.repo.repo_type = AddonManagerRepo.RepoType.WORKBENCH
|
||||
self.repo.repo_type = Addon.Kind.WORKBENCH
|
||||
self.repo.metadata = None
|
||||
self.repo.installed_version = None
|
||||
self.repo.updated_timestamp = QDateTime.currentDateTime().toSecsSinceEpoch()
|
||||
self.repo.branch = name
|
||||
self.repo.set_status(AddonManagerRepo.UpdateStatus.PENDING_RESTART)
|
||||
self.repo.set_status(Addon.Status.PENDING_RESTART)
|
||||
|
||||
installed_version_string = "<h3>"
|
||||
installed_version_string += translate(
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
# ***************************************************************************
|
||||
# * *
|
||||
# * Copyright (c) 2021 Chris Hennes <chennes@pioneerlibrarysystem.org> *
|
||||
# * Copyright (c) 2022 FreeCAD Project Association *
|
||||
# * *
|
||||
# * This program is free software; you can redistribute it and/or modify *
|
||||
# * it under the terms of the GNU Lesser General Public License (LGPL) *
|
||||
@@ -31,7 +31,7 @@ from PySide2.QtWidgets import *
|
||||
from enum import IntEnum
|
||||
import threading
|
||||
|
||||
from AddonManagerRepo import AddonManagerRepo
|
||||
from Addon import Addon
|
||||
|
||||
from compact_view import Ui_CompactView
|
||||
from expanded_view import Ui_ExpandedView
|
||||
@@ -56,7 +56,7 @@ class StatusFilter(IntEnum):
|
||||
class PackageList(QWidget):
|
||||
"""A widget that shows a list of packages and various widgets to control the display of the list"""
|
||||
|
||||
itemSelected = Signal(AddonManagerRepo)
|
||||
itemSelected = Signal(Addon)
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
@@ -206,15 +206,15 @@ class PackageListItemModel(QAbstractListModel):
|
||||
row = index.row()
|
||||
if role == Qt.ToolTipRole:
|
||||
tooltip = ""
|
||||
if self.repos[row].repo_type == AddonManagerRepo.RepoType.PACKAGE:
|
||||
if self.repos[row].repo_type == Addon.Kind.PACKAGE:
|
||||
tooltip = translate(
|
||||
"AddonsInstaller", "Click for details about package {}"
|
||||
).format(self.repos[row].display_name)
|
||||
elif self.repos[row].repo_type == AddonManagerRepo.RepoType.WORKBENCH:
|
||||
elif self.repos[row].repo_type == Addon.Kind.WORKBENCH:
|
||||
tooltip = translate(
|
||||
"AddonsInstaller", "Click for details about workbench {}"
|
||||
).format(self.repos[row].display_name)
|
||||
elif self.repos[row].repo_type == AddonManagerRepo.RepoType.MACRO:
|
||||
elif self.repos[row].repo_type == Addon.Kind.MACRO:
|
||||
tooltip = translate(
|
||||
"AddonsInstaller", "Click for details about macro {}"
|
||||
).format(self.repos[row].display_name)
|
||||
@@ -246,7 +246,7 @@ class PackageListItemModel(QAbstractListModel):
|
||||
)
|
||||
self.write_lock.release()
|
||||
|
||||
def append_item(self, repo: AddonManagerRepo) -> None:
|
||||
def append_item(self, repo: Addon) -> None:
|
||||
if repo in self.repos:
|
||||
# Cowardly refuse to insert the same repo a second time
|
||||
return
|
||||
@@ -264,9 +264,7 @@ class PackageListItemModel(QAbstractListModel):
|
||||
self.endRemoveRows()
|
||||
self.write_lock.release()
|
||||
|
||||
def update_item_status(
|
||||
self, name: str, status: AddonManagerRepo.UpdateStatus
|
||||
) -> None:
|
||||
def update_item_status(self, name: str, status: Addon.Status) -> None:
|
||||
for row, item in enumerate(self.repos):
|
||||
if item.name == name:
|
||||
self.setData(
|
||||
@@ -282,7 +280,7 @@ class PackageListItemModel(QAbstractListModel):
|
||||
)
|
||||
return
|
||||
|
||||
def reload_item(self, repo: AddonManagerRepo) -> None:
|
||||
def reload_item(self, repo: Addon) -> None:
|
||||
for index, item in enumerate(self.repos):
|
||||
if item.name == repo.name:
|
||||
self.write_lock.acquire()
|
||||
@@ -414,32 +412,38 @@ class PackageListItemDelegate(QStyledItemDelegate):
|
||||
|
||||
self.widget.adjustSize()
|
||||
|
||||
def get_compact_update_string(self, repo: AddonManagerRepo) -> str:
|
||||
def get_compact_update_string(self, repo: Addon) -> str:
|
||||
"""Get a single-line string listing details about the installed version and date"""
|
||||
|
||||
result = ""
|
||||
if repo.status() == AddonManagerRepo.UpdateStatus.UNCHECKED:
|
||||
if repo.status() == Addon.Status.UNCHECKED:
|
||||
result = translate("AddonsInstaller", "Installed")
|
||||
elif repo.status() == AddonManagerRepo.UpdateStatus.NO_UPDATE_AVAILABLE:
|
||||
elif repo.status() == Addon.Status.NO_UPDATE_AVAILABLE:
|
||||
result = translate("AddonsInstaller", "Up-to-date")
|
||||
elif repo.status() == AddonManagerRepo.UpdateStatus.UPDATE_AVAILABLE:
|
||||
elif repo.status() == Addon.Status.UPDATE_AVAILABLE:
|
||||
result = translate("AddonsInstaller", "Update available")
|
||||
elif repo.status() == AddonManagerRepo.UpdateStatus.PENDING_RESTART:
|
||||
elif repo.status() == Addon.Status.PENDING_RESTART:
|
||||
result = translate("AddonsInstaller", "Pending restart")
|
||||
|
||||
|
||||
if repo.is_disabled():
|
||||
style = "style='color:" + utils.warning_color_string() + "; font-weight:bold;'"
|
||||
result += f"<span {style}> [" + translate("AddonsInstaller","DISABLED") + "]</span>"
|
||||
style = (
|
||||
"style='color:" + utils.warning_color_string() + "; font-weight:bold;'"
|
||||
)
|
||||
result += (
|
||||
f"<span {style}> ["
|
||||
+ translate("AddonsInstaller", "DISABLED")
|
||||
+ "]</span>"
|
||||
)
|
||||
|
||||
return result
|
||||
|
||||
def get_expanded_update_string(self, repo: AddonManagerRepo) -> str:
|
||||
def get_expanded_update_string(self, repo: Addon) -> str:
|
||||
"""Get a multi-line string listing details about the installed version and date"""
|
||||
|
||||
result = ""
|
||||
|
||||
installed_version_string = ""
|
||||
if repo.status() != AddonManagerRepo.UpdateStatus.NOT_INSTALLED:
|
||||
if repo.status() != Addon.Status.NOT_INSTALLED:
|
||||
if repo.installed_version:
|
||||
installed_version_string = (
|
||||
"<br/>" + translate("AddonsInstaller", "Installed version") + ": "
|
||||
@@ -468,25 +472,31 @@ class PackageListItemDelegate(QStyledItemDelegate):
|
||||
)
|
||||
available_version_string += repo.metadata.Version
|
||||
|
||||
if repo.status() == AddonManagerRepo.UpdateStatus.UNCHECKED:
|
||||
if repo.status() == Addon.Status.UNCHECKED:
|
||||
result = translate("AddonsInstaller", "Installed")
|
||||
result += installed_version_string
|
||||
result += installed_date_string
|
||||
elif repo.status() == AddonManagerRepo.UpdateStatus.NO_UPDATE_AVAILABLE:
|
||||
elif repo.status() == Addon.Status.NO_UPDATE_AVAILABLE:
|
||||
result = translate("AddonsInstaller", "Up-to-date")
|
||||
result += installed_version_string
|
||||
result += installed_date_string
|
||||
elif repo.status() == AddonManagerRepo.UpdateStatus.UPDATE_AVAILABLE:
|
||||
elif repo.status() == Addon.Status.UPDATE_AVAILABLE:
|
||||
result = translate("AddonsInstaller", "Update available")
|
||||
result += installed_version_string
|
||||
result += installed_date_string
|
||||
result += available_version_string
|
||||
elif repo.status() == AddonManagerRepo.UpdateStatus.PENDING_RESTART:
|
||||
elif repo.status() == Addon.Status.PENDING_RESTART:
|
||||
result = translate("AddonsInstaller", "Pending restart")
|
||||
|
||||
|
||||
if repo.is_disabled():
|
||||
style = "style='color:" + utils.warning_color_string() + "; font-weight:bold;'"
|
||||
result += f"<br/><span {style}>[" + translate("AddonsInstaller","DISABLED") + "]</span>"
|
||||
style = (
|
||||
"style='color:" + utils.warning_color_string() + "; font-weight:bold;'"
|
||||
)
|
||||
result += (
|
||||
f"<br/><span {style}>["
|
||||
+ translate("AddonsInstaller", "DISABLED")
|
||||
+ "]</span>"
|
||||
)
|
||||
|
||||
return result
|
||||
|
||||
@@ -554,18 +564,18 @@ class PackageListFilter(QSortFilterProxyModel):
|
||||
return False
|
||||
|
||||
if self.status == StatusFilter.INSTALLED:
|
||||
if data.status() == AddonManagerRepo.UpdateStatus.NOT_INSTALLED:
|
||||
if data.status() == Addon.Status.NOT_INSTALLED:
|
||||
return False
|
||||
elif self.status == StatusFilter.NOT_INSTALLED:
|
||||
if data.status() != AddonManagerRepo.UpdateStatus.NOT_INSTALLED:
|
||||
if data.status() != Addon.Status.NOT_INSTALLED:
|
||||
return False
|
||||
elif self.status == StatusFilter.UPDATE_AVAILABLE:
|
||||
if data.status() != AddonManagerRepo.UpdateStatus.UPDATE_AVAILABLE:
|
||||
if data.status() != Addon.Status.UPDATE_AVAILABLE:
|
||||
return False
|
||||
|
||||
# If it's not installed, check to see if it's Py2 only
|
||||
if (
|
||||
data.status() == AddonManagerRepo.UpdateStatus.NOT_INSTALLED
|
||||
data.status() == Addon.Status.NOT_INSTALLED
|
||||
and self.hide_py2
|
||||
and data.python2
|
||||
):
|
||||
@@ -573,7 +583,7 @@ class PackageListFilter(QSortFilterProxyModel):
|
||||
|
||||
# If it's not installed, check to see if it's marked obsolete
|
||||
if (
|
||||
data.status() == AddonManagerRepo.UpdateStatus.NOT_INSTALLED
|
||||
data.status() == Addon.Status.NOT_INSTALLED
|
||||
and self.hide_obsolete
|
||||
and data.obsolete
|
||||
):
|
||||
@@ -581,7 +591,7 @@ class PackageListFilter(QSortFilterProxyModel):
|
||||
|
||||
# If it's not installed, check to see if it's for a newer version of FreeCAD
|
||||
if (
|
||||
data.status() == AddonManagerRepo.UpdateStatus.NOT_INSTALLED
|
||||
data.status() == Addon.Status.NOT_INSTALLED
|
||||
and self.hide_newer_freecad_required
|
||||
and data.metadata
|
||||
):
|
||||
|
||||
Reference in New Issue
Block a user