94 self.homePageUrlEdit.text().startswith(("http://", "https://")) |
94 self.homePageUrlEdit.text().startswith(("http://", "https://")) |
95 ) |
95 ) |
96 |
96 |
97 self.__okButton.setEnabled(enable) |
97 self.__okButton.setEnabled(enable) |
98 |
98 |
99 def __loadClassifiersFromPyPI(self): |
99 def __populateClassifiers(self): |
100 """ |
|
101 Private method to populate the classifiers list with data retrieved |
|
102 from PyPI. |
|
103 """ |
|
104 request = QNetworkRequest(QUrl(SetupWizardDialog.ClassifiersUrl)) |
|
105 request.setAttribute( |
|
106 QNetworkRequest.Attribute.CacheLoadControlAttribute, |
|
107 QNetworkRequest.CacheLoadControl.AlwaysNetwork) |
|
108 reply = ( |
|
109 ericApp().getObject("UserInterface").networkAccessManager() |
|
110 .get(request) |
|
111 ) |
|
112 reply.finished.connect(lambda: self.__classifiersDownloadDone(reply)) |
|
113 self.__replies.append(reply) |
|
114 |
|
115 @pyqtSlot() |
|
116 def __classifiersDownloadDone(self, reply): |
|
117 """ |
|
118 Private slot called, after the classifiers file has been downloaded |
|
119 from the internet. |
|
120 |
|
121 @param reply reference to the network reply |
|
122 @type QNetworkReply |
|
123 """ |
|
124 reply.deleteLater() |
|
125 if reply in self.__replies: |
|
126 self.__replies.remove(reply) |
|
127 if reply.error() == QNetworkReply.NetworkError.NoError: |
|
128 ioEncoding = Preferences.getSystem("IOEncoding") |
|
129 lines = str(reply.readAll(), ioEncoding, 'replace').splitlines() |
|
130 |
|
131 self.__populateClassifiers(lines) |
|
132 |
|
133 reply.close() |
|
134 |
|
135 @pyqtSlot() |
|
136 def on_localClassifiersButton_clicked(self): |
|
137 """ |
|
138 Private method to populate lists from the Trove list file. |
|
139 |
|
140 Note: The trove list file was created from querying |
|
141 "https://pypi.org/pypi?%3Aaction=list_classifiers". |
|
142 """ |
|
143 filename = os.path.join(os.path.dirname(__file__), |
|
144 "data", "trove_classifiers.txt") |
|
145 try: |
|
146 with open(filename, "r") as f: |
|
147 lines = f.readlines() |
|
148 except OSError as err: |
|
149 EricMessageBox.warning( |
|
150 self, |
|
151 self.tr("Reading Trove Classifiers"), |
|
152 self.tr("""<p>The Trove Classifiers file <b>{0}</b>""" |
|
153 """ could not be read.</p><p>Reason: {1}</p>""") |
|
154 .format(filename, str(err))) |
|
155 return |
|
156 |
|
157 self.__populateClassifiers(lines) |
|
158 |
|
159 def __populateClassifiers(self, classifiers): |
|
160 """ |
100 """ |
161 Private method to populate the classifiers. |
101 Private method to populate the classifiers. |
162 |
|
163 @param classifiers list of classifiers read from a local file or |
|
164 retrieved from PyPI |
|
165 @type list of str |
|
166 """ |
102 """ |
167 self.licenseClassifierComboBox.clear() |
103 self.licenseClassifierComboBox.clear() |
168 self.classifiersList.clear() |
104 self.classifiersList.clear() |
169 self.developmentStatusComboBox.clear() |
105 self.developmentStatusComboBox.clear() |
170 |
106 |
171 self.developmentStatusComboBox.addItem("", "") |
107 self.developmentStatusComboBox.addItem("", "") |
172 |
108 |
173 self.__classifiersDict = {} |
109 self.__classifiersDict = {} |
174 for line in classifiers: |
110 for classifier in trove_classifiers.sorted_classifiers: |
175 line = line.strip() |
111 if classifier.startswith("License ::"): |
176 if line.startswith("License "): |
|
177 self.licenseClassifierComboBox.addItem( |
112 self.licenseClassifierComboBox.addItem( |
178 "/".join(line.split(" :: ")[1:]), |
113 "/".join(classifier.split(" :: ")[1:]), |
179 line |
114 classifier |
180 ) |
115 ) |
181 elif line.startswith("Development Status "): |
116 elif classifier.startswith("Development Status ::"): |
182 self.developmentStatusComboBox.addItem( |
117 self.developmentStatusComboBox.addItem( |
183 line.split(" :: ")[1], line) |
118 classifier.split(" :: ")[1], classifier) |
184 else: |
119 else: |
185 self.__addClassifierEntry(line) |
120 self.__addClassifierEntry(classifier) |
186 self.__classifiersDict = {} |
121 self.__classifiersDict = {} |
187 |
122 |
188 self.licenseClassifierComboBox.setCurrentIndex( |
123 self.licenseClassifierComboBox.setCurrentIndex( |
189 self.licenseClassifierComboBox.findText( |
124 self.licenseClassifierComboBox.findText( |
190 "(GPLv3)", |
125 "(GPLv3)", |
191 Qt.MatchFlag.MatchContains | Qt.MatchFlag.MatchCaseSensitive |
126 Qt.MatchFlag.MatchContains | Qt.MatchFlag.MatchCaseSensitive |
192 ) |
127 ) |
193 ) |
128 ) |
194 |
129 |
195 def __addClassifierEntry(self, line): |
130 def __addClassifierEntry(self, classifier): |
196 """ |
131 """ |
197 Private method to add a new entry to the list of trove classifiers. |
132 Private method to add a new entry to the list of trove classifiers. |
198 |
133 |
199 @param line line containing the data for the entry (string) |
134 @param classifier classifier containing the data for the entry |
|
135 @type str |
200 """ |
136 """ |
201 itm = None |
137 itm = None |
202 pitm = None |
138 pitm = None |
203 dataList = line.split(" :: ") |
139 dataList = classifier.split(" :: ") |
204 for index in range(len(dataList)): |
140 for index in range(len(dataList)): |
205 key = " :: ".join(dataList[:index + 1]) |
141 key = " :: ".join(dataList[:index + 1]) |
206 if key not in self.__classifiersDict: |
142 if key not in self.__classifiersDict: |
207 if pitm is None: |
143 if pitm is None: |
208 itm = QTreeWidgetItem( |
144 itm = QTreeWidgetItem( |
248 i2string = (il + 2) * indString |
188 i2string = (il + 2) * indString |
249 estring = os.linesep + indLevel * indString |
189 estring = os.linesep + indLevel * indString |
250 |
190 |
251 # now generate the code |
191 # now generate the code |
252 if self.introCheckBox.isChecked(): |
192 if self.introCheckBox.isChecked(): |
253 code = "#!/usr/bin/env python3{0}".format(os.linesep) |
193 sourceCode = "#!/usr/bin/env python3{0}".format(os.linesep) |
254 code += "# -*- coding: utf-8 -*-{0}{0}".format(os.linesep) |
194 sourceCode += "# -*- coding: utf-8 -*-{0}{0}".format(os.linesep) |
255 else: |
195 else: |
256 code = "" |
196 sourceCode = "" |
257 |
197 |
258 if self.metaDataCheckBox.isChecked(): |
198 if self.metaDataCheckBox.isChecked(): |
259 code += '# metadata{0}'.format(os.linesep) |
199 sourceCode += '# metadata{0}'.format(os.linesep) |
260 code += '"{0}"{1}'.format( |
200 sourceCode += '"{0}"{1}'.format( |
261 self.summaryEdit.text() or "Setup routine", |
201 self.summaryEdit.text() or "Setup routine", |
262 os.linesep |
202 os.linesep |
263 ) |
203 ) |
264 code += '__version__ = "{0}"{1}'.format( |
204 sourceCode += '__version__ = "{0}"{1}'.format( |
265 self.versionEdit.text(), os.linesep) |
205 self.versionEdit.text(), os.linesep) |
266 code += '__license__ = "{0}"{1}'.format( |
206 sourceCode += '__license__ = "{0}"{1}'.format( |
267 self.__getLicenseText(), os.linesep) |
207 self.__getLicenseText(), os.linesep) |
268 code += '__author__ = "{0}"{1}'.format( |
208 sourceCode += '__author__ = "{0}"{1}'.format( |
269 self.authorEdit.text() or self.maintainerEdit.text(), |
209 self.authorEdit.text() or self.maintainerEdit.text(), |
270 os.linesep) |
210 os.linesep) |
271 code += '__email__ = "{0}"{1}'.format( |
211 sourceCode += '__email__ = "{0}"{1}'.format( |
272 self.authorEmailEdit.text() or self.maintainerEmailEdit.text(), |
212 self.authorEmailEdit.text() or self.maintainerEmailEdit.text(), |
273 os.linesep) |
213 os.linesep) |
274 code += '__url__ = "{0}"{1}'.format( |
214 sourceCode += '__url__ = "{0}"{1}'.format( |
275 self.homePageUrlEdit.text(), os.linesep) |
215 self.homePageUrlEdit.text(), os.linesep) |
276 code += '__date__ = "{0}"{1}'.format( |
216 sourceCode += '__date__ = "{0}"{1}'.format( |
277 datetime.datetime.now().isoformat().split('.')[0], os.linesep) |
217 datetime.datetime.now().isoformat().split('.')[0], os.linesep) |
278 code += '__prj__ = "{0}"{1}'.format( |
218 sourceCode += '__prj__ = "{0}"{1}'.format( |
279 self.nameEdit.text(), os.linesep) |
219 self.nameEdit.text(), os.linesep) |
280 code += os.linesep |
220 sourceCode += os.linesep |
281 |
221 |
282 if self.importCheckBox.isChecked(): |
222 if self.importCheckBox.isChecked(): |
283 additionalImport = ", find_packages" |
223 additionalImport = ", find_packages" |
284 code += "from setuptools import setup{0}{1}".format( |
224 sourceCode += "from setuptools import setup{0}{1}".format( |
285 additionalImport, os.linesep) |
225 additionalImport, os.linesep) |
286 if code: |
226 if sourceCode: |
287 code += "{0}{0}".format(os.linesep) |
227 sourceCode += "{0}{0}".format(os.linesep) |
288 |
228 |
289 if self.descriptionFromFilesCheckBox.isChecked(): |
229 if self.descriptionFromFilesCheckBox.isChecked(): |
290 code += 'def get_long_description():{0}'.format(os.linesep) |
230 sourceCode += 'def get_long_description():{0}'.format(os.linesep) |
291 code += '{0}descr = []{1}'.format(istring, os.linesep) |
231 sourceCode += '{0}descr = []{1}'.format(istring, os.linesep) |
292 code += '{0}for fname in "{1}":{2}'.format( |
232 sourceCode += '{0}for fname in "{1}":{2}'.format( |
293 istring, |
233 istring, |
294 '", "'.join(self.descriptionEdit.toPlainText().splitlines()), |
234 '", "'.join(self.descriptionEdit.toPlainText().splitlines()), |
295 os.linesep) |
235 os.linesep) |
296 code += '{0}{0}with open(fname) as f:{1}'.format( |
236 sourceCode += '{0}{0}with open(fname) as f:{1}'.format( |
297 istring, os.linesep) |
237 istring, os.linesep) |
298 code += '{0}{0}{0}descr.append(f.read()){1}'.format( |
238 sourceCode += '{0}{0}{0}descr.append(f.read()){1}'.format( |
299 istring, os.linesep) |
239 istring, os.linesep) |
300 code += '{0}return "\\n\\n".join(descr){1}'.format( |
240 sourceCode += '{0}return "\\n\\n".join(descr){1}'.format( |
301 istring, os.linesep) |
241 istring, os.linesep) |
302 code += "{0}{0}".format(os.linesep) |
242 sourceCode += "{0}{0}".format(os.linesep) |
303 |
243 |
304 code += 'setup({0}'.format(os.linesep) |
244 sourceCode += 'setup({0}'.format(os.linesep) |
305 code += '{0}name="{1}",{2}'.format( |
245 sourceCode += '{0}name="{1}",{2}'.format( |
306 istring, self.nameEdit.text(), os.linesep) |
246 istring, self.nameEdit.text(), os.linesep) |
307 code += '{0}version="{1}",{2}'.format( |
247 sourceCode += '{0}version="{1}",{2}'.format( |
308 istring, self.versionEdit.text(), os.linesep) |
248 istring, self.versionEdit.text(), os.linesep) |
309 |
249 |
310 if self.summaryEdit.text(): |
250 if self.summaryEdit.text(): |
311 code += '{0}description="{1}",{2}'.format( |
251 sourceCode += '{0}description="{1}",{2}'.format( |
312 istring, self.summaryEdit.text(), os.linesep) |
252 istring, self.summaryEdit.text(), os.linesep) |
313 |
253 |
314 if self.descriptionFromFilesCheckBox.isChecked(): |
254 if self.descriptionFromFilesCheckBox.isChecked(): |
315 code += '{0}long_description=get_long_description(),{1}'.format( |
255 sourceCode += '{0}long_description=get_long_description(),{1}'.format( |
316 istring, os.linesep) |
256 istring, os.linesep) |
317 elif self.descriptionEdit.toPlainText(): |
257 elif self.descriptionEdit.toPlainText(): |
318 code += '{0}long_description="""{1}""",{2}'.format( |
258 sourceCode += '{0}long_description="""{1}""",{2}'.format( |
319 istring, self.descriptionEdit.toPlainText(), os.linesep) |
259 istring, self.descriptionEdit.toPlainText(), os.linesep) |
320 |
260 |
321 if self.authorEdit.text(): |
261 if self.authorEdit.text(): |
322 code += '{0}author="{1}",{2}'.format( |
262 sourceCode += '{0}author="{1}",{2}'.format( |
323 istring, self.authorEdit.text(), os.linesep) |
263 istring, self.authorEdit.text(), os.linesep) |
324 code += '{0}author_email="{1}",{2}'.format( |
264 sourceCode += '{0}author_email="{1}",{2}'.format( |
325 istring, self.authorEmailEdit.text(), os.linesep) |
265 istring, self.authorEmailEdit.text(), os.linesep) |
326 |
266 |
327 if self.maintainerEdit.text(): |
267 if self.maintainerEdit.text(): |
328 code += '{0}maintainer="{1}",{2}'.format( |
268 sourceCode += '{0}maintainer="{1}",{2}'.format( |
329 istring, self.maintainerEdit.text(), os.linesep) |
269 istring, self.maintainerEdit.text(), os.linesep) |
330 code += '{0}maintainer_email="{1}",{2}'.format( |
270 sourceCode += '{0}maintainer_email="{1}",{2}'.format( |
331 istring, self.maintainerEmailEdit.text(), os.linesep) |
271 istring, self.maintainerEmailEdit.text(), os.linesep) |
332 |
272 |
333 code += '{0}url="{1}",{2}'.format( |
273 sourceCode += '{0}url="{1}",{2}'.format( |
334 istring, self.homePageUrlEdit.text(), os.linesep) |
274 istring, self.homePageUrlEdit.text(), os.linesep) |
335 if self.downloadUrlEdit.text(): |
275 if self.downloadUrlEdit.text(): |
336 code += '{0}download_url="{1}",{2}'.format( |
276 sourceCode += '{0}download_url="{1}",{2}'.format( |
337 istring, self.downloadUrlEdit.text(), os.linesep) |
277 istring, self.downloadUrlEdit.text(), os.linesep) |
338 |
278 |
339 classifiers = [] |
279 classifiers = [] |
340 if not self.licenseClassifierCheckBox.isChecked(): |
280 if not self.licenseClassifierCheckBox.isChecked(): |
341 code += '{0}license="{1}",{2}'.format( |
281 sourceCode += '{0}license="{1}",{2}'.format( |
342 istring, self.licenseEdit.text(), os.linesep) |
282 istring, self.licenseEdit.text(), os.linesep) |
343 else: |
283 else: |
344 classifiers.append( |
284 classifiers.append( |
345 self.licenseClassifierComboBox.itemData( |
285 self.licenseClassifierComboBox.itemData( |
346 self.licenseClassifierComboBox.currentIndex())) |
286 self.licenseClassifierComboBox.currentIndex())) |
347 |
287 |
348 platforms = self.platformsEdit.toPlainText().splitlines() |
288 platforms = self.platformsEdit.toPlainText().splitlines() |
349 if platforms: |
289 if platforms: |
350 code += '{0}platforms=[{1}'.format(istring, os.linesep) |
290 sourceCode += '{0}platforms=[{1}'.format(istring, os.linesep) |
351 code += '{0}"{1}"{2}'.format( |
291 sourceCode += '{0}"{1}"{2}'.format( |
352 i1string, |
292 i1string, |
353 '",{0}{1}"'.format(os.linesep, i1string).join(platforms), |
293 '",{0}{1}"'.format(os.linesep, i1string).join(platforms), |
354 os.linesep) |
294 os.linesep) |
355 code += '{0}],{1}'.format(istring, os.linesep) |
295 sourceCode += '{0}],{1}'.format(istring, os.linesep) |
356 |
296 |
357 if self.developmentStatusComboBox.currentIndex() != 0: |
297 if self.developmentStatusComboBox.currentIndex() != 0: |
358 classifiers.append( |
298 classifiers.append( |
359 self.developmentStatusComboBox.itemData( |
299 self.developmentStatusComboBox.itemData( |
360 self.developmentStatusComboBox.currentIndex())) |
300 self.developmentStatusComboBox.currentIndex())) |
367 itm = self.classifiersList.itemBelow(itm) |
307 itm = self.classifiersList.itemBelow(itm) |
368 |
308 |
369 # cleanup classifiers list - remove all invalid entries |
309 # cleanup classifiers list - remove all invalid entries |
370 classifiers = [c for c in classifiers if bool(c)] |
310 classifiers = [c for c in classifiers if bool(c)] |
371 if classifiers: |
311 if classifiers: |
372 code += '{0}classifiers=[{1}'.format(istring, os.linesep) |
312 sourceCode += '{0}classifiers=[{1}'.format(istring, os.linesep) |
373 code += '{0}"{1}"{2}'.format( |
313 sourceCode += '{0}"{1}"{2}'.format( |
374 i1string, |
314 i1string, |
375 '",{0}{1}"'.format(os.linesep, i1string).join(classifiers), |
315 '",{0}{1}"'.format(os.linesep, i1string).join(classifiers), |
376 os.linesep) |
316 os.linesep) |
377 code += '{0}],{1}'.format(istring, os.linesep) |
317 sourceCode += '{0}],{1}'.format(istring, os.linesep) |
378 del classifiers |
318 del classifiers |
379 |
319 |
380 if self.keywordsEdit.text(): |
320 if self.keywordsEdit.text(): |
381 code += '{0}keywords="{1}",{2}'.format( |
321 sourceCode += '{0}keywords="{1}",{2}'.format( |
382 istring, self.keywordsEdit.text(), os.linesep) |
322 istring, self.keywordsEdit.text(), os.linesep) |
383 |
323 |
384 code += '{0}packages=find_packages('.format(istring) |
324 sourceCode += '{0}packages=find_packages('.format(istring) |
385 src = Utilities.fromNativeSeparators( |
325 src = Utilities.fromNativeSeparators( |
386 self.sourceDirectoryPicker.text()) |
326 self.sourceDirectoryPicker.text()) |
387 excludePatterns = [] |
327 excludePatterns = [] |
388 for row in range(self.excludePatternList.count()): |
328 for row in range(self.excludePatternList.count()): |
389 excludePatterns.append( |
329 excludePatterns.append( |
390 self.excludePatternList.item(row).text()) |
330 self.excludePatternList.item(row).text()) |
391 if src: |
331 if src: |
392 code += '{0}{1}"{2}"'.format(os.linesep, i1string, src) |
332 sourceCode += '{0}{1}"{2}"'.format(os.linesep, i1string, src) |
393 if excludePatterns: |
333 if excludePatterns: |
394 code += ',' |
334 sourceCode += ',' |
395 else: |
335 else: |
396 code += '{0}{1}'.format(os.linesep, istring) |
336 sourceCode += '{0}{1}'.format(os.linesep, istring) |
397 if excludePatterns: |
337 if excludePatterns: |
398 code += '{0}{1}exclude=[{0}'.format(os.linesep, i1string) |
338 sourceCode += '{0}{1}exclude=[{0}'.format(os.linesep, i1string) |
399 code += '{0}"{1}"{2}'.format( |
339 sourceCode += '{0}"{1}"{2}'.format( |
400 i2string, |
340 i2string, |
401 '",{0}{1}"'.format(os.linesep, i2string) |
341 '",{0}{1}"'.format(os.linesep, i2string) |
402 .join(excludePatterns), |
342 .join(excludePatterns), |
403 os.linesep) |
343 os.linesep) |
404 code += '{0}]{1}{2}'.format(i1string, os.linesep, istring) |
344 sourceCode += '{0}]{1}{2}'.format(i1string, os.linesep, istring) |
405 code += '),{0}'.format(os.linesep) |
345 sourceCode += '),{0}'.format(os.linesep) |
406 |
346 |
407 if self.includePackageDataCheckBox.isChecked(): |
347 if self.includePackageDataCheckBox.isChecked(): |
408 code += '{0}include_package_data = True,{1}'.format( |
348 sourceCode += '{0}include_package_data = True,{1}'.format( |
409 istring, os.linesep) |
349 istring, os.linesep) |
410 |
350 |
411 modules = [] |
351 modules = [] |
412 for row in range(self.modulesList.count()): |
352 for row in range(self.modulesList.count()): |
413 modules.append(self.modulesList.item(row).text()) |
353 modules.append(self.modulesList.item(row).text()) |
414 if modules: |
354 if modules: |
415 code += '{0}py_modules=[{1}'.format(istring, os.linesep) |
355 sourceCode += '{0}py_modules=[{1}'.format(istring, os.linesep) |
416 code += '{0}"{1}"{2}'.format( |
356 sourceCode += '{0}"{1}"{2}'.format( |
417 i1string, |
357 i1string, |
418 '",{0}{1}"'.format(os.linesep, i1string).join(modules), |
358 '",{0}{1}"'.format(os.linesep, i1string).join(modules), |
419 os.linesep) |
359 os.linesep) |
420 code += '{0}],{1}'.format(istring, os.linesep) |
360 sourceCode += '{0}],{1}'.format(istring, os.linesep) |
421 del modules |
361 del modules |
422 |
362 |
423 scripts = [] |
363 scripts = [] |
424 for row in range(self.scriptsList.count()): |
364 for row in range(self.scriptsList.count()): |
425 scripts.append(self.scriptsList.item(row).text()) |
365 scripts.append(self.scriptsList.item(row).text()) |
426 if scripts: |
366 if scripts: |
427 code += '{0}scripts=[{1}'.format(istring, os.linesep) |
367 sourceCode += '{0}scripts=[{1}'.format(istring, os.linesep) |
428 code += '{0}"{1}"{2}'.format( |
368 sourceCode += '{0}"{1}"{2}'.format( |
429 i1string, |
369 i1string, |
430 '",{0}{1}"'.format(os.linesep, i1string).join(scripts), |
370 '",{0}{1}"'.format(os.linesep, i1string).join(scripts), |
431 os.linesep) |
371 os.linesep) |
432 code += '{0}],{1}'.format(istring, os.linesep) |
372 sourceCode += '{0}],{1}'.format(istring, os.linesep) |
433 del scripts |
373 del scripts |
434 |
374 |
435 code += "){0}".format(estring) |
375 sourceCode += "){0}".format(estring) |
436 return code |
376 return sourceCode |
437 |
377 |
438 @pyqtSlot() |
378 @pyqtSlot() |
439 def on_projectButton_clicked(self): |
379 def on_projectButton_clicked(self): |
440 """ |
380 """ |
441 Private slot to populate some fields with data retrieved from the |
381 Private slot to populate some fields with data retrieved from the |