from __future__ import absolute_import, print_function # Standard modules import logging import os import yaml from qtpy import QtCore, QtWidgets, uic from .. import base from ..properties import Paths # Logging log = logging.getLogger(f"grc.application.{__name__}") class OOTBrowser(QtWidgets.QDialog, base.Component): data_role = QtCore.Qt.UserRole def __init__(self): super().__init__() uic.loadUi(Paths.RESOURCES + "/oot_browser.ui", self) self.setMinimumSize(600, 450) self.setModal(True) self.setWindowTitle("GRC OOT Modules") self.left_list.currentItemChanged.connect(self.populate_right_view) self.manifest_dir = os.path.join(Paths.RESOURCES, "manifests") for f in os.listdir(self.manifest_dir): with open(os.path.join(self.manifest_dir, f), 'r', encoding='utf8') as manifest: text = manifest.read() yml, desc = text.split("---") data = yaml.safe_load(yml) data["description"] = desc self.validate(data) item = QtWidgets.QListWidgetItem() item.setText(data["title"]) item.setData(self.data_role, data) self.left_list.addItem(item) self.left_list.setCurrentRow(0) def validate(self, module) -> bool: type_dict = { 'title': str, 'brief': str, 'website': str, 'dependencies': list, 'repo': str, 'copyright_owner': list, 'gr_supported_version': list, 'tags': list, 'license': str, 'description': str, 'author': list } valid = True for key, val in type_dict.items(): if key in module: if not type(module.get(key)) == val: log.error( f"OOT module {module.get('title')} has field {key}, but it's not the correct type. Expected {val}, got {type(module.get(key))}. Ignoring") valid = False else: log.error(f"OOT module {module.get('title')} is missing field {key}. Ignoring") valid = False return valid def populate_right_view(self): module = self.left_list.currentItem().data(self.data_role) self.title_label.setText(f"{module.get('title')}") self.version_label.setText(f"Version: {module.get('version')}") self.brief_label.setText(module.get("brief")) if module.get('website'): self.website_label.setText(f"**Website:** {module.get('website')}") else: self.website_label.setText(f'**Website:** None') if module.get("dependencies"): self.dep_label.setText(f"Dependencies: {'; '.join(module.get('dependencies'))}") else: self.dep_label.setText("Dependencies: None") if module.get('repo'): self.repo_label.setText(f"**Repository:** {module.get('repo')}") else: self.repo_label.setText(f'**Repository:** None') if module.get("copyright_owner"): self.copyright_label.setText(f"Copyright Owner: {', '.join(module.get('copyright_owner'))}") else: self.copyright_label.setText("Copyright Owner: None") if type(module.get('gr_supported_version')) == list: self.supp_ver_label.setText( f"Supported GNU Radio Versions: {', '.join(module.get('gr_supported_version'))}") else: self.supp_ver_label.setText("Supported GNU Radio Versions: N/A") log.error(f"module {module.get('title')} has invalid manifest field gr_supported_version") self.tags_label.setText(f"Tags: {'; '.join(module.get('tags'))}") self.license_label.setText(f"License: {module.get('license')}") self.desc_label.setMarkdown("\n" + module.get("description").replace("\t", "")) self.author_label.setText(f"**Author(s):** {', '.join(module.get('author'))}")