Helpviewer/Download/DownloadItem.py

changeset 3002
6ffc581f00f1
parent 2954
bf0215fe12d1
child 3034
7ce719013078
child 3057
10516539f238
equal deleted inserted replaced
3001:3674ff5fa8f8 3002:6ffc581f00f1
5 5
6 """ 6 """
7 Module implementing a widget controlling a download. 7 Module implementing a widget controlling a download.
8 """ 8 """
9 9
10 from PyQt4.QtCore import pyqtSlot, pyqtSignal, Qt, QTime, QFile, QFileInfo, QUrl, \ 10 from PyQt4.QtCore import pyqtSlot, pyqtSignal, Qt, QTime, QFile, QFileInfo, \
11 QIODevice, QCryptographicHash 11 QUrl, QIODevice, QCryptographicHash
12 from PyQt4.QtGui import QWidget, QPalette, QStyle, QDesktopServices, QDialog 12 from PyQt4.QtGui import QWidget, QPalette, QStyle, QDesktopServices, QDialog
13 from PyQt4.QtNetwork import QNetworkRequest, QNetworkReply 13 from PyQt4.QtNetwork import QNetworkRequest, QNetworkReply
14 14
15 from E5Gui import E5FileDialog 15 from E5Gui import E5FileDialog
16 16
42 download=False, parent=None, mainWindow=None): 42 download=False, parent=None, mainWindow=None):
43 """ 43 """
44 Constructor 44 Constructor
45 45
46 @keyparam reply reference to the network reply object (QNetworkReply) 46 @keyparam reply reference to the network reply object (QNetworkReply)
47 @keyparam requestFilename flag indicating to ask the user for a filename (boolean) 47 @keyparam requestFilename flag indicating to ask the user for a
48 @keyparam webPage reference to the web page object the download originated 48 filename (boolean)
49 from (QWebPage) 49 @keyparam webPage reference to the web page object the download
50 originated from (QWebPage)
50 @keyparam download flag indicating a download operation (boolean) 51 @keyparam download flag indicating a download operation (boolean)
51 @keyparam parent reference to the parent widget (QWidget) 52 @keyparam parent reference to the parent widget (QWidget)
52 @keyparam mainWindow reference to the main window (HelpWindow) 53 @keyparam mainWindow reference to the main window (HelpWindow)
53 """ 54 """
54 super().__init__(parent) 55 super().__init__(parent)
58 p.setColor(QPalette.Text, Qt.darkGray) 59 p.setColor(QPalette.Text, Qt.darkGray)
59 self.infoLabel.setPalette(p) 60 self.infoLabel.setPalette(p)
60 61
61 self.progressBar.setMaximum(0) 62 self.progressBar.setMaximum(0)
62 63
63 self.__isFtpDownload = reply is not None and reply.url().scheme() == "ftp" 64 self.__isFtpDownload = reply is not None and \
65 reply.url().scheme() == "ftp"
64 66
65 self.tryAgainButton.setIcon(UI.PixmapCache.getIcon("restart.png")) 67 self.tryAgainButton.setIcon(UI.PixmapCache.getIcon("restart.png"))
66 self.tryAgainButton.setEnabled(False) 68 self.tryAgainButton.setEnabled(False)
67 self.tryAgainButton.setVisible(False) 69 self.tryAgainButton.setVisible(False)
68 self.stopButton.setIcon(UI.PixmapCache.getIcon("stopLoading.png")) 70 self.stopButton.setIcon(UI.PixmapCache.getIcon("stopLoading.png"))
101 103
102 self.__sha1Hash = QCryptographicHash(QCryptographicHash.Sha1) 104 self.__sha1Hash = QCryptographicHash(QCryptographicHash.Sha1)
103 self.__md5Hash = QCryptographicHash(QCryptographicHash.Md5) 105 self.__md5Hash = QCryptographicHash(QCryptographicHash.Md5)
104 106
105 if not requestFilename: 107 if not requestFilename:
106 self.__requestFilename = Preferences.getUI("RequestDownloadFilename") 108 self.__requestFilename = \
109 Preferences.getUI("RequestDownloadFilename")
107 110
108 self.__initialize() 111 self.__initialize()
109 112
110 def __initialize(self, tryAgain=False): 113 def __initialize(self, tryAgain=False):
111 """ 114 """
161 fileName = self.__fileName 164 fileName = self.__fileName
162 originalFileName = self.__originalFileName 165 originalFileName = self.__originalFileName
163 self.__toDownload = True 166 self.__toDownload = True
164 ask = False 167 ask = False
165 else: 168 else:
166 defaultFileName, originalFileName = self.__saveFileName(downloadDirectory) 169 defaultFileName, originalFileName = \
170 self.__saveFileName(downloadDirectory)
167 fileName = defaultFileName 171 fileName = defaultFileName
168 self.__originalFileName = originalFileName 172 self.__originalFileName = originalFileName
169 ask = True 173 ask = True
170 self.__autoOpen = False 174 self.__autoOpen = False
171 if not self.__toDownload: 175 if not self.__toDownload:
178 self) 182 self)
179 if dlg.exec_() == QDialog.Rejected or dlg.getAction() == "cancel": 183 if dlg.exec_() == QDialog.Rejected or dlg.getAction() == "cancel":
180 self.progressBar.setVisible(False) 184 self.progressBar.setVisible(False)
181 self.__reply.close() 185 self.__reply.close()
182 self.on_stopButton_clicked() 186 self.on_stopButton_clicked()
183 self.filenameLabel.setText(self.trUtf8("Download canceled: {0}").format( 187 self.filenameLabel.setText(
184 QFileInfo(defaultFileName).fileName())) 188 self.trUtf8("Download canceled: {0}").format(
189 QFileInfo(defaultFileName).fileName()))
185 self.__canceledFileSelect = True 190 self.__canceledFileSelect = True
186 return 191 return
187 192
188 if dlg.getAction() == "scan": 193 if dlg.getAction() == "scan":
189 self.__mainWindow.requestVirusTotalScan(url) 194 self.__mainWindow.requestVirusTotalScan(url)
196 QFileInfo(defaultFileName).fileName())) 201 QFileInfo(defaultFileName).fileName()))
197 self.__canceledFileSelect = True 202 self.__canceledFileSelect = True
198 return 203 return
199 204
200 self.__autoOpen = dlg.getAction() == "open" 205 self.__autoOpen = dlg.getAction() == "open"
201 fileName = QDesktopServices.storageLocation(QDesktopServices.TempLocation) + \ 206 fileName = QDesktopServices.storageLocation(
202 '/' + QFileInfo(fileName).completeBaseName() 207 QDesktopServices.TempLocation) + \
208 '/' + QFileInfo(fileName).completeBaseName()
203 209
204 if ask and not self.__autoOpen and self.__requestFilename: 210 if ask and not self.__autoOpen and self.__requestFilename:
205 self.__gettingFileName = True 211 self.__gettingFileName = True
206 fileName = E5FileDialog.getSaveFileName( 212 fileName = E5FileDialog.getSaveFileName(
207 None, 213 None,
211 self.__gettingFileName = False 217 self.__gettingFileName = False
212 if not fileName: 218 if not fileName:
213 self.progressBar.setVisible(False) 219 self.progressBar.setVisible(False)
214 self.__reply.close() 220 self.__reply.close()
215 self.on_stopButton_clicked() 221 self.on_stopButton_clicked()
216 self.filenameLabel.setText(self.trUtf8("Download canceled: {0}")\ 222 self.filenameLabel.setText(
217 .format(QFileInfo(defaultFileName).fileName())) 223 self.trUtf8("Download canceled: {0}")\
224 .format(QFileInfo(defaultFileName).fileName()))
218 self.__canceledFileSelect = True 225 self.__canceledFileSelect = True
219 return 226 return
220 227
221 fileInfo = QFileInfo(fileName) 228 fileInfo = QFileInfo(fileName)
222 Helpviewer.HelpWindow.HelpWindow.downloadManager().setDownloadDirectory( 229 Helpviewer.HelpWindow.HelpWindow.downloadManager()\
223 fileInfo.absoluteDir().absolutePath()) 230 .setDownloadDirectory(fileInfo.absoluteDir().absolutePath())
224 self.filenameLabel.setText(fileInfo.fileName()) 231 self.filenameLabel.setText(fileInfo.fileName())
225 232
226 self.__output.setFileName(fileName + ".part") 233 self.__output.setFileName(fileName + ".part")
227 self.__fileName = fileName 234 self.__fileName = fileName
228 235
230 saveDirPath = QFileInfo(self.__fileName).dir() 237 saveDirPath = QFileInfo(self.__fileName).dir()
231 if not saveDirPath.exists(): 238 if not saveDirPath.exists():
232 if not saveDirPath.mkpath(saveDirPath.absolutePath()): 239 if not saveDirPath.mkpath(saveDirPath.absolutePath()):
233 self.progressBar.setVisible(False) 240 self.progressBar.setVisible(False)
234 self.on_stopButton_clicked() 241 self.on_stopButton_clicked()
235 self.infoLabel.setText( 242 self.infoLabel.setText(self.trUtf8(
236 self.trUtf8("Download directory ({0}) couldn't be created.")\ 243 "Download directory ({0}) couldn't be created.")\
237 .format(saveDirPath.absolutePath())) 244 .format(saveDirPath.absolutePath()))
238 return 245 return
239 246
240 self.filenameLabel.setText(QFileInfo(self.__fileName).fileName()) 247 self.filenameLabel.setText(QFileInfo(self.__fileName).fileName())
241 if self.__requestFilename: 248 if self.__requestFilename:
248 @param directory name of the directory to store the file into (string) 255 @param directory name of the directory to store the file into (string)
249 @return proposed filename and original filename (string, string) 256 @return proposed filename and original filename (string, string)
250 """ 257 """
251 path = "" 258 path = ""
252 if self.__reply.hasRawHeader("Content-Disposition"): 259 if self.__reply.hasRawHeader("Content-Disposition"):
253 header = bytes(self.__reply.rawHeader("Content-Disposition")).decode() 260 header = bytes(self.__reply.rawHeader("Content-Disposition"))\
261 .decode()
254 if header: 262 if header:
255 pos = header.find("filename=") 263 pos = header.find("filename=")
256 if pos != -1: 264 if pos != -1:
257 path = header[pos + 9:] 265 path = header[pos + 9:]
258 if path.startswith('"') and path.endswith('"'): 266 if path.startswith('"') and path.endswith('"'):
405 if not self.__output.isOpen(): 413 if not self.__output.isOpen():
406 # in case someone else has already put a file there 414 # in case someone else has already put a file there
407 if not self.__requestFilename: 415 if not self.__requestFilename:
408 self.__getFileName() 416 self.__getFileName()
409 if not self.__output.open(QIODevice.WriteOnly): 417 if not self.__output.open(QIODevice.WriteOnly):
410 self.infoLabel.setText(self.trUtf8("Error opening save file: {0}")\ 418 self.infoLabel.setText(
419 self.trUtf8("Error opening save file: {0}")\
411 .format(self.__output.errorString())) 420 .format(self.__output.errorString()))
412 self.on_stopButton_clicked() 421 self.on_stopButton_clicked()
413 self.statusChanged.emit() 422 self.statusChanged.emit()
414 return 423 return
415 self.statusChanged.emit() 424 self.statusChanged.emit()
443 """ 452 """
444 locationHeader = self.__reply.header(QNetworkRequest.LocationHeader) 453 locationHeader = self.__reply.header(QNetworkRequest.LocationHeader)
445 if locationHeader and locationHeader.isValid(): 454 if locationHeader and locationHeader.isValid():
446 self.__url = QUrl(locationHeader) 455 self.__url = QUrl(locationHeader)
447 import Helpviewer.HelpWindow 456 import Helpviewer.HelpWindow
448 self.__reply = Helpviewer.HelpWindow.HelpWindow.networkAccessManager().get( 457 self.__reply = Helpviewer.HelpWindow.HelpWindow\
449 QNetworkRequest(self.__url)) 458 .networkAccessManager().get(QNetworkRequest(self.__url))
450 self.__initialize() 459 self.__initialize()
451 460
452 def __downloadProgress(self, bytesReceived, bytesTotal): 461 def __downloadProgress(self, bytesReceived, bytesTotal):
453 """ 462 """
454 Private method to show the download progress. 463 Private method to show the download progress.
474 Public method to get the total number of bytes of the download. 483 Public method to get the total number of bytes of the download.
475 484
476 @return total number of bytes (integer) 485 @return total number of bytes (integer)
477 """ 486 """
478 if self.__bytesTotal == -1: 487 if self.__bytesTotal == -1:
479 self.__bytesTotal = self.__reply.header(QNetworkRequest.ContentLengthHeader) 488 self.__bytesTotal = self.__reply.header(
489 QNetworkRequest.ContentLengthHeader)
480 if self.__bytesTotal is None: 490 if self.__bytesTotal is None:
481 self.__bytesTotal = -1 491 self.__bytesTotal = -1
482 return self.__bytesTotal 492 return self.__bytesTotal
483 493
484 def bytesReceived(self): 494 def bytesReceived(self):
499 return -1.0 509 return -1.0
500 510
501 if self.bytesTotal() == -1: 511 if self.bytesTotal() == -1:
502 return -1.0 512 return -1.0
503 513
504 timeRemaining = (self.bytesTotal() - self.bytesReceived()) / self.currentSpeed() 514 timeRemaining = (self.bytesTotal() -
515 self.bytesReceived()) / self.currentSpeed()
505 516
506 # ETA should never be 0 517 # ETA should never be 0
507 if timeRemaining == 0: 518 if timeRemaining == 0:
508 timeRemaining = 1 519 timeRemaining = 1
509 520
549 remaining) 560 remaining)
550 else: 561 else:
551 if self.__bytesReceived == bytesTotal or bytesTotal == -1: 562 if self.__bytesReceived == bytesTotal or bytesTotal == -1:
552 info = self.trUtf8("{0} downloaded\nSHA1: {1}\nMD5: {2}")\ 563 info = self.trUtf8("{0} downloaded\nSHA1: {1}\nMD5: {2}")\
553 .format(dataString(self.__output.size()), 564 .format(dataString(self.__output.size()),
554 str(self.__sha1Hash.result().toHex(), encoding="ascii"), 565 str(self.__sha1Hash.result().toHex(),
555 str(self.__md5Hash.result().toHex(), encoding="ascii")) 566 encoding="ascii"),
567 str(self.__md5Hash.result().toHex(),
568 encoding="ascii")
569 )
556 else: 570 else:
557 info = self.trUtf8("{0} of {1} - Stopped")\ 571 info = self.trUtf8("{0} of {1} - Stopped")\
558 .format(dataString(self.__bytesReceived), 572 .format(dataString(self.__bytesReceived),
559 dataString(bytesTotal)) 573 dataString(bytesTotal))
560 self.infoLabel.setText(info) 574 self.infoLabel.setText(info)

eric ide

mercurial