src/eric7/PipInterface/PipLicensesDialog.py

branch
eric7
changeset 9221
bf71ee032bb4
parent 9209
b99e7fd55fd3
child 9264
18a7312cfdb3
child 9413
80c06d472826
equal deleted inserted replaced
9220:e9e7eca7efee 9221:bf71ee032bb4
21 21
22 class PipLicensesDialog(QDialog, Ui_PipLicensesDialog): 22 class PipLicensesDialog(QDialog, Ui_PipLicensesDialog):
23 """ 23 """
24 Class implementing a dialog to show the licenses of an environment. 24 Class implementing a dialog to show the licenses of an environment.
25 """ 25 """
26
26 LicensesPackageColumn = 0 27 LicensesPackageColumn = 0
27 LicensesVersionColumn = 1 28 LicensesVersionColumn = 1
28 LicensesLicenseColumn = 2 29 LicensesLicenseColumn = 2
29 30
30 SummaryCountColumn = 0 31 SummaryCountColumn = 0
31 SummaryLicenseColumn = 1 32 SummaryLicenseColumn = 1
32 33
33 def __init__(self, pip, environment, localPackages=True, usersite=False, 34 def __init__(
34 parent=None): 35 self, pip, environment, localPackages=True, usersite=False, parent=None
36 ):
35 """ 37 """
36 Constructor 38 Constructor
37 39
38 @param pip reference to the pip interface object 40 @param pip reference to the pip interface object
39 @type Pip 41 @type Pip
40 @param environment name of the environment to show the licenses for 42 @param environment name of the environment to show the licenses for
41 @type str 43 @type str
42 @param localPackages flag indicating to show the licenses for local 44 @param localPackages flag indicating to show the licenses for local
48 @param parent reference to the parent widget (defaults to None) 50 @param parent reference to the parent widget (defaults to None)
49 @type QWidget (optional) 51 @type QWidget (optional)
50 """ 52 """
51 super().__init__(parent) 53 super().__init__(parent)
52 self.setupUi(self) 54 self.setupUi(self)
53 55
54 self.__pip = pip 56 self.__pip = pip
55 self.__environment = environment 57 self.__environment = environment
56 58
57 self.__allFilter = self.tr("<All>") 59 self.__allFilter = self.tr("<All>")
58 60
59 self.__saveCSVButton = self.buttonBox.addButton( 61 self.__saveCSVButton = self.buttonBox.addButton(
60 self.tr("Save as CSV..."), QDialogButtonBox.ButtonRole.ActionRole) 62 self.tr("Save as CSV..."), QDialogButtonBox.ButtonRole.ActionRole
63 )
61 self.__saveCSVButton.clicked.connect(self.__saveAsCSV) 64 self.__saveCSVButton.clicked.connect(self.__saveAsCSV)
62 65
63 self.buttonBox.button( 66 self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setDefault(True)
64 QDialogButtonBox.StandardButton.Close).setDefault(True) 67
65
66 self.localCheckBox.setChecked(localPackages) 68 self.localCheckBox.setChecked(localPackages)
67 self.userCheckBox.setChecked(usersite) 69 self.userCheckBox.setChecked(usersite)
68 70
69 self.localCheckBox.toggled.connect(self.__refreshLicenses) 71 self.localCheckBox.toggled.connect(self.__refreshLicenses)
70 self.userCheckBox.toggled.connect(self.__refreshLicenses) 72 self.userCheckBox.toggled.connect(self.__refreshLicenses)
71 73
72 if environment: 74 if environment:
73 self.environmentLabel.setText("<b>{0}</b>".format( 75 self.environmentLabel.setText(
74 self.tr('Licenses of "{0}"').format(environment) 76 "<b>{0}</b>".format(self.tr('Licenses of "{0}"').format(environment))
75 )) 77 )
76 else: 78 else:
77 # That should never happen; play it safe. 79 # That should never happen; play it safe.
78 self.environmentLabel.setText(self.tr("No environment specified.")) 80 self.environmentLabel.setText(self.tr("No environment specified."))
79 81
80 self.licenseFilterComboBox.currentTextChanged.connect( 82 self.licenseFilterComboBox.currentTextChanged.connect(
81 self.__filterPackagesByLicense) 83 self.__filterPackagesByLicense
82 84 )
85
83 self.__refreshLicenses() 86 self.__refreshLicenses()
84 87
85 @pyqtSlot() 88 @pyqtSlot()
86 def __refreshLicenses(self): 89 def __refreshLicenses(self):
87 """ 90 """
88 Private slot to refresh the license lists. 91 Private slot to refresh the license lists.
89 """ 92 """
90 with EricOverrideCursor(): 93 with EricOverrideCursor():
91 self.licensesList.clear() 94 self.licensesList.clear()
92 self.summaryList.clear() 95 self.summaryList.clear()
93 self.licenseFilterComboBox.clear() 96 self.licenseFilterComboBox.clear()
94 97
95 licensesForFilter = set() 98 licensesForFilter = set()
96 99
97 # step 1: show the licenses per package 100 # step 1: show the licenses per package
98 self.licensesList.setUpdatesEnabled(False) 101 self.licensesList.setUpdatesEnabled(False)
99 licenses = self.__pip.getLicenses( 102 licenses = self.__pip.getLicenses(
100 self.__environment, 103 self.__environment,
101 localPackages=self.localCheckBox.isChecked(), 104 localPackages=self.localCheckBox.isChecked(),
102 usersite=self.userCheckBox.isChecked(), 105 usersite=self.userCheckBox.isChecked(),
103 ) 106 )
104 for lic in licenses: 107 for lic in licenses:
105 QTreeWidgetItem(self.licensesList, [ 108 QTreeWidgetItem(
106 lic["Name"], 109 self.licensesList,
107 lic["Version"], 110 [
108 lic["License"].replace("; ", "\n"), 111 lic["Name"],
109 ]) 112 lic["Version"],
110 113 lic["License"].replace("; ", "\n"),
114 ],
115 )
116
111 self.licensesList.sortItems( 117 self.licensesList.sortItems(
112 PipLicensesDialog.LicensesPackageColumn, 118 PipLicensesDialog.LicensesPackageColumn, Qt.SortOrder.AscendingOrder
113 Qt.SortOrder.AscendingOrder) 119 )
114 for col in range(self.licensesList.columnCount()): 120 for col in range(self.licensesList.columnCount()):
115 self.licensesList.resizeColumnToContents(col) 121 self.licensesList.resizeColumnToContents(col)
116 self.licensesList.setUpdatesEnabled(True) 122 self.licensesList.setUpdatesEnabled(True)
117 123
118 # step 2: show the licenses summary 124 # step 2: show the licenses summary
119 self.summaryList.setUpdatesEnabled(False) 125 self.summaryList.setUpdatesEnabled(False)
120 licenses = self.__pip.getLicensesSummary( 126 licenses = self.__pip.getLicensesSummary(
121 self.__environment, 127 self.__environment,
122 localPackages=self.localCheckBox.isChecked(), 128 localPackages=self.localCheckBox.isChecked(),
123 usersite=self.userCheckBox.isChecked(), 129 usersite=self.userCheckBox.isChecked(),
124 ) 130 )
125 for lic in licenses: 131 for lic in licenses:
126 QTreeWidgetItem(self.summaryList, [ 132 QTreeWidgetItem(
127 "{0:4d}".format(lic["Count"]), 133 self.summaryList,
128 lic["License"].replace("; ", "\n"), 134 [
129 ]) 135 "{0:4d}".format(lic["Count"]),
136 lic["License"].replace("; ", "\n"),
137 ],
138 )
130 licensesForFilter |= set(lic["License"].split("; ")) 139 licensesForFilter |= set(lic["License"].split("; "))
131 140
132 self.summaryList.sortItems( 141 self.summaryList.sortItems(
133 PipLicensesDialog.SummaryLicenseColumn, 142 PipLicensesDialog.SummaryLicenseColumn, Qt.SortOrder.AscendingOrder
134 Qt.SortOrder.AscendingOrder) 143 )
135 for col in range(self.summaryList.columnCount()): 144 for col in range(self.summaryList.columnCount()):
136 self.summaryList.resizeColumnToContents(col) 145 self.summaryList.resizeColumnToContents(col)
137 self.summaryList.setUpdatesEnabled(True) 146 self.summaryList.setUpdatesEnabled(True)
138 147
139 self.licenseFilterComboBox.addItems( 148 self.licenseFilterComboBox.addItems(
140 [self.__allFilter] + sorted(licensesForFilter)) 149 [self.__allFilter] + sorted(licensesForFilter)
141 150 )
151
142 enable = bool(self.licensesList.topLevelItemCount()) 152 enable = bool(self.licensesList.topLevelItemCount())
143 self.__saveCSVButton.setEnabled(enable) 153 self.__saveCSVButton.setEnabled(enable)
144 154
145 @pyqtSlot(str) 155 @pyqtSlot(str)
146 def __filterPackagesByLicense(self, licenseName): 156 def __filterPackagesByLicense(self, licenseName):
147 """ 157 """
148 Private slot to filter the list of packages by license. 158 Private slot to filter the list of packages by license.
149 159
150 @param licenseName license name 160 @param licenseName license name
151 @type str 161 @type str
152 """ 162 """
153 pattern = r"\b{0}".format(re.escape(licenseName)) 163 pattern = r"\b{0}".format(re.escape(licenseName))
154 if not licenseName.endswith((")", "]", "}")): 164 if not licenseName.endswith((")", "]", "}")):
158 itm = self.licensesList.topLevelItem(row) 168 itm = self.licensesList.topLevelItem(row)
159 if licenseName == self.__allFilter: 169 if licenseName == self.__allFilter:
160 itm.setHidden(False) 170 itm.setHidden(False)
161 else: 171 else:
162 itm.setHidden( 172 itm.setHidden(
163 regexp.search( 173 regexp.search(itm.text(PipLicensesDialog.LicensesLicenseColumn))
164 itm.text(PipLicensesDialog.LicensesLicenseColumn) 174 is None
165 ) is None 175 )
166 ) 176
167
168 @pyqtSlot() 177 @pyqtSlot()
169 def __saveAsCSV(self): 178 def __saveAsCSV(self):
170 """ 179 """
171 Private slot to save the license information as a CSV file. 180 Private slot to save the license information as a CSV file.
172 """ 181 """
173 import csv 182 import csv
174 183
175 fileName, selectedFilter = EricFileDialog.getSaveFileNameAndFilter( 184 fileName, selectedFilter = EricFileDialog.getSaveFileNameAndFilter(
176 self, 185 self,
177 self.tr("Save as CSV"), 186 self.tr("Save as CSV"),
178 os.path.expanduser("~"), 187 os.path.expanduser("~"),
179 self.tr("CSV Files (*.csv);;All Files (*)"), 188 self.tr("CSV Files (*.csv);;All Files (*)"),
180 None, 189 None,
181 EricFileDialog.DontConfirmOverwrite 190 EricFileDialog.DontConfirmOverwrite,
182 ) 191 )
183 if fileName: 192 if fileName:
184 ext = os.path.splitext(fileName)[1] 193 ext = os.path.splitext(fileName)[1]
185 if not ext: 194 if not ext:
186 ex = selectedFilter.split("(*")[1].split(")")[0] 195 ex = selectedFilter.split("(*")[1].split(")")[0]
187 if ex: 196 if ex:
188 fileName += ex 197 fileName += ex
189 198
190 try: 199 try:
191 with open(fileName, "w", newline="", 200 with open(fileName, "w", newline="", encoding="utf-8") as csvFile:
192 encoding="utf-8") as csvFile:
193 fieldNames = ["Name", "Version", "License"] 201 fieldNames = ["Name", "Version", "License"]
194 writer = csv.DictWriter(csvFile, fieldnames=fieldNames) 202 writer = csv.DictWriter(csvFile, fieldnames=fieldNames)
195 203
196 writer.writeheader() 204 writer.writeheader()
197 for row in range(self.licensesList.topLevelItemCount()): 205 for row in range(self.licensesList.topLevelItemCount()):
198 itm = self.licensesList.topLevelItem(row) 206 itm = self.licensesList.topLevelItem(row)
199 writer.writerow({ 207 writer.writerow(
200 "Name": itm.text(0), 208 {
201 "Version": itm.text(1), 209 "Name": itm.text(0),
202 "License": itm.text(2), 210 "Version": itm.text(1),
203 }) 211 "License": itm.text(2),
212 }
213 )
204 except OSError as err: 214 except OSError as err:
205 EricMessageBox.critical( 215 EricMessageBox.critical(
206 self, 216 self,
207 self.tr("Save as CSV"), 217 self.tr("Save as CSV"),
208 self.tr( 218 self.tr(
209 """<p>The license information could not be saved""" 219 """<p>The license information could not be saved"""
210 """ into the CSV file <b>{0}</b>.</p>""" 220 """ into the CSV file <b>{0}</b>.</p>"""
211 """<p>Reason: {1}</p>""" 221 """<p>Reason: {1}</p>"""
212 ).format(fileName, str(err)) 222 ).format(fileName, str(err)),
213 ) 223 )

eric ide

mercurial