eric7/CycloneDXInterface/CycloneDXMetaDataDialog.py

branch
eric7
changeset 9141
7085ece52151
child 9175
21e2be5f0b41
equal deleted inserted replaced
9140:6bbb4e047902 9141:7085ece52151
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2022 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing a dialog to edit the metadata of the CycloneDX SBOM.
8 """
9
10 import os
11
12 from PyQt6.QtCore import pyqtSlot, QCoreApplication
13 from PyQt6.QtWidgets import QDialog, QDialogButtonBox
14
15 from EricWidgets import EricMessageBox
16
17 from cyclonedx.model.component import ComponentType
18
19 from .Ui_CycloneDXMetaDataDialog import Ui_CycloneDXMetaDataDialog
20
21
22 class CycloneDXMetaDataDialog(QDialog, Ui_CycloneDXMetaDataDialog):
23 """
24 Class implementing a dialog to edit the metadata of the CycloneDX SBOM.
25 """
26 ComponentTypeMapping = {
27 ComponentType.APPLICATION: QCoreApplication.translate(
28 "CycloneDXMetaDataDialog", "Application"),
29 ComponentType.CONTAINER: QCoreApplication.translate(
30 "CycloneDXMetaDataDialog", "Container"),
31 ComponentType.DEVICE: QCoreApplication.translate(
32 "CycloneDXMetaDataDialog", "Device"),
33 ComponentType.FILE: QCoreApplication.translate(
34 "CycloneDXMetaDataDialog", "File"),
35 ComponentType.FIRMWARE: QCoreApplication.translate(
36 "CycloneDXMetaDataDialog", "Firmware"),
37 ComponentType.FRAMEWORK: QCoreApplication.translate(
38 "CycloneDXMetaDataDialog", "Framework"),
39 ComponentType.LIBRARY: QCoreApplication.translate(
40 "CycloneDXMetaDataDialog", "Library"),
41 ComponentType.OPERATING_SYSTEM: QCoreApplication.translate(
42 "CycloneDXMetaDataDialog", "Operating System"),
43 }
44
45 def __init__(self, metadata=None, parent=None):
46 """
47 Constructor
48
49 @param metadata dictionary containing metadata to populate the dialog
50 (defaults to None)
51 @type dict (optional)
52 @param parent reference to the parent widget (defaults to None)
53 @type QWidget (optional)
54 """
55 super().__init__(parent)
56 self.setupUi(self)
57
58 self.__populateComponentTypeSelector()
59 self.__populateLicenseSelector()
60
61 if metadata:
62 # populate the dialog from given metadata dictionary
63 self.nameEdit.setText(metadata["Name"])
64 self.versionEdit.setText(metadata["Version"])
65 self.descriptionEdit.setPlainText(metadata["Description"])
66 self.authorEdit.setText(metadata["AuthorName"])
67 self.emailEdit.setText(metadata["AuthorEmail"])
68 self.licenseComboBox.setCurrentText(metadata["License"])
69 self.manufacturerEdit.setText(metadata["Manufacturer"])
70 self.supplierEdit.setText(metadata["Supplier"])
71 index = self.typeComboBox.findData(metadata["Type"])
72 self.typeComboBox.setCurrentIndex(index)
73
74 self.nameEdit.textChanged.connect(self.__updateOkButton)
75 self.typeComboBox.currentTextChanged.connect(self.__updateOkButton)
76 self.licenseComboBox.currentTextChanged.connect(self.__updateOkButton)
77
78 self.__updateOkButton()
79
80 def __populateComponentTypeSelector(self):
81 """
82 Private method to populate the component type selector.
83 """
84 self.typeComboBox.addItem("", "")
85 for componentType, displayStr in sorted(
86 CycloneDXMetaDataDialog.ComponentTypeMapping.items(),
87 key=lambda x: x[1]
88 ):
89 self.typeComboBox.addItem(displayStr, componentType)
90
91 def __populateLicenseSelector(self):
92 """
93 Private method to populate the license selector with the list of trove
94 license types.
95
96 Note: The trove licanese list file was created from querying
97 "https://pypi.org/pypi?%3Aaction=list_classifiers".
98 """
99 filename = os.path.join(
100 os.path.dirname(__file__), "..", "data",
101 "trove_license_classifiers.txt")
102 try:
103 with open(filename, "r") as f:
104 lines = f.readlines()
105 except OSError as err:
106 EricMessageBox.warning(
107 self,
108 self.tr("Reading Trove License Classifiers"),
109 self.tr("""<p>The Trove License Classifiers file <b>{0}</b>"""
110 """ could not be read.</p><p>Reason: {1}</p>""")
111 .format(filename, str(err)))
112 return
113
114 self.licenseComboBox.addItem("")
115 self.licenseComboBox.addItems(sorted(
116 line.split("::")[-1].strip()
117 for line in lines
118 if line.startswith("License ") # play it safe
119 ))
120
121 @pyqtSlot()
122 def __updateOkButton(self):
123 """
124 Private slot to update the enabled state of the OK button.
125 """
126 self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setEnabled(
127 bool(self.nameEdit.text()) and
128 bool(self.typeComboBox.currentText()) and
129 bool(self.licenseComboBox.currentText())
130 )
131
132 def getMetaData(self):
133 """
134 Public method to get the entered data.
135
136 @return dictionary containing the metadata.
137 @rtype dict
138 """
139 return {
140 "Name": self.nameEdit.text(),
141 "Type": self.typeComboBox.currentData(),
142 "Version": self.versionEdit.text(),
143 "Description": self.descriptionEdit.toPlainText(),
144 "AuthorName": self.authorEdit.text(),
145 "AuthorEmail": self.emailEdit.text(),
146 "License": self.licenseComboBox.currentText(),
147 "Manufacturer": self.manufacturerEdit.text(),
148 "Supplier": self.supplierEdit.text(),
149 }

eric ide

mercurial