13 import os |
13 import os |
14 import zipfile |
14 import zipfile |
15 import glob |
15 import glob |
16 import re |
16 import re |
17 |
17 |
18 from PyQt5.QtCore import pyqtSignal, pyqtSlot, Qt, QFile, QIODevice, QUrl, \ |
18 from PyQt5.QtCore import ( |
19 QProcess, QPoint, QCoreApplication |
19 pyqtSignal, pyqtSlot, Qt, QFile, QIODevice, QUrl, QProcess, QPoint, |
20 from PyQt5.QtWidgets import QWidget, QDialogButtonBox, QAbstractButton, \ |
20 QCoreApplication |
21 QTreeWidgetItem, QDialog, QVBoxLayout, QMenu |
21 ) |
22 from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest, \ |
22 from PyQt5.QtWidgets import ( |
23 QNetworkReply, QNetworkConfigurationManager |
23 QWidget, QDialogButtonBox, QAbstractButton, QTreeWidgetItem, QDialog, |
|
24 QVBoxLayout, QMenu |
|
25 ) |
|
26 from PyQt5.QtNetwork import ( |
|
27 QNetworkAccessManager, QNetworkRequest, QNetworkReply, |
|
28 QNetworkConfigurationManager |
|
29 ) |
24 |
30 |
25 from .Ui_PluginRepositoryDialog import Ui_PluginRepositoryDialog |
31 from .Ui_PluginRepositoryDialog import Ui_PluginRepositoryDialog |
26 |
32 |
27 from E5Gui import E5MessageBox |
33 from E5Gui import E5MessageBox |
28 from E5Gui.E5MainWindow import E5MainWindow |
34 from E5Gui.E5MainWindow import E5MainWindow |
95 QDialogButtonBox.ActionRole) |
101 QDialogButtonBox.ActionRole) |
96 self.__downloadInstallButton.setEnabled(False) |
102 self.__downloadInstallButton.setEnabled(False) |
97 self.__downloadCancelButton = self.buttonBox.addButton( |
103 self.__downloadCancelButton = self.buttonBox.addButton( |
98 self.tr("Cancel"), QDialogButtonBox.ActionRole) |
104 self.tr("Cancel"), QDialogButtonBox.ActionRole) |
99 self.__downloadCancelButton.setEnabled(False) |
105 self.__downloadCancelButton.setEnabled(False) |
100 self.__installButton = \ |
106 self.__installButton = self.buttonBox.addButton( |
101 self.buttonBox.addButton(self.tr("Close && Install"), |
107 self.tr("Close && Install"), QDialogButtonBox.ActionRole) |
102 QDialogButtonBox.ActionRole) |
|
103 self.__installButton.setEnabled(False) |
108 self.__installButton.setEnabled(False) |
104 self.__closeButton = self.buttonBox.button(QDialogButtonBox.Close) |
109 self.__closeButton = self.buttonBox.button(QDialogButtonBox.Close) |
105 self.__closeButton.setEnabled(True) |
110 self.__closeButton.setEnabled(True) |
106 |
111 |
107 self.repositoryUrlEdit.setText( |
112 self.repositoryUrlEdit.setText( |
121 self.tr("Show All"), self.__showAllPlugins) |
126 self.tr("Show All"), self.__showAllPlugins) |
122 self.__pluginContextMenu.addSeparator() |
127 self.__pluginContextMenu.addSeparator() |
123 self.__pluginContextMenu.addAction( |
128 self.__pluginContextMenu.addAction( |
124 self.tr("Cleanup Downloads"), self.__cleanupDownloads) |
129 self.tr("Cleanup Downloads"), self.__cleanupDownloads) |
125 |
130 |
126 self.pluginRepositoryFile = \ |
131 self.pluginRepositoryFile = os.path.join(Utilities.getConfigDir(), |
127 os.path.join(Utilities.getConfigDir(), "PluginRepository") |
132 "PluginRepository") |
128 |
133 |
129 # attributes for the network objects |
134 # attributes for the network objects |
130 self.__networkManager = QNetworkAccessManager(self) |
135 self.__networkManager = QNetworkAccessManager(self) |
131 self.__networkManager.proxyAuthenticationRequired.connect( |
136 self.__networkManager.proxyAuthenticationRequired.connect( |
132 proxyAuthenticationRequired) |
137 proxyAuthenticationRequired) |
134 self.__sslErrorHandler = E5SslErrorHandler(self) |
139 self.__sslErrorHandler = E5SslErrorHandler(self) |
135 self.__networkManager.sslErrors.connect(self.__sslErrors) |
140 self.__networkManager.sslErrors.connect(self.__sslErrors) |
136 self.__replies = [] |
141 self.__replies = [] |
137 |
142 |
138 if Preferences.getUI("DynamicOnlineCheck"): |
143 if Preferences.getUI("DynamicOnlineCheck"): |
139 self.__networkConfigurationManager = \ |
144 self.__networkConfigurationManager = ( |
140 QNetworkConfigurationManager(self) |
145 QNetworkConfigurationManager(self) |
|
146 ) |
141 self.__onlineStateChanged( |
147 self.__onlineStateChanged( |
142 self.__networkConfigurationManager.isOnline()) |
148 self.__networkConfigurationManager.isOnline()) |
143 self.__networkConfigurationManager.onlineStateChanged.connect( |
149 self.__networkConfigurationManager.onlineStateChanged.connect( |
144 self.__onlineStateChanged) |
150 self.__onlineStateChanged) |
145 else: |
151 else: |
612 if pluginName in self.__hiddenPlugins: |
618 if pluginName in self.__hiddenPlugins: |
613 return |
619 return |
614 |
620 |
615 if status == "stable": |
621 if status == "stable": |
616 if self.__stableItem is None: |
622 if self.__stableItem is None: |
617 self.__stableItem = \ |
623 self.__stableItem = QTreeWidgetItem( |
618 QTreeWidgetItem(self.repositoryList, |
624 self.repositoryList, [self.tr("Stable")]) |
619 [self.tr("Stable")]) |
|
620 self.__stableItem.setExpanded(True) |
625 self.__stableItem.setExpanded(True) |
621 parent = self.__stableItem |
626 parent = self.__stableItem |
622 elif status == "unstable": |
627 elif status == "unstable": |
623 if self.__unstableItem is None: |
628 if self.__unstableItem is None: |
624 self.__unstableItem = \ |
629 self.__unstableItem = QTreeWidgetItem( |
625 QTreeWidgetItem(self.repositoryList, |
630 self.repositoryList, [self.tr("Unstable")]) |
626 [self.tr("Unstable")]) |
|
627 self.__unstableItem.setExpanded(True) |
631 self.__unstableItem.setExpanded(True) |
628 parent = self.__unstableItem |
632 parent = self.__unstableItem |
629 elif status == "obsolete": |
633 elif status == "obsolete": |
630 if self.__obsoleteItem is None: |
634 if self.__obsoleteItem is None: |
631 self.__obsoleteItem = \ |
635 self.__obsoleteItem = QTreeWidgetItem( |
632 QTreeWidgetItem(self.repositoryList, |
636 self.repositoryList, [self.tr("Obsolete")]) |
633 [self.tr("Obsolete")]) |
|
634 self.__obsoleteItem.setExpanded(True) |
637 self.__obsoleteItem.setExpanded(True) |
635 parent = self.__obsoleteItem |
638 parent = self.__obsoleteItem |
636 else: |
639 else: |
637 if self.__unknownItem is None: |
640 if self.__unknownItem is None: |
638 self.__unknownItem = \ |
641 self.__unknownItem = QTreeWidgetItem( |
639 QTreeWidgetItem(self.repositoryList, |
642 self.repositoryList, [self.tr("Unknown")]) |
640 [self.tr("Unknown")]) |
|
641 self.__unknownItem.setExpanded(True) |
643 self.__unknownItem.setExpanded(True) |
642 parent = self.__unknownItem |
644 parent = self.__unknownItem |
643 itm = QTreeWidgetItem(parent, [name, version, short]) |
645 itm = QTreeWidgetItem(parent, [name, version, short]) |
644 |
646 |
645 itm.setData(0, PluginRepositoryWidget.UrlRole, url) |
647 itm.setData(0, PluginRepositoryWidget.UrlRole, url) |
685 archivesPattern = archive.rsplit('-', 1)[0] + "-*.zip" |
687 archivesPattern = archive.rsplit('-', 1)[0] + "-*.zip" |
686 if len(glob.glob(archivesPattern)) == 0: |
688 if len(glob.glob(archivesPattern)) == 0: |
687 # Check against installed/loaded plug-ins |
689 # Check against installed/loaded plug-ins |
688 pluginName = filename.rsplit('-', 1)[0] |
690 pluginName = filename.rsplit('-', 1)[0] |
689 pluginDetails = self.__pluginManager.getPluginDetails(pluginName) |
691 pluginDetails = self.__pluginManager.getPluginDetails(pluginName) |
690 if pluginDetails is None or \ |
692 if ( |
691 pluginDetails["moduleName"] != pluginName: |
693 pluginDetails is None or |
|
694 pluginDetails["moduleName"] != pluginName |
|
695 ): |
692 return PluginRepositoryWidget.PluginStatusNew |
696 return PluginRepositoryWidget.PluginStatusNew |
693 if pluginDetails["error"]: |
697 if pluginDetails["error"]: |
694 return PluginRepositoryWidget.PluginStatusError |
698 return PluginRepositoryWidget.PluginStatusError |
695 pluginVersionTuple = Globals.versionToTuple( |
699 pluginVersionTuple = Globals.versionToTuple( |
696 pluginDetails["version"])[:3] |
700 pluginDetails["version"])[:3] |
719 # Check against installed/loaded plug-ins |
723 # Check against installed/loaded plug-ins |
720 pluginName = filename.rsplit('-', 1)[0] |
724 pluginName = filename.rsplit('-', 1)[0] |
721 pluginDetails = self.__pluginManager.getPluginDetails(pluginName) |
725 pluginDetails = self.__pluginManager.getPluginDetails(pluginName) |
722 if pluginDetails is None: |
726 if pluginDetails is None: |
723 return PluginRepositoryWidget.PluginStatusLocalUpdate |
727 return PluginRepositoryWidget.PluginStatusLocalUpdate |
724 if Globals.versionToTuple(pluginDetails["version"])[:3] < \ |
728 if ( |
725 Globals.versionToTuple(version)[:3]: |
729 Globals.versionToTuple(pluginDetails["version"])[:3] < |
|
730 Globals.versionToTuple(version)[:3] |
|
731 ): |
726 return PluginRepositoryWidget.PluginStatusLocalUpdate |
732 return PluginRepositoryWidget.PluginStatusLocalUpdate |
727 else: |
733 else: |
728 return PluginRepositoryWidget.PluginStatusUpToDate |
734 return PluginRepositoryWidget.PluginStatusUpToDate |
729 else: |
735 else: |
730 return PluginRepositoryWidget.PluginStatusRemoteUpdate |
736 return PluginRepositoryWidget.PluginStatusRemoteUpdate |
903 |
909 |
904 args = [] |
910 args = [] |
905 args.append(applPath) |
911 args.append(applPath) |
906 args += self.cw.getDownloadedPlugins() |
912 args += self.cw.getDownloadedPlugins() |
907 |
913 |
908 if not os.path.isfile(applPath) or \ |
914 if ( |
909 not proc.startDetached(sys.executable, args): |
915 not os.path.isfile(applPath) or |
|
916 not proc.startDetached(sys.executable, args) |
|
917 ): |
910 E5MessageBox.critical( |
918 E5MessageBox.critical( |
911 self, |
919 self, |
912 self.tr('Process Generation Error'), |
920 self.tr('Process Generation Error'), |
913 self.tr( |
921 self.tr( |
914 '<p>Could not start the process.<br>' |
922 '<p>Could not start the process.<br>' |
953 for pluginFile in os.listdir(downloadPath): |
961 for pluginFile in os.listdir(downloadPath): |
954 if not os.path.isfile(os.path.join(downloadPath, pluginFile)): |
962 if not os.path.isfile(os.path.join(downloadPath, pluginFile)): |
955 continue |
963 continue |
956 |
964 |
957 try: |
965 try: |
958 pluginName, pluginVersion = \ |
966 pluginName, pluginVersion = ( |
959 pluginFile.replace(".zip", "").rsplit("-", 1) |
967 pluginFile.replace(".zip", "").rsplit("-", 1) |
|
968 ) |
960 pluginVersionList = re.split("[._-]", pluginVersion) |
969 pluginVersionList = re.split("[._-]", pluginVersion) |
961 for index in range(len(pluginVersionList)): |
970 for index in range(len(pluginVersionList)): |
962 try: |
971 try: |
963 pluginVersionList[index] = int(pluginVersionList[index]) |
972 pluginVersionList[index] = int(pluginVersionList[index]) |
964 except ValueError: |
973 except ValueError: |
978 # step 2: delete old entries |
987 # step 2: delete old entries |
979 hiddenPlugins = Preferences.getPluginManager("HiddenPlugins") |
988 hiddenPlugins = Preferences.getPluginManager("HiddenPlugins") |
980 for pluginName in downloads: |
989 for pluginName in downloads: |
981 downloads[pluginName].sort(key=lambda x: x[1]) |
990 downloads[pluginName].sort(key=lambda x: x[1]) |
982 |
991 |
983 if pluginName in hiddenPlugins and \ |
992 if ( |
984 not Preferences.getPluginManager("KeepHidden"): |
993 pluginName in hiddenPlugins and |
|
994 not Preferences.getPluginManager("KeepHidden") |
|
995 ): |
985 removeFiles = [f[0] for f in downloads[pluginName]] |
996 removeFiles = [f[0] for f in downloads[pluginName]] |
986 else: |
997 else: |
987 removeFiles = [f[0] for f in downloads[pluginName][ |
998 removeFiles = [f[0] for f in downloads[pluginName][ |
988 :-Preferences.getPluginManager("KeepGenerations")]] |
999 :-Preferences.getPluginManager("KeepGenerations")]] |
989 for removeFile in removeFiles: |
1000 for removeFile in removeFiles: |