Skip to content
Closed
Show file tree
Hide file tree
Changes from 2 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
20 changes: 18 additions & 2 deletions Widgets/addonmanager_widget_package_details_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,12 @@
# ***************************************************************************

from dataclasses import dataclass
from typing import Optional, Dict
from enum import Enum, auto
import os
from typing import Optional

from addonmanager_freecad_interface import translate
from addonmanager_readme_controller import TabView

from PySideWrapper import QtCore, QtWidgets

Expand Down Expand Up @@ -71,6 +72,7 @@ class PackageDetailsView(QtWidgets.QWidget):
def __init__(self, parent: QtWidgets.QWidget = None):
super().__init__(parent)
self.button_bar = None
self.license_browser = None
self.readme_browser = None
self.message_label = None
self.location_label = None
Expand All @@ -83,12 +85,26 @@ def __init__(self, parent: QtWidgets.QWidget = None):
self.installed_branch = None
self.installed_timestamp = None
self.can_disable = True
self.tabs: Dict[TabView, int] = {}
self._setup_ui()

def _setup_ui(self):
self.vertical_layout = QtWidgets.QVBoxLayout(self)
self.button_bar = WidgetAddonButtons(self)

self.license_browser = WidgetReadmeBrowser(self)
self.readme_browser = WidgetReadmeBrowser(self)

self.tabs_widget = QtWidgets.QTabWidget(self)

self.tabs[TabView.Readme] = self.tabs_widget.addTab(
self.readme_browser, translate("AddonsInstaller", "README")
Comment thread
PhoneDroid marked this conversation as resolved.
Outdated
)

self.tabs[TabView.License] = self.tabs_widget.addTab(
self.license_browser, translate("AddonsInstaller", "LICENSE")
)

self.message_label = QtWidgets.QLabel(self)
self.location_label = QtWidgets.QLabel(self)
self.url_label = QtWidgets.QLabel(self)
Expand All @@ -98,7 +114,7 @@ def _setup_ui(self):
self.vertical_layout.addWidget(self.message_label)
self.vertical_layout.addWidget(self.location_label)
self.vertical_layout.addWidget(self.url_label)
self.vertical_layout.addWidget(self.readme_browser)
self.vertical_layout.addWidget(self.tabs_widget)
self.button_bar.hide() # Start with no bar

def set_location(self, location: Optional[str]):
Expand Down
26 changes: 22 additions & 4 deletions addonmanager_package_details_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,15 @@
get_branch_from_metadata,
get_repo_url_from_metadata,
)
from Widgets.addonmanager_widget_package_details_view import (
PackageDetailsView,
UpdateInformation,
WarningFlags,
)
from addonmanager_readme_controller import ReadmeController, TabView
from addonmanager_workers_startup import CheckSingleUpdateWorker
from addonmanager_git import GitManager, NoGitFound
from Addon import Addon
from addonmanager_readme_controller import ReadmeController
from Widgets.addonmanager_widget_package_details_view import UpdateInformation, WarningFlags

translate = fci.translate

Expand All @@ -52,10 +56,13 @@ class PackageDetailsController(QtCore.QObject):
execute = QtCore.Signal(Addon)
update_status = QtCore.Signal(Addon)

def __init__(self, widget=None):
def __init__(self, widget: PackageDetailsView):
super().__init__()
self.ui = widget

self.license_controller = ReadmeController(self.ui.license_browser)
self.readme_controller = ReadmeController(self.ui.readme_browser)

self.worker = None
self.addon = None
self.update_check_thread = None
Expand All @@ -79,9 +86,20 @@ def __init__(self, widget=None):
def show_addon(self, addon: Addon) -> None:
"""The main entry point for this class shows the package details and related buttons
for the provided repo."""

self.addon = addon
self.readme_controller.set_addon(addon)

self.readme_controller.set_addon(addon, TabView.Readme)

has_license = bool(self.addon.license)

self.ui.tabs_widget.setTabVisible(self.ui.tabs[TabView.License], has_license)

if has_license:
self.license_controller.set_addon(addon, TabView.License)

self.original_disabled_state = self.addon.is_disabled()

if addon is not None:
self.ui.button_bar.show()
if addon.repo_type == Addon.Kind.MACRO:
Expand Down
160 changes: 108 additions & 52 deletions addonmanager_readme_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,13 @@
import addonmanager_utilities as utils
import addonmanager_freecad_interface as fci

from enum import IntEnum
from typing import Optional
from requests import get as fetch, ConnectionError
from typing import Optional, cast
from enum import IntEnum, auto

import NetworkManager
from addonmanager_metadata import UrlType
from Widgets.addonmanager_widget_readme_browser import WidgetReadmeBrowser
from addonmanager_metadata import UrlType, License

translate = fci.translate

Expand All @@ -44,11 +46,16 @@
Html = 2


class TabView(IntEnum):
License = auto()
Readme = 0


class ReadmeController(QtCore.QObject):
"""A class that can provide README data from an Addon, possibly loading external resources such
as images"""

def __init__(self, widget):
def __init__(self, widget: WidgetReadmeBrowser):
super().__init__()
NetworkManager.InitializeNetworkManager()
NetworkManager.AM_NETWORK_MANAGER.completed.connect(self._download_completed)
Expand All @@ -64,16 +71,16 @@
self.widget.load_resource.connect(self.loadResource)
self.widget.follow_link.connect(self.follow_link)

def set_addon(self, repo: Addon):
def set_addon(self, addon: Addon, view: TabView):
"""Set which Addon's information is displayed"""

self.addon = repo
self.addon = addon
self.stop = False
self.readme_data = None
if self.addon.repo_type == Addon.Kind.MACRO:
self._create_wiki_display()
else:
self._create_non_wiki_display()
self._create_non_wiki_display(view)

def _download_completed(self, index: int, code: int, data: QtCore.QByteArray) -> None:
"""Callback for handling a completed README file download."""
Expand Down Expand Up @@ -103,7 +110,9 @@
else:
self.widget.setText(self.readme_data)
else:
self.set_addon(self.addon) # Trigger a reload of the page now with resources
self.set_addon(
self.addon, TabView.Readme
) # Trigger a reload of the page now with resources

def _process_package_download(self, data: str):
self.readme_data = data
Expand Down Expand Up @@ -182,47 +191,94 @@
self.readme_data_type = ReadmeDataType.Markdown
self.widget.setMarkdown(markdown)

def _create_non_wiki_display(self):
self.url = utils.get_readme_url(self.addon)
if self.addon.metadata and self.addon.metadata.url:
for url in self.addon.metadata.url:
if url.type == UrlType.readme:
if self.url != url.location:
fci.Console.PrintLog("README url does not match expected location\n")
fci.Console.PrintLog(f"Expected: {self.url}\n")
fci.Console.PrintLog(f"package.xml contents: {url.location}\n")
fci.Console.PrintLog(
"Note to addon devs: package.xml now expects a"
" url to the raw MD data, now that Qt can render"
" it without having it transformed to HTML.\n"
)
self.url = url.location
if "/blob/" in self.url:
fci.Console.PrintLog("Attempting to replace 'blob' with 'raw'...\n")
self.url = self.url.replace("/blob/", "/raw/")
elif "/src/" in self.url and "codeberg" in self.url:
fci.Console.PrintLog(
"Attempting to replace 'src' with 'raw' in codeberg URL..."
)
self.url = self.url.replace("/src/", "/raw/")

self.widget.setUrl(self.url)

self.widget.setText(
translate("AddonsInstaller", "Loading page for {} from {}...").format(
self.addon.display_name, self.url
)
)

if self.url[0] == "/":
if self.url.lower().endswith(".md"):
self.readme_data_type = ReadmeDataType.Markdown
elif self.url.lower().endswith(".html"):
self.readme_data_type = ReadmeDataType.Html

with open(self.url, "r") as fd:
self._process_package_download("".join(fd.readlines()))
else:
self.readme_request_index = NetworkManager.AM_NETWORK_MANAGER.submit_unmonitored_get(
self.url
)
def _create_non_wiki_display(self, view: TabView):

match view:
case TabView.License:

addon = cast(Addon, self.addon)

licenses = addon.license

match licenses:
case list():

text = ""

licenses = cast(list[License | str], licenses)

for license in licenses:
if license == str():
text += license
else:

name = license.name

url = utils.construct_git_url(addon, license.file)

try:

response = fetch(url)

if response.ok:
text += response.text
else:
text += name

except ConnectionError:

text += name

self.widget.setText(text)

case str():
self.widget.setText(licenses)

case TabView.Readme:

self.url = utils.get_readme_url(self.addon)

if self.addon.metadata and self.addon.metadata.url:
for url in self.addon.metadata.url:
if url.type == UrlType.readme:
if self.url != url.location:
fci.Console.PrintLog(
"README url does not match expected location\n"
)
fci.Console.PrintLog(f"Expected: {self.url}\n")
fci.Console.PrintLog(f"package.xml contents: {url.location}\n")
fci.Console.PrintLog(
"Note to addon devs: package.xml now expects a"
" url to the raw MD data, now that Qt can render"
" it without having it transformed to HTML.\n"
)
self.url = url.location
if "/blob/" in self.url:
fci.Console.PrintLog("Attempting to replace 'blob' with 'raw'...\n")
self.url = self.url.replace("/blob/", "/raw/")
elif "/src/" in self.url and "codeberg" in self.url:
fci.Console.PrintLog(
"Attempting to replace 'src' with 'raw' in codeberg URL..."
)
self.url = self.url.replace("/src/", "/raw/")

self.widget.setUrl(self.url)

self.widget.setText(
translate("AddonsInstaller", "Loading page for {} from {}...").format(
self.addon.display_name, self.url
)
)

if self.url[0] == "/":
if self.url.lower().endswith(".md"):
self.readme_data_type = ReadmeDataType.Markdown
elif self.url.lower().endswith(".html"):
self.readme_data_type = ReadmeDataType.Html

with open(self.url, "r") as fd:
Comment thread Fixed
self._process_package_download("".join(fd.readlines()))
else:
self.readme_request_index = (
NetworkManager.AM_NETWORK_MANAGER.submit_unmonitored_get(self.url)
)
Loading