18 import urllib.parse as parse |
18 import urllib.parse as parse |
19 except (ImportError): |
19 except (ImportError): |
20 import urlparse as parse # __IGNORE_WARNING__ |
20 import urlparse as parse # __IGNORE_WARNING__ |
21 |
21 |
22 from PyQt5.QtCore import pyqtSlot, Qt, QDir, QFileInfo |
22 from PyQt5.QtCore import pyqtSlot, Qt, QDir, QFileInfo |
23 from PyQt5.QtWidgets import QWidget, QDialogButtonBox, QAbstractButton, \ |
23 from PyQt5.QtWidgets import ( |
24 QApplication, QDialog, QVBoxLayout |
24 QWidget, QDialogButtonBox, QAbstractButton, QApplication, QDialog, |
|
25 QVBoxLayout |
|
26 ) |
25 |
27 |
26 from E5Gui import E5FileDialog |
28 from E5Gui import E5FileDialog |
27 from E5Gui.E5MainWindow import E5MainWindow |
29 from E5Gui.E5MainWindow import E5MainWindow |
28 |
30 |
29 from .Ui_PluginInstallDialog import Ui_PluginInstallDialog |
31 from .Ui_PluginInstallDialog import Ui_PluginInstallDialog |
140 self.__finishButton.setEnabled(True) |
142 self.__finishButton.setEnabled(True) |
141 self.__closeButton.hide() |
143 self.__closeButton.hide() |
142 self.__cancelButton.show() |
144 self.__cancelButton.show() |
143 |
145 |
144 msg = self.tr( |
146 msg = self.tr( |
145 "Plugin ZIP-Archives:\n{0}\n\nDestination:\n{1} ({2})")\ |
147 "Plugin ZIP-Archives:\n{0}\n\nDestination:\n{1} ({2})" |
146 .format("\n".join(self.__createArchivesList()), |
148 ).format( |
147 self.destinationCombo.currentText(), |
149 "\n".join(self.__createArchivesList()), |
148 self.destinationCombo.itemData( |
150 self.destinationCombo.currentText(), |
149 self.destinationCombo.currentIndex()) |
151 self.destinationCombo.itemData( |
150 ) |
152 self.destinationCombo.currentIndex() |
|
153 ) |
|
154 ) |
151 self.summaryEdit.setPlainText(msg) |
155 self.summaryEdit.setPlainText(msg) |
152 |
156 |
153 @pyqtSlot() |
157 @pyqtSlot() |
154 def on_addArchivesButton_clicked(self): |
158 def on_addArchivesButton_clicked(self): |
155 """ |
159 """ |
266 if url[0].lower() == 'file': |
270 if url[0].lower() == 'file': |
267 archive = url[2] |
271 archive = url[2] |
268 |
272 |
269 # check, if the archive exists |
273 # check, if the archive exists |
270 if not os.path.exists(archive): |
274 if not os.path.exists(archive): |
271 return False, \ |
275 return ( |
|
276 False, |
272 self.tr( |
277 self.tr( |
273 """<p>The archive file <b>{0}</b> does not exist. """ |
278 """<p>The archive file <b>{0}</b> does not exist. """ |
274 """Aborting...</p>""").format(archive), \ |
279 """Aborting...</p>""").format(archive), |
275 False |
280 False |
|
281 ) |
276 |
282 |
277 # check, if the archive is a valid zip file |
283 # check, if the archive is a valid zip file |
278 if not zipfile.is_zipfile(archive): |
284 if not zipfile.is_zipfile(archive): |
279 return False, \ |
285 return ( |
|
286 False, |
280 self.tr( |
287 self.tr( |
281 """<p>The file <b>{0}</b> is not a valid plugin """ |
288 """<p>The file <b>{0}</b> is not a valid plugin """ |
282 """ZIP-archive. Aborting...</p>""").format(archive), \ |
289 """ZIP-archive. Aborting...</p>""").format(archive), |
283 False |
290 False |
|
291 ) |
284 |
292 |
285 # check, if the destination is writeable |
293 # check, if the destination is writeable |
286 if not os.access(destination, os.W_OK): |
294 if not os.access(destination, os.W_OK): |
287 return False, \ |
295 return ( |
|
296 False, |
288 self.tr( |
297 self.tr( |
289 """<p>The destination directory <b>{0}</b> is not """ |
298 """<p>The destination directory <b>{0}</b> is not """ |
290 """writeable. Aborting...</p>""").format(destination), \ |
299 """writeable. Aborting...</p>""").format(destination), |
291 False |
300 False |
|
301 ) |
292 |
302 |
293 zipFile = zipfile.ZipFile(archive, "r") |
303 zipFile = zipfile.ZipFile(archive, "r") |
294 |
304 |
295 # check, if the archive contains a valid plugin |
305 # check, if the archive contains a valid plugin |
296 pluginFound = False |
306 pluginFound = False |
346 doCompile = False |
360 doCompile = False |
347 elif line.startswith("# End-Of-Header"): |
361 elif line.startswith("# End-Of-Header"): |
348 break |
362 break |
349 |
363 |
350 if not packageName: |
364 if not packageName: |
351 return False, \ |
365 return ( |
|
366 False, |
352 self.tr( |
367 self.tr( |
353 """<p>The plugin module <b>{0}</b> does not contain """ |
368 """<p>The plugin module <b>{0}</b> does not contain """ |
354 """a 'packageName' attribute. Aborting...</p>""")\ |
369 """a 'packageName' attribute. Aborting...</p>""" |
355 .format(pluginFileName), \ |
370 ).format(pluginFileName), |
356 False |
371 False |
|
372 ) |
357 |
373 |
358 if pyqtApi < 2: |
374 if pyqtApi < 2: |
359 return False, \ |
375 return ( |
|
376 False, |
360 self.tr( |
377 self.tr( |
361 """<p>The plugin module <b>{0}</b> does not conform""" |
378 """<p>The plugin module <b>{0}</b> does not conform""" |
362 """ with the PyQt v2 API. Aborting...</p>""")\ |
379 """ with the PyQt v2 API. Aborting...</p>""" |
363 .format(pluginFileName), \ |
380 ).format(pluginFileName), |
364 False |
381 False |
|
382 ) |
365 |
383 |
366 # check, if it is a plugin, that collides with others |
384 # check, if it is a plugin, that collides with others |
367 if not os.path.exists(os.path.join(destination, pluginFileName)) and \ |
385 if ( |
368 packageName != "None" and \ |
386 not os.path.exists(os.path.join(destination, pluginFileName)) and |
369 os.path.exists(os.path.join(destination, packageName)): |
387 packageName != "None" and |
370 return False, \ |
388 os.path.exists(os.path.join(destination, packageName)) |
|
389 ): |
|
390 return ( |
|
391 False, |
371 self.tr("""<p>The plugin package <b>{0}</b> exists. """ |
392 self.tr("""<p>The plugin package <b>{0}</b> exists. """ |
372 """Aborting...</p>""")\ |
393 """Aborting...</p>""").format( |
373 .format(os.path.join(destination, packageName)), \ |
394 os.path.join(destination, packageName)), |
374 False |
395 False |
375 |
396 ) |
376 if os.path.exists(os.path.join(destination, pluginFileName)) and \ |
397 |
377 packageName != "None" and \ |
398 if ( |
378 not os.path.exists(os.path.join(destination, packageName)): |
399 os.path.exists(os.path.join(destination, pluginFileName)) and |
379 return False, \ |
400 packageName != "None" and |
|
401 not os.path.exists(os.path.join(destination, packageName)) |
|
402 ): |
|
403 return ( |
|
404 False, |
380 self.tr("""<p>The plugin module <b>{0}</b> exists. """ |
405 self.tr("""<p>The plugin module <b>{0}</b> exists. """ |
381 """Aborting...</p>""")\ |
406 """Aborting...</p>""").format( |
382 .format(os.path.join(destination, pluginFileName)), \ |
407 os.path.join(destination, pluginFileName)), |
383 False |
408 False |
|
409 ) |
384 |
410 |
385 activatePlugin = False |
411 activatePlugin = False |
386 if not self.__external: |
412 if not self.__external: |
387 activatePlugin = \ |
413 activatePlugin = ( |
388 not self.__pluginManager.isPluginLoaded( |
414 not self.__pluginManager.isPluginLoaded( |
389 installedPluginName) or \ |
415 installedPluginName) or |
390 (self.__pluginManager.isPluginLoaded(installedPluginName) and |
416 (self.__pluginManager.isPluginLoaded(installedPluginName) and |
391 self.__pluginManager.isPluginActive(installedPluginName)) |
417 self.__pluginManager.isPluginActive(installedPluginName)) |
|
418 ) |
392 # try to unload a plugin with the same name |
419 # try to unload a plugin with the same name |
393 self.__pluginManager.unloadPlugin(installedPluginName) |
420 self.__pluginManager.unloadPlugin(installedPluginName) |
394 |
421 |
395 # uninstall existing plug-in first to get clean conditions |
422 # uninstall existing plug-in first to get clean conditions |
396 if packageName != "None" and \ |
423 if ( |
|
424 packageName != "None" and |
397 not os.path.exists( |
425 not os.path.exists( |
398 os.path.join(destination, packageName, "__init__.py")): |
426 os.path.join(destination, packageName, "__init__.py")) |
|
427 ): |
399 # package directory contains just data, don't delete it |
428 # package directory contains just data, don't delete it |
400 self.__uninstallPackage(destination, pluginFileName, "") |
429 self.__uninstallPackage(destination, pluginFileName, "") |
401 else: |
430 else: |
402 self.__uninstallPackage(destination, pluginFileName, packageName) |
431 self.__uninstallPackage(destination, pluginFileName, packageName) |
403 |
432 |
417 QApplication.processEvents() |
446 QApplication.processEvents() |
418 for name in namelist: |
447 for name in namelist: |
419 self.progress.setValue(prog) |
448 self.progress.setValue(prog) |
420 QApplication.processEvents() |
449 QApplication.processEvents() |
421 prog += 1 |
450 prog += 1 |
422 if name == pluginFileName or \ |
451 if ( |
423 name.startswith("{0}/".format(packageName)) or \ |
452 name == pluginFileName or |
424 name.startswith("{0}\\".format(packageName)): |
453 name.startswith("{0}/".format(packageName)) or |
|
454 name.startswith("{0}\\".format(packageName)) |
|
455 ): |
425 outname = name.replace("/", os.sep) |
456 outname = name.replace("/", os.sep) |
426 outname = os.path.join(destination, outname) |
457 outname = os.path.join(destination, outname) |
427 if outname.endswith("/") or outname.endswith("\\"): |
458 if outname.endswith("/") or outname.endswith("\\"): |
428 # it is a directory entry |
459 # it is a directory entry |
429 outname = outname[:-1] |
460 outname = outname[:-1] |
447 f.write(pluginSource) |
478 f.write(pluginSource) |
448 f.close() |
479 f.close() |
449 self.__installedFiles.append(outname) |
480 self.__installedFiles.append(outname) |
450 except os.error as why: |
481 except os.error as why: |
451 self.__rollback() |
482 self.__rollback() |
452 return False, \ |
483 return ( |
453 self.tr( |
484 False, |
454 "Error installing plugin. Reason: {0}").format(str(why)), \ |
485 self.tr( |
455 False |
486 "Error installing plugin. Reason: {0}").format(str(why)), |
|
487 False |
|
488 ) |
456 except IOError as why: |
489 except IOError as why: |
457 self.__rollback() |
490 self.__rollback() |
458 return False, \ |
491 return ( |
459 self.tr( |
492 False, |
460 "Error installing plugin. Reason: {0}").format(str(why)), \ |
493 self.tr( |
461 False |
494 "Error installing plugin. Reason: {0}").format(str(why)), |
|
495 False |
|
496 ) |
462 except OSError as why: |
497 except OSError as why: |
463 self.__rollback() |
498 self.__rollback() |
464 return False, \ |
499 return ( |
465 self.tr( |
500 False, |
466 "Error installing plugin. Reason: {0}").format(str(why)), \ |
501 self.tr( |
467 False |
502 "Error installing plugin. Reason: {0}").format(str(why)), |
|
503 False |
|
504 ) |
468 except Exception: |
505 except Exception: |
469 sys.stderr.write("Unspecific exception installing plugin.\n") |
506 sys.stderr.write("Unspecific exception installing plugin.\n") |
470 self.__rollback() |
507 self.__rollback() |
471 return False, \ |
508 return ( |
472 self.tr("Unspecific exception installing plugin."), \ |
509 False, |
473 False |
510 self.tr("Unspecific exception installing plugin."), |
|
511 False |
|
512 ) |
474 |
513 |
475 # now compile the plugins |
514 # now compile the plugins |
476 if doCompile: |
515 if doCompile: |
477 dirName = os.path.join(destination, packageName) |
516 dirName = os.path.join(destination, packageName) |
478 files = os.path.join(destination, pluginFileName) |
517 files = os.path.join(destination, pluginFileName) |