11 try: |
11 try: |
12 str = unicode |
12 str = unicode |
13 except (NameError): |
13 except (NameError): |
14 pass |
14 pass |
15 |
15 |
16 from PyQt4.QtCore import pyqtSlot, pyqtSignal, Qt, QTime, QFile, QFileInfo, QUrl, \ |
16 from PyQt4.QtCore import pyqtSlot, pyqtSignal, Qt, QTime, QFile, QFileInfo, \ |
17 QIODevice, QCryptographicHash |
17 QUrl, QIODevice, QCryptographicHash |
18 from PyQt4.QtGui import QWidget, QPalette, QStyle, QDesktopServices, QDialog |
18 from PyQt4.QtGui import QWidget, QPalette, QStyle, QDesktopServices, QDialog |
19 from PyQt4.QtNetwork import QNetworkRequest, QNetworkReply |
19 from PyQt4.QtNetwork import QNetworkRequest, QNetworkReply |
20 |
20 |
21 from E5Gui import E5FileDialog |
21 from E5Gui import E5FileDialog |
22 |
22 |
48 download=False, parent=None, mainWindow=None): |
48 download=False, parent=None, mainWindow=None): |
49 """ |
49 """ |
50 Constructor |
50 Constructor |
51 |
51 |
52 @keyparam reply reference to the network reply object (QNetworkReply) |
52 @keyparam reply reference to the network reply object (QNetworkReply) |
53 @keyparam requestFilename flag indicating to ask the user for a filename (boolean) |
53 @keyparam requestFilename flag indicating to ask the user for a |
54 @keyparam webPage reference to the web page object the download originated |
54 filename (boolean) |
55 from (QWebPage) |
55 @keyparam webPage reference to the web page object the download |
|
56 originated from (QWebPage) |
56 @keyparam download flag indicating a download operation (boolean) |
57 @keyparam download flag indicating a download operation (boolean) |
57 @keyparam parent reference to the parent widget (QWidget) |
58 @keyparam parent reference to the parent widget (QWidget) |
58 @keyparam mainWindow reference to the main window (HelpWindow) |
59 @keyparam mainWindow reference to the main window (HelpWindow) |
59 """ |
60 """ |
60 super(DownloadItem, self).__init__(parent) |
61 super(DownloadItem, self).__init__(parent) |
64 p.setColor(QPalette.Text, Qt.darkGray) |
65 p.setColor(QPalette.Text, Qt.darkGray) |
65 self.infoLabel.setPalette(p) |
66 self.infoLabel.setPalette(p) |
66 |
67 |
67 self.progressBar.setMaximum(0) |
68 self.progressBar.setMaximum(0) |
68 |
69 |
69 self.__isFtpDownload = reply is not None and reply.url().scheme() == "ftp" |
70 self.__isFtpDownload = reply is not None and \ |
|
71 reply.url().scheme() == "ftp" |
70 |
72 |
71 self.tryAgainButton.setIcon(UI.PixmapCache.getIcon("restart.png")) |
73 self.tryAgainButton.setIcon(UI.PixmapCache.getIcon("restart.png")) |
72 self.tryAgainButton.setEnabled(False) |
74 self.tryAgainButton.setEnabled(False) |
73 self.tryAgainButton.setVisible(False) |
75 self.tryAgainButton.setVisible(False) |
74 self.stopButton.setIcon(UI.PixmapCache.getIcon("stopLoading.png")) |
76 self.stopButton.setIcon(UI.PixmapCache.getIcon("stopLoading.png")) |
107 |
109 |
108 self.__sha1Hash = QCryptographicHash(QCryptographicHash.Sha1) |
110 self.__sha1Hash = QCryptographicHash(QCryptographicHash.Sha1) |
109 self.__md5Hash = QCryptographicHash(QCryptographicHash.Md5) |
111 self.__md5Hash = QCryptographicHash(QCryptographicHash.Md5) |
110 |
112 |
111 if not requestFilename: |
113 if not requestFilename: |
112 self.__requestFilename = Preferences.getUI("RequestDownloadFilename") |
114 self.__requestFilename = \ |
|
115 Preferences.getUI("RequestDownloadFilename") |
113 |
116 |
114 self.__initialize() |
117 self.__initialize() |
115 |
118 |
116 def __initialize(self, tryAgain=False): |
119 def __initialize(self, tryAgain=False): |
117 """ |
120 """ |
152 self.__networkError() |
155 self.__networkError() |
153 self.__finished() |
156 self.__finished() |
154 |
157 |
155 def __getFileName(self): |
158 def __getFileName(self): |
156 """ |
159 """ |
157 Private method to get the filename to save to from the user. |
160 Private method to get the file name to save to from the user. |
158 |
|
159 @return flag indicating success (boolean) |
|
160 """ |
161 """ |
161 if self.__gettingFileName: |
162 if self.__gettingFileName: |
162 return |
163 return |
163 |
164 |
164 import Helpviewer.HelpWindow |
165 import Helpviewer.HelpWindow |
169 fileName = self.__fileName |
170 fileName = self.__fileName |
170 originalFileName = self.__originalFileName |
171 originalFileName = self.__originalFileName |
171 self.__toDownload = True |
172 self.__toDownload = True |
172 ask = False |
173 ask = False |
173 else: |
174 else: |
174 defaultFileName, originalFileName = self.__saveFileName(downloadDirectory) |
175 defaultFileName, originalFileName = \ |
|
176 self.__saveFileName(downloadDirectory) |
175 fileName = defaultFileName |
177 fileName = defaultFileName |
176 self.__originalFileName = originalFileName |
178 self.__originalFileName = originalFileName |
177 ask = True |
179 ask = True |
178 self.__autoOpen = False |
180 self.__autoOpen = False |
179 if not self.__toDownload: |
181 if not self.__toDownload: |
186 self) |
188 self) |
187 if dlg.exec_() == QDialog.Rejected or dlg.getAction() == "cancel": |
189 if dlg.exec_() == QDialog.Rejected or dlg.getAction() == "cancel": |
188 self.progressBar.setVisible(False) |
190 self.progressBar.setVisible(False) |
189 self.__reply.close() |
191 self.__reply.close() |
190 self.on_stopButton_clicked() |
192 self.on_stopButton_clicked() |
191 self.filenameLabel.setText(self.trUtf8("Download canceled: {0}").format( |
193 self.filenameLabel.setText( |
192 QFileInfo(defaultFileName).fileName())) |
194 self.trUtf8("Download canceled: {0}").format( |
|
195 QFileInfo(defaultFileName).fileName())) |
193 self.__canceledFileSelect = True |
196 self.__canceledFileSelect = True |
194 return |
197 return |
195 |
198 |
196 if dlg.getAction() == "scan": |
199 if dlg.getAction() == "scan": |
197 self.__mainWindow.requestVirusTotalScan(url) |
200 self.__mainWindow.requestVirusTotalScan(url) |
204 QFileInfo(defaultFileName).fileName())) |
207 QFileInfo(defaultFileName).fileName())) |
205 self.__canceledFileSelect = True |
208 self.__canceledFileSelect = True |
206 return |
209 return |
207 |
210 |
208 self.__autoOpen = dlg.getAction() == "open" |
211 self.__autoOpen = dlg.getAction() == "open" |
209 fileName = QDesktopServices.storageLocation(QDesktopServices.TempLocation) + \ |
212 fileName = QDesktopServices.storageLocation( |
210 '/' + QFileInfo(fileName).completeBaseName() |
213 QDesktopServices.TempLocation) + \ |
|
214 '/' + QFileInfo(fileName).completeBaseName() |
211 |
215 |
212 if ask and not self.__autoOpen and self.__requestFilename: |
216 if ask and not self.__autoOpen and self.__requestFilename: |
213 self.__gettingFileName = True |
217 self.__gettingFileName = True |
214 fileName = E5FileDialog.getSaveFileName( |
218 fileName = E5FileDialog.getSaveFileName( |
215 None, |
219 None, |
219 self.__gettingFileName = False |
223 self.__gettingFileName = False |
220 if not fileName: |
224 if not fileName: |
221 self.progressBar.setVisible(False) |
225 self.progressBar.setVisible(False) |
222 self.__reply.close() |
226 self.__reply.close() |
223 self.on_stopButton_clicked() |
227 self.on_stopButton_clicked() |
224 self.filenameLabel.setText(self.trUtf8("Download canceled: {0}")\ |
228 self.filenameLabel.setText( |
225 .format(QFileInfo(defaultFileName).fileName())) |
229 self.trUtf8("Download canceled: {0}")\ |
|
230 .format(QFileInfo(defaultFileName).fileName())) |
226 self.__canceledFileSelect = True |
231 self.__canceledFileSelect = True |
227 return |
232 return |
228 |
233 |
229 fileInfo = QFileInfo(fileName) |
234 fileInfo = QFileInfo(fileName) |
230 Helpviewer.HelpWindow.HelpWindow.downloadManager().setDownloadDirectory( |
235 Helpviewer.HelpWindow.HelpWindow.downloadManager()\ |
231 fileInfo.absoluteDir().absolutePath()) |
236 .setDownloadDirectory(fileInfo.absoluteDir().absolutePath()) |
232 self.filenameLabel.setText(fileInfo.fileName()) |
237 self.filenameLabel.setText(fileInfo.fileName()) |
233 |
238 |
234 self.__output.setFileName(fileName + ".part") |
239 self.__output.setFileName(fileName + ".part") |
235 self.__fileName = fileName |
240 self.__fileName = fileName |
236 |
241 |
238 saveDirPath = QFileInfo(self.__fileName).dir() |
243 saveDirPath = QFileInfo(self.__fileName).dir() |
239 if not saveDirPath.exists(): |
244 if not saveDirPath.exists(): |
240 if not saveDirPath.mkpath(saveDirPath.absolutePath()): |
245 if not saveDirPath.mkpath(saveDirPath.absolutePath()): |
241 self.progressBar.setVisible(False) |
246 self.progressBar.setVisible(False) |
242 self.on_stopButton_clicked() |
247 self.on_stopButton_clicked() |
243 self.infoLabel.setText( |
248 self.infoLabel.setText(self.trUtf8( |
244 self.trUtf8("Download directory ({0}) couldn't be created.")\ |
249 "Download directory ({0}) couldn't be created.")\ |
245 .format(saveDirPath.absolutePath())) |
250 .format(saveDirPath.absolutePath())) |
246 return |
251 return |
247 |
252 |
248 self.filenameLabel.setText(QFileInfo(self.__fileName).fileName()) |
253 self.filenameLabel.setText(QFileInfo(self.__fileName).fileName()) |
249 if self.__requestFilename: |
254 if self.__requestFilename: |
256 @param directory name of the directory to store the file into (string) |
261 @param directory name of the directory to store the file into (string) |
257 @return proposed filename and original filename (string, string) |
262 @return proposed filename and original filename (string, string) |
258 """ |
263 """ |
259 path = "" |
264 path = "" |
260 if self.__reply.hasRawHeader("Content-Disposition"): |
265 if self.__reply.hasRawHeader("Content-Disposition"): |
261 header = bytes(self.__reply.rawHeader("Content-Disposition")).decode() |
266 header = bytes(self.__reply.rawHeader("Content-Disposition"))\ |
|
267 .decode() |
262 if header: |
268 if header: |
263 pos = header.find("filename=") |
269 pos = header.find("filename=") |
264 if pos != -1: |
270 if pos != -1: |
265 path = header[pos + 9:] |
271 path = header[pos + 9:] |
266 if path.startswith('"') and path.endswith('"'): |
272 if path.startswith('"') and path.endswith('"'): |
413 if not self.__output.isOpen(): |
419 if not self.__output.isOpen(): |
414 # in case someone else has already put a file there |
420 # in case someone else has already put a file there |
415 if not self.__requestFilename: |
421 if not self.__requestFilename: |
416 self.__getFileName() |
422 self.__getFileName() |
417 if not self.__output.open(QIODevice.WriteOnly): |
423 if not self.__output.open(QIODevice.WriteOnly): |
418 self.infoLabel.setText(self.trUtf8("Error opening save file: {0}")\ |
424 self.infoLabel.setText( |
|
425 self.trUtf8("Error opening save file: {0}")\ |
419 .format(self.__output.errorString())) |
426 .format(self.__output.errorString())) |
420 self.on_stopButton_clicked() |
427 self.on_stopButton_clicked() |
421 self.statusChanged.emit() |
428 self.statusChanged.emit() |
422 return |
429 return |
423 self.statusChanged.emit() |
430 self.statusChanged.emit() |
451 """ |
458 """ |
452 locationHeader = self.__reply.header(QNetworkRequest.LocationHeader) |
459 locationHeader = self.__reply.header(QNetworkRequest.LocationHeader) |
453 if locationHeader and locationHeader.isValid(): |
460 if locationHeader and locationHeader.isValid(): |
454 self.__url = QUrl(locationHeader) |
461 self.__url = QUrl(locationHeader) |
455 import Helpviewer.HelpWindow |
462 import Helpviewer.HelpWindow |
456 self.__reply = Helpviewer.HelpWindow.HelpWindow.networkAccessManager().get( |
463 self.__reply = Helpviewer.HelpWindow.HelpWindow\ |
457 QNetworkRequest(self.__url)) |
464 .networkAccessManager().get(QNetworkRequest(self.__url)) |
458 self.__initialize() |
465 self.__initialize() |
459 |
466 |
460 def __downloadProgress(self, bytesReceived, bytesTotal): |
467 def __downloadProgress(self, bytesReceived, bytesTotal): |
461 """ |
468 """ |
462 Private method to show the download progress. |
469 Private method to show the download progress. |
482 Public method to get the total number of bytes of the download. |
489 Public method to get the total number of bytes of the download. |
483 |
490 |
484 @return total number of bytes (integer) |
491 @return total number of bytes (integer) |
485 """ |
492 """ |
486 if self.__bytesTotal == -1: |
493 if self.__bytesTotal == -1: |
487 self.__bytesTotal = self.__reply.header(QNetworkRequest.ContentLengthHeader) |
494 self.__bytesTotal = self.__reply.header( |
|
495 QNetworkRequest.ContentLengthHeader) |
488 if self.__bytesTotal is None: |
496 if self.__bytesTotal is None: |
489 self.__bytesTotal = -1 |
497 self.__bytesTotal = -1 |
490 return self.__bytesTotal |
498 return self.__bytesTotal |
491 |
499 |
492 def bytesReceived(self): |
500 def bytesReceived(self): |
557 remaining) |
566 remaining) |
558 else: |
567 else: |
559 if self.__bytesReceived == bytesTotal or bytesTotal == -1: |
568 if self.__bytesReceived == bytesTotal or bytesTotal == -1: |
560 info = self.trUtf8("{0} downloaded\nSHA1: {1}\nMD5: {2}")\ |
569 info = self.trUtf8("{0} downloaded\nSHA1: {1}\nMD5: {2}")\ |
561 .format(dataString(self.__output.size()), |
570 .format(dataString(self.__output.size()), |
562 str(self.__sha1Hash.result().toHex(), encoding="ascii"), |
571 str(self.__sha1Hash.result().toHex(), |
563 str(self.__md5Hash.result().toHex(), encoding="ascii")) |
572 encoding="ascii"), |
|
573 str(self.__md5Hash.result().toHex(), |
|
574 encoding="ascii") |
|
575 ) |
564 else: |
576 else: |
565 info = self.trUtf8("{0} of {1} - Stopped")\ |
577 info = self.trUtf8("{0} of {1} - Stopped")\ |
566 .format(dataString(self.__bytesReceived), |
578 .format(dataString(self.__bytesReceived), |
567 dataString(bytesTotal)) |
579 dataString(bytesTotal)) |
568 self.infoLabel.setText(info) |
580 self.infoLabel.setText(info) |