PluginManager/PluginManager.py

changeset 3112
9485059ea9fa
parent 3036
30c81c9e88b8
child 3113
2780e230f129
equal deleted inserted replaced
3111:5366f0647f79 3112:9485059ea9fa
8 """ 8 """
9 9
10 import os 10 import os
11 import sys 11 import sys
12 import imp 12 import imp
13 13 import zipfile
14 from PyQt4.QtCore import pyqtSignal, QObject 14
15 from PyQt4.QtCore import pyqtSignal, QObject, QDate, QFile, QUrl, QIODevice
15 from PyQt4.QtGui import QPixmap 16 from PyQt4.QtGui import QPixmap
17 from PyQt4.QtNetwork import QNetworkAccessManager, QNetworkRequest, \
18 QNetworkReply
16 19
17 from E5Gui import E5MessageBox 20 from E5Gui import E5MessageBox
21
22 from E5Network.E5NetworkProxyFactory import proxyAuthenticationRequired
23 try:
24 from E5Network.E5SslErrorHandler import E5SslErrorHandler
25 SSL_AVAILABLE = True
26 except ImportError:
27 SSL_AVAILABLE = False
18 28
19 from .PluginExceptions import PluginPathError, PluginModulesError, \ 29 from .PluginExceptions import PluginPathError, PluginModulesError, \
20 PluginLoadError, PluginActivationError, PluginModuleFormatError, \ 30 PluginLoadError, PluginActivationError, PluginModuleFormatError, \
21 PluginClassFormatError 31 PluginClassFormatError
22 32
115 self.__insertPluginsPaths() 125 self.__insertPluginsPaths()
116 126
117 self.__loadPlugins() 127 self.__loadPlugins()
118 128
119 self.__checkPluginsDownloadDirectory() 129 self.__checkPluginsDownloadDirectory()
130
131 self.pluginRepositoryFile = \
132 os.path.join(Utilities.getConfigDir(), "PluginRepository")
133
134 # attributes for the network objects
135 self.__networkManager = QNetworkAccessManager(self)
136 self.__networkManager.proxyAuthenticationRequired.connect(
137 proxyAuthenticationRequired)
138 if SSL_AVAILABLE:
139 self.__sslErrorHandler = E5SslErrorHandler(self)
140 self.__networkManager.sslErrors.connect(self.__sslErrors)
141 self.__replies = []
120 142
121 def finalizeSetup(self): 143 def finalizeSetup(self):
122 """ 144 """
123 Public method to finalize the setup of the plugin manager. 145 Public method to finalize the setup of the plugin manager.
124 """ 146 """
1013 def preferencesChanged(self): 1035 def preferencesChanged(self):
1014 """ 1036 """
1015 Public slot to react to changes in configuration. 1037 Public slot to react to changes in configuration.
1016 """ 1038 """
1017 self.__checkPluginsDownloadDirectory() 1039 self.__checkPluginsDownloadDirectory()
1040
1041 ########################################################################
1042 ## Methods for automatic plug-in update check below
1043 ########################################################################
1044
1045 def checkPluginUpdatesAvailable(self):
1046 """
1047 Public method to check the availability of updates of plug-ins.
1048 """
1049 period = Preferences.getPluginManager("UpdatesCheckInterval")
1050 if period == 0:
1051 return
1052 elif period in [2, 3, 4]:
1053 lastCheck = Preferences.Prefs.settings.value(
1054 "PluginUpdates/LastCheckDate", QDate(1970, 1, 1))
1055 if lastCheck.isValid():
1056 now = QDate.currentDate()
1057 if period == 2 and lastCheck.day() == now.day():
1058 # daily
1059 return
1060 elif period == 3 and lastCheck.daysTo(now) < 7:
1061 # weekly
1062 return
1063 elif period == 4 and lastCheck.month() == now.month():
1064 # monthly
1065 return
1066
1067 self.__updateAvailable = False
1068
1069 request = QNetworkRequest(
1070 QUrl(Preferences.getUI("PluginRepositoryUrl5")))
1071 request.setAttribute(QNetworkRequest.CacheLoadControlAttribute,
1072 QNetworkRequest.AlwaysNetwork)
1073 reply = self.__networkManager.get(request)
1074 reply.finished[()].connect(self.__downloadFileDone)
1075 reply.downloadProgress.connect(self.__downloadRepositoryFileDone)
1076 self.__replies.append(reply)
1077
1078 def __downloadRepositoryFileDone(self):
1079 """
1080 Private method called after the repository file was downloaded.
1081 """
1082 reply = self.sender()
1083 if reply in self.__replies:
1084 self.__replies.remove(reply)
1085 if reply.error() != QNetworkReply.NoError:
1086 E5MessageBox.warning(
1087 None,
1088 self.trUtf8("Error downloading file"),
1089 self.trUtf8(
1090 """<p>Could not download the requested file"""
1091 """ from {0}.</p><p>Error: {1}</p>"""
1092 ).format(Preferences.getUI("PluginRepositoryUrl5"),
1093 reply.errorString())
1094 )
1095 return
1096
1097 ioDevice = QFile(self.pluginRepositoryFile + ".tmp")
1098 ioDevice.open(QIODevice.WriteOnly)
1099 ioDevice.write(reply.readAll())
1100 ioDevice.close()
1101 if QFile.exists(self.pluginRepositoryFile):
1102 QFile.remove(self.pluginRepositoryFile)
1103 ioDevice.rename(self.pluginRepositoryFile)
1104
1105 if os.path.exists(self.pluginRepositoryFile):
1106 f = QFile(self.pluginRepositoryFile)
1107 if f.open(QIODevice.ReadOnly):
1108 from E5XML.PluginRepositoryReader import PluginRepositoryReader
1109 reader = PluginRepositoryReader(f, self)
1110 reader.readXML()
1111 url = Preferences.getUI("PluginRepositoryUrl5")
1112 if url != self.repositoryUrlEdit.text():
1113 self.checkPluginUpdatesAvailable()
1114 return
1115 Preferences.Prefs.settings.setValue(
1116 "Updates/LastCheckDate", QDate.currentDate())
1117
1118 if self.__updateAvailable:
1119 E5MessageBox.information(
1120 None,
1121 self.trUtf8("New plugin versions available"),
1122 self.trUtf8("<p>There are new plugins or plugin"
1123 " updates available. Use the plugin"
1124 " repository dialog to get them.</p>")
1125 )
1126
1127 def addEntry(self, name, short, description, url, author, version,
1128 filename, status):
1129 """
1130 Public method to add an entry to the list.
1131
1132 @param name data for the name field (string)
1133 @param short data for the short field (string)
1134 @param description data for the description field (list of strings)
1135 @param url data for the url field (string)
1136 @param author data for the author field (string)
1137 @param version data for the version field (string)
1138 @param filename data for the filename field (string)
1139 @param status status of the plugin (string [stable, unstable, unknown])
1140 """
1141 archive = os.path.join(Preferences.getPluginManager("DownloadPath"),
1142 filename)
1143
1144 # check, if the archive exists
1145 if not os.path.exists(archive) and \
1146 not Preferences.getPluginManager("CheckInstalledOnly"):
1147 self.__updateAvailable = True
1148 return
1149
1150 # check, if the archive is a valid zip file
1151 if not zipfile.is_zipfile(archive) and \
1152 not Preferences.getPluginManager("CheckInstalledOnly"):
1153 self.__updateAvailable = True
1154 return
1155
1156 zip = zipfile.ZipFile(archive, "r")
1157 try:
1158 aversion = zip.read("VERSION").decode("utf-8")
1159 except KeyError:
1160 aversion = ""
1161 zip.close()
1162
1163 if aversion != version:
1164 self.__updateAvailable = True
1165
1166 def __sslErrors(self, reply, errors):
1167 """
1168 Private slot to handle SSL errors.
1169
1170 @param reply reference to the reply object (QNetworkReply)
1171 @param errors list of SSL errors (list of QSslError)
1172 """
1173 ignored = self.__sslErrorHandler.sslErrorsReply(reply, errors)[0]
1174 if ignored == E5SslErrorHandler.NotIgnored:
1175 self.__downloadCancelled = True
1176
1177 # TODO: test this stuff
1178 # TODO: update the config page

eric ide

mercurial