7 Module implementing a widget controlling a download. |
7 Module implementing a widget controlling a download. |
8 """ |
8 """ |
9 |
9 |
10 from __future__ import unicode_literals |
10 from __future__ import unicode_literals |
11 try: |
11 try: |
12 str = unicode # __IGNORE_WARNING__ |
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, \ |
16 from PyQt4.QtCore import pyqtSlot, pyqtSignal, Qt, QTime, QFile, QFileInfo, \ |
17 QUrl, 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 |
138 |
138 |
139 # attach to the reply object |
139 # attach to the reply object |
140 self.__url = self.__reply.url() |
140 self.__url = self.__reply.url() |
141 self.__reply.setParent(self) |
141 self.__reply.setParent(self) |
142 self.__reply.setReadBufferSize(16 * 1024 * 1024) |
142 self.__reply.setReadBufferSize(16 * 1024 * 1024) |
143 self.__reply.readyRead[()].connect(self.__readyRead) |
143 self.__reply.readyRead.connect(self.__readyRead) |
144 self.__reply.error.connect(self.__networkError) |
144 self.__reply.error.connect(self.__networkError) |
145 self.__reply.downloadProgress.connect(self.__downloadProgress) |
145 self.__reply.downloadProgress.connect(self.__downloadProgress) |
146 self.__reply.metaDataChanged.connect(self.__metaDataChanged) |
146 self.__reply.metaDataChanged.connect(self.__metaDataChanged) |
147 self.__reply.finished[()].connect(self.__finished) |
147 self.__reply.finished.connect(self.__finished) |
148 |
148 |
149 # reset info |
149 # reset info |
150 self.infoLabel.clear() |
150 self.infoLabel.clear() |
151 self.progressBar.setValue(0) |
151 self.progressBar.setValue(0) |
152 self.__getFileName() |
152 self.__getFileName() |
189 if dlg.exec_() == QDialog.Rejected or dlg.getAction() == "cancel": |
189 if dlg.exec_() == QDialog.Rejected or dlg.getAction() == "cancel": |
190 self.progressBar.setVisible(False) |
190 self.progressBar.setVisible(False) |
191 self.__reply.close() |
191 self.__reply.close() |
192 self.on_stopButton_clicked() |
192 self.on_stopButton_clicked() |
193 self.filenameLabel.setText( |
193 self.filenameLabel.setText( |
194 self.trUtf8("Download canceled: {0}").format( |
194 self.tr("Download canceled: {0}").format( |
195 QFileInfo(defaultFileName).fileName())) |
195 QFileInfo(defaultFileName).fileName())) |
196 self.__canceledFileSelect = True |
196 self.__canceledFileSelect = True |
197 return |
197 return |
198 |
198 |
199 if dlg.getAction() == "scan": |
199 if dlg.getAction() == "scan": |
201 |
201 |
202 self.progressBar.setVisible(False) |
202 self.progressBar.setVisible(False) |
203 self.__reply.close() |
203 self.__reply.close() |
204 self.on_stopButton_clicked() |
204 self.on_stopButton_clicked() |
205 self.filenameLabel.setText( |
205 self.filenameLabel.setText( |
206 self.trUtf8("VirusTotal scan scheduled: {0}").format( |
206 self.tr("VirusTotal scan scheduled: {0}").format( |
207 QFileInfo(defaultFileName).fileName())) |
207 QFileInfo(defaultFileName).fileName())) |
208 self.__canceledFileSelect = True |
208 self.__canceledFileSelect = True |
209 return |
209 return |
210 |
210 |
211 self.__autoOpen = dlg.getAction() == "open" |
211 self.__autoOpen = dlg.getAction() == "open" |
215 |
215 |
216 if ask and not self.__autoOpen and self.__requestFilename: |
216 if ask and not self.__autoOpen and self.__requestFilename: |
217 self.__gettingFileName = True |
217 self.__gettingFileName = True |
218 fileName = E5FileDialog.getSaveFileName( |
218 fileName = E5FileDialog.getSaveFileName( |
219 None, |
219 None, |
220 self.trUtf8("Save File"), |
220 self.tr("Save File"), |
221 defaultFileName, |
221 defaultFileName, |
222 "") |
222 "") |
223 self.__gettingFileName = False |
223 self.__gettingFileName = False |
224 if not fileName: |
224 if not fileName: |
225 self.progressBar.setVisible(False) |
225 self.progressBar.setVisible(False) |
226 self.__reply.close() |
226 self.__reply.close() |
227 self.on_stopButton_clicked() |
227 self.on_stopButton_clicked() |
228 self.filenameLabel.setText( |
228 self.filenameLabel.setText( |
229 self.trUtf8("Download canceled: {0}") |
229 self.tr("Download canceled: {0}") |
230 .format(QFileInfo(defaultFileName).fileName())) |
230 .format(QFileInfo(defaultFileName).fileName())) |
231 self.__canceledFileSelect = True |
231 self.__canceledFileSelect = True |
232 return |
232 return |
233 |
233 |
234 fileInfo = QFileInfo(fileName) |
234 fileInfo = QFileInfo(fileName) |
243 saveDirPath = QFileInfo(self.__fileName).dir() |
243 saveDirPath = QFileInfo(self.__fileName).dir() |
244 if not saveDirPath.exists(): |
244 if not saveDirPath.exists(): |
245 if not saveDirPath.mkpath(saveDirPath.absolutePath()): |
245 if not saveDirPath.mkpath(saveDirPath.absolutePath()): |
246 self.progressBar.setVisible(False) |
246 self.progressBar.setVisible(False) |
247 self.on_stopButton_clicked() |
247 self.on_stopButton_clicked() |
248 self.infoLabel.setText(self.trUtf8( |
248 self.infoLabel.setText(self.tr( |
249 "Download directory ({0}) couldn't be created.") |
249 "Download directory ({0}) couldn't be created.") |
250 .format(saveDirPath.absolutePath())) |
250 .format(saveDirPath.absolutePath())) |
251 return |
251 return |
252 |
252 |
253 self.filenameLabel.setText(QFileInfo(self.__fileName).fileName()) |
253 self.filenameLabel.setText(QFileInfo(self.__fileName).fileName()) |
352 Private slot to pause the download. |
352 Private slot to pause the download. |
353 |
353 |
354 @param checked flag indicating the state of the button (boolean) |
354 @param checked flag indicating the state of the button (boolean) |
355 """ |
355 """ |
356 if checked: |
356 if checked: |
357 self.__reply.readyRead[()].disconnect(self.__readyRead) |
357 self.__reply.readyRead.disconnect(self.__readyRead) |
358 self.__reply.setReadBufferSize(16 * 1024) |
358 self.__reply.setReadBufferSize(16 * 1024) |
359 else: |
359 else: |
360 self.__reply.readyRead[()].connect(self.__readyRead) |
360 self.__reply.readyRead.connect(self.__readyRead) |
361 self.__reply.setReadBufferSize(16 * 1024 * 1024) |
361 self.__reply.setReadBufferSize(16 * 1024 * 1024) |
362 self.__readyRead() |
362 self.__readyRead() |
363 |
363 |
364 @pyqtSlot() |
364 @pyqtSlot() |
365 def on_stopButton_clicked(self): |
365 def on_stopButton_clicked(self): |
421 # in case someone else has already put a file there |
421 # in case someone else has already put a file there |
422 if not self.__requestFilename: |
422 if not self.__requestFilename: |
423 self.__getFileName() |
423 self.__getFileName() |
424 if not self.__output.open(QIODevice.WriteOnly): |
424 if not self.__output.open(QIODevice.WriteOnly): |
425 self.infoLabel.setText( |
425 self.infoLabel.setText( |
426 self.trUtf8("Error opening save file: {0}") |
426 self.tr("Error opening save file: {0}") |
427 .format(self.__output.errorString())) |
427 .format(self.__output.errorString())) |
428 self.on_stopButton_clicked() |
428 self.on_stopButton_clicked() |
429 self.statusChanged.emit() |
429 self.statusChanged.emit() |
430 return |
430 return |
431 self.statusChanged.emit() |
431 self.statusChanged.emit() |
433 buffer = self.__reply.readAll() |
433 buffer = self.__reply.readAll() |
434 self.__sha1Hash.addData(buffer) |
434 self.__sha1Hash.addData(buffer) |
435 self.__md5Hash.addData(buffer) |
435 self.__md5Hash.addData(buffer) |
436 bytesWritten = self.__output.write(buffer) |
436 bytesWritten = self.__output.write(buffer) |
437 if bytesWritten == -1: |
437 if bytesWritten == -1: |
438 self.infoLabel.setText(self.trUtf8("Error saving: {0}") |
438 self.infoLabel.setText(self.tr("Error saving: {0}") |
439 .format(self.__output.errorString())) |
439 .format(self.__output.errorString())) |
440 self.on_stopButton_clicked() |
440 self.on_stopButton_clicked() |
441 else: |
441 else: |
442 self.__startedSaving = True |
442 self.__startedSaving = True |
443 if self.__finishedDownloading: |
443 if self.__finishedDownloading: |
445 |
445 |
446 def __networkError(self): |
446 def __networkError(self): |
447 """ |
447 """ |
448 Private slot to handle a network error. |
448 Private slot to handle a network error. |
449 """ |
449 """ |
450 self.infoLabel.setText(self.trUtf8("Network Error: {0}") |
450 self.infoLabel.setText(self.tr("Network Error: {0}") |
451 .format(self.__reply.errorString())) |
451 .format(self.__reply.errorString())) |
452 self.tryAgainButton.setEnabled(True) |
452 self.tryAgainButton.setEnabled(True) |
453 self.tryAgainButton.setVisible(True) |
453 self.tryAgainButton.setVisible(True) |
454 self.downloadFinished.emit() |
454 self.downloadFinished.emit() |
455 |
455 |
556 remaining = "" |
556 remaining = "" |
557 |
557 |
558 if bytesTotal > 0: |
558 if bytesTotal > 0: |
559 remaining = timeString(timeRemaining) |
559 remaining = timeString(timeRemaining) |
560 |
560 |
561 info = self.trUtf8("{0} of {1} ({2}/sec)\n{3}")\ |
561 info = self.tr("{0} of {1} ({2}/sec)\n{3}")\ |
562 .format( |
562 .format( |
563 dataString(self.__bytesReceived), |
563 dataString(self.__bytesReceived), |
564 bytesTotal == -1 and self.trUtf8("?") |
564 bytesTotal == -1 and self.tr("?") |
565 or dataString(bytesTotal), |
565 or dataString(bytesTotal), |
566 dataString(int(speed)), |
566 dataString(int(speed)), |
567 remaining) |
567 remaining) |
568 else: |
568 else: |
569 if self.__bytesReceived == bytesTotal or bytesTotal == -1: |
569 if self.__bytesReceived == bytesTotal or bytesTotal == -1: |
570 info = self.trUtf8("{0} downloaded\nSHA1: {1}\nMD5: {2}")\ |
570 info = self.tr("{0} downloaded\nSHA1: {1}\nMD5: {2}")\ |
571 .format(dataString(self.__output.size()), |
571 .format(dataString(self.__output.size()), |
572 str(self.__sha1Hash.result().toHex(), |
572 str(self.__sha1Hash.result().toHex(), |
573 encoding="ascii"), |
573 encoding="ascii"), |
574 str(self.__md5Hash.result().toHex(), |
574 str(self.__md5Hash.result().toHex(), |
575 encoding="ascii") |
575 encoding="ascii") |
576 ) |
576 ) |
577 else: |
577 else: |
578 info = self.trUtf8("{0} of {1} - Stopped")\ |
578 info = self.tr("{0} of {1} - Stopped")\ |
579 .format(dataString(self.__bytesReceived), |
579 .format(dataString(self.__bytesReceived), |
580 dataString(bytesTotal)) |
580 dataString(bytesTotal)) |
581 self.infoLabel.setText(info) |
581 self.infoLabel.setText(info) |
582 |
582 |
583 def downloading(self): |
583 def downloading(self): |