[Pkg-privacy-commits] [tails-installer] 28/210: Reorganized the structure, every release has its own downloader
Intrigeri
intrigeri at moszumanska.debian.org
Wed May 24 15:26:25 UTC 2017
This is an automated email from the git hooks/post-receive script.
intrigeri pushed a commit to tag 3.90.0
in repository tails-installer.
commit 0147f066fee75b9860fbe99239520d4f92c7a763
Author: Martin Briza <mbriza at redhat.com>
Date: Thu Feb 26 14:15:57 2015 +0100
Reorganized the structure, every release has its own downloader
---
liveusb/components/DownloadDialog.qml | 10 +-
liveusb/components/ImageDetails.qml | 4 +-
liveusb/components/ImageList.qml | 2 +-
liveusb/gui.py | 385 +++++++++++++++++++++-------------
4 files changed, 252 insertions(+), 149 deletions(-)
diff --git a/liveusb/components/DownloadDialog.qml b/liveusb/components/DownloadDialog.qml
index 77e919a..b01bfb6 100644
--- a/liveusb/components/DownloadDialog.qml
+++ b/liveusb/components/DownloadDialog.qml
@@ -34,17 +34,17 @@ Dialog {
Text {
Layout.fillWidth: true
horizontalAlignment: Text.AlignHCenter
- property double leftSize: liveUSBData.downloader.maxProgress - liveUSBData.downloader.progress
+ property double leftSize: liveUSBData.currentImage.download.maxProgress - liveUSBData.currentImage.download.progress
property string leftStr: leftSize <= 0 ? "" :
(leftSize < 1024) ? (leftSize + " B") :
(leftSize < (1024 * 1024)) ? ((leftSize / 1024).toFixed(1) + " KB") :
(leftSize < (1024 * 1024 * 1024)) ? ((leftSize / 1024 / 1024).toFixed(1) + " MB") :
((leftSize / 1024 / 1024 / 1024).toFixed(1) + " GB")
- text: liveUSBData.downloader.status + (liveUSBData.downloader.maxProgress > 0 ? " (" + leftStr + " left)" : "")
+ text: liveUSBData.currentImage.status + (liveUSBData.currentImage.download.maxProgress > 0 ? " (" + leftStr + " left)" : "")
}
AdwaitaProgressBar {
Layout.fillWidth: true
- value: liveUSBData.downloader.progress / liveUSBData.downloader.maxProgress
+ value: liveUSBData.currentImage.download.progress / liveUSBData.currentImage.download.maxProgress
}
}
@@ -92,7 +92,7 @@ Dialog {
width: implicitWidth * 1.2
text: "Cancel"
onClicked: {
- liveUSBData.downloader.cancel()
+ liveUSBData.currentImage.download.cancel()
root.close()
}
}
@@ -106,7 +106,7 @@ Dialog {
color: "red"
textColor: enabled ? "white" : palette.text
width: implicitWidth * 1.2
- enabled: liveUSBData.downloader.readyToWrite
+ enabled: liveUSBData.currentImage.readyToWrite
text: "Write to disk"
}
}
diff --git a/liveusb/components/ImageDetails.qml b/liveusb/components/ImageDetails.qml
index 0eabea3..a0d9172 100644
--- a/liveusb/components/ImageDetails.qml
+++ b/liveusb/components/ImageDetails.qml
@@ -47,7 +47,7 @@ Item {
width: implicitWidth + 16
onClicked: {
dlDialog.visible = true
- liveUSBData.downloader.run(liveUSBData.currentImage.url)
+ liveUSBData.currentImage.get()
}
enabled: mainWindow.currentImageIndex != 0 || fileDialog.fileUrl.length > 0
anchors {
@@ -148,7 +148,7 @@ Item {
AdwaitaButton {
text: "Find the image"
Layout.alignment: Qt.AlignHCenter
- visible: mainWindow.currentImageIndex == 0
+ visible: liveUSBData.currentImage.isLocal
onClicked: fileDialog.visible = true
}
}
diff --git a/liveusb/components/ImageList.qml b/liveusb/components/ImageList.qml
index e3a43f8..7628da5 100644
--- a/liveusb/components/ImageList.qml
+++ b/liveusb/components/ImageList.qml
@@ -308,7 +308,7 @@ Item {
}
}
Arrow {
- visible: hasDetails
+ visible: !isLocal
anchors {
verticalCenter: parent.verticalCenter
right: parent.right
diff --git a/liveusb/gui.py b/liveusb/gui.py
index 6db81e8..763b21e 100755
--- a/liveusb/gui.py
+++ b/liveusb/gui.py
@@ -57,12 +57,126 @@ MAX_FAT16 = 2047
MAX_FAT32 = 3999
MAX_EXT = 2097152
+class ReleaseDownloadThread(QThread):
+ downloadFinished = pyqtSignal(str)
+ downloadError = pyqtSignal(str)
+
+ def __init__(self, url, progress, proxies):
+ QThread.__init__(self)
+ self.url = url
+ self.progress = progress
+ self.proxies = proxies
+
+ def run(self):
+ self.grabber = URLGrabber(progress_obj=self.progress, proxies=self.proxies)
+ home = os.getenv('HOME', 'USERPROFILE')
+ filename = os.path.basename(urlparse.urlparse(self.url).path)
+ for folder in ('Downloads', 'My Documents'):
+ if os.path.isdir(os.path.join(home, folder)):
+ filename = os.path.join(home, folder, filename)
+ break
+ try:
+ iso = self.grabber.urlgrab(self.url, reget='simple')
+ except URLGrabError, e:
+ # TODO find out if this errno is _really_ benign
+ if e.errno == 9: # Requested byte range not satisfiable.
+ self.downloadFinished.emit(filename)
+ else:
+ self.downloadError.emit(e.strerror)
+ else:
+ self.downloadFinished.emit(iso)
+
+class ReleaseDownload(QObject, BaseMeter):
+ runningChanged = pyqtSignal()
+ currentChanged = pyqtSignal()
+ maximumChanged = pyqtSignal()
+ pathChanged = pyqtSignal()
+
+ _running = False
+ _current = -1.0
+ _maximum = -1.0
+ _path = ''
+
+ def __init__(self, parent):
+ QObject.__init__(self, parent)
+ self._grabber = ReleaseDownloadThread(parent.url, self, parent.live.get_proxies())
+
+ def reset(self):
+ self._running = False
+ self._current = -1.0
+ self._maximum = -1.0
+ self._path = ''
+ self.runningChanged.emit()
+ self.currentChanged.emit()
+ self.maximumChanged.emit()
+ self.pathChanged.emit()
+
+ def start(self, filename=None, url=None, basename=None, size=None, now=None, text=None):
+ self._maximum = size
+ self._running = True
+ self.maximumChanged.emit()
+ self.runningChanged.emit()
+
+ def update(self, amount_read, now=None):
+ """ Update our download progressbar.
+
+ :read: the number of bytes read so far
+ """
+ if self._current < amount_read:
+ self._current = amount_read
+ self.currentChanged.emit()
+
+ def end(self, amount_read):
+ self._current = amount_read
+ self.currentChanged.emit()
+
+ @pyqtSlot(str)
+ def childFinished(self, iso):
+ self._path = iso
+ self._running = False
+ self.pathChanged.emit()
+ self.runningChanged.emit()
+
+ @pyqtSlot(str)
+ def childError(self, err):
+ self.reset()
+
+ @pyqtSlot(str)
+ def run(self):
+ self._grabber.start()
+ self._grabber.downloadFinished.connect(self.childFinished)
+ self._grabber.downloadError.connect(self.childError)
+
+ @pyqtSlot()
+ def cancel(self):
+ self._grabber.terminate()
+ self.reset()
+
+ @pyqtProperty(float, notify=maximumChanged)
+ def maxProgress(self):
+ return self._maximum
+
+ @pyqtProperty(float, notify=currentChanged)
+ def progress(self):
+ return self._current
+
+ @pyqtProperty(bool, notify=runningChanged)
+ def running(self):
+ return self._running
+
+ @pyqtProperty(str, notify=pathChanged)
+ def path(self):
+ return self._path
+
class Release(QObject):
screenshotsChanged = pyqtSignal()
+ pathChanged = pyqtSignal()
+ statusChanged = pyqtSignal()
- def __init__(self, parent=None, name = '', logo = '', size = 0, arch = '', fullName = '', releaseDate = QDateTime(), shortDescription = '', fullDescription = '', hasDetails = True, screenshots = [], url=''):
+ def __init__(self, parent=None, live=None, name = '', logo = '', size = 0, arch = '', fullName = '', releaseDate = QDateTime(), shortDescription = '', fullDescription = '', isLocal = False, screenshots = [], url=''):
QObject.__init__(self, parent)
+ self.live = live
self._name = name.replace('_', ' ')
self._logo = logo
self._size = size
@@ -71,9 +185,10 @@ class Release(QObject):
self._releaseDate = releaseDate
self._shortDescription = shortDescription
self._fullDescription = fullDescription
- self._hasDetails = hasDetails
+ self._isLocal = isLocal
self._screenshots = screenshots
self._url = url
+ self._path = ''
if self._logo == '':
if self._name == 'Fedora Workstation':
@@ -91,6 +206,20 @@ class Release(QObject):
else:
self._logo = '../../data/logo-fedora.svg'
+ self._download = ReleaseDownload(self)
+ self._download.pathChanged.connect(self.pathChanged)
+
+ self._download.runningChanged.connect(self.statusChanged)
+
+
+ @pyqtSlot()
+ def get(self):
+ self._download.run()
+
+ @pyqtSlot()
+ def write(self):
+ pass
+
@pyqtProperty(str, constant=True)
def name(self):
return self._name
@@ -111,7 +240,7 @@ class Release(QObject):
def fullName(self):
return self._fullName
- @pyqtProperty('QDateTime', constant=True)
+ @pyqtProperty(QDateTime, constant=True)
def releaseDate(self):
return self._releaseDate
@@ -124,8 +253,8 @@ class Release(QObject):
return self._fullDescription
@pyqtProperty(bool, constant=True)
- def hasDetails(self):
- return self._hasDetails
+ def isLocal(self):
+ return self._isLocal
@pyqtProperty(QQmlListProperty, notify=screenshotsChanged)
def screenshots(self):
@@ -135,145 +264,123 @@ class Release(QObject):
def url(self):
return self._url
-class IsoDownloaderThread(QThread):
- downloadFinished = pyqtSignal(str)
- downloadError = pyqtSignal(str)
-
- def __init__(self, url, progress, proxies):
- QThread.__init__(self)
- self.url = url
- self.progress = progress
- self.proxies = proxies
-
- def run(self):
- self.grabber = URLGrabber(progress_obj=self.progress, proxies=self.proxies)
- home = os.getenv('HOME', 'USERPROFILE')
- filename = os.path.basename(urlparse.urlparse(self.url).path)
- for folder in ('Downloads', 'My Documents'):
- if os.path.isdir(os.path.join(home, folder)):
- filename = os.path.join(home, folder, filename)
- break
- try:
- iso = self.grabber.urlgrab(self.url, reget='simple')
- except URLGrabError, e:
- # TODO find out if this errno is _really_ benign
- if e.errno == 9: # Requested byte range not satisfiable.
- self.downloadFinished.emit(filename)
- else:
- self.downloadError.emit(e.strerror)
- else:
- self.downloadFinished.emit(iso)
-
-class IsoDownloader(QObject, BaseMeter):
- maxProgressChanged = pyqtSignal()
- progressChanged = pyqtSignal()
- statusChanged = pyqtSignal()
- readyToWriteChanged = pyqtSignal()
- isoPathChanged = pyqtSignal()
-
- _status = 'Initializing'
- _maximum = -1.0
- _current = -1.0
- _readyToWrite = False
- _isoPath = ''
-
- """ A QObject urlgrabber BaseMeter class.
+ @pyqtProperty(str, notify=pathChanged)
+ def path(self):
+ return self._download.path
- This class is called automatically by urlgrabber with our download details.
- This class then sends signals to our main dialog window to update the
- progress bar.
- """
- def __init__(self, parent, live):
- QObject.__init__(self, parent)
-
- self._live = live
-
- def start(self, filename=None, url=None, basename=None, size=None, now=None, text=None):
- self._maximum = size
- self._status = 'Starting'
- self.statusChanged.emit()
-
- def update(self, amount_read, now=None):
- """ Update our download progressbar.
-
- :read: the number of bytes read so far
- """
- if self._current < amount_read:
- self._current = amount_read
- self.progressChanged.emit()
- self._status = 'Downloading'
- self.statusChanged.emit()
-
- def end(self, amount_read):
- self._current = amount_read
- self.progressChanged.emit()
-
- @pyqtSlot(str)
- def childFinished(self, iso):
- print(iso)
- self._status = 'Ready to write'
- self._maximum = -1.0
- self._current = -1.0
- self._readyToWrite = True
- self._isoPath = iso
- self.statusChanged.emit()
- self.progressChanged.emit()
- self.maxProgressChanged.emit()
- self.readyToWriteChanged.emit()
- self.isoPathChanged.emit()
-
- @pyqtSlot(str)
- def childError(self, err):
- self._status = 'Error: ' + err
- self._maximum = -1.0
- self._current = -1.0
- self.statusChanged.emit()
- self.progressChanged.emit()
- self.maxProgressChanged.emit()
-
- @pyqtSlot(str)
- def run(self, url):
- self._grabber = IsoDownloaderThread(url, self, self._live.get_proxies())
- self._grabber.start()
- self._grabber.downloadFinished.connect(self.childFinished)
- self._grabber.downloadError.connect(self.childError)
+ @pyqtProperty(bool, notify=pathChanged)
+ def readyToWrite(self):
+ return len(self.path) != 0
- @pyqtSlot()
- def cancel(self):
- self._grabber.terminate()
- self._status = 'Initializing...'
- self._maximum = -1.0
- self._current = -1.0
- self._readyToWrite = False
- self._isoPath = ''
- self.statusChanged.emit()
- self.progressChanged.emit()
- self.maxProgressChanged.emit()
+ @pyqtProperty(ReleaseDownload, constant=True)
+ def download(self):
+ return self._download
@pyqtProperty(str, notify=statusChanged)
def status(self):
- return self._status
+ if not self._download.running and not self.readyToWrite:
+ return 'Starting'
+ elif self._download.running:
+ return 'Downloading'
+ elif self.readyToWrite:
+ return 'Ready to write'
- @pyqtProperty(float, notify=maxProgressChanged)
- def maxProgress(self):
- return self._maximum
-
- @pyqtProperty(float, notify=progressChanged)
- def progress(self):
- return self._current
+class WriterThread(QThread):
+ status = pyqtSignal(str)
- @pyqtProperty(bool, notify=readyToWriteChanged)
- def readyToWrite(self):
- return self._readyToWrite
+ _useDD = False
- @pyqtProperty(str, notify=isoPathChanged)
- def isoPath(self):
- return self._isoPath
+ def __init__(self, live, parent, useDD = False):
+ QThread.__init__(self, parent)
-class WriterThread(QThread):
+ self.live = live
+ self.parent = parent
+ self._useDD = useDD
- def __init__(self, live, parent):
- QThread.__init__(self, parent)
+ def run(self):
+ handler = LiveUSBLogHandler(self.status)
+ self.live.log.addHandler(handler)
+ now = datetime.now()
+ try:
+ if self._useDD:
+ self.ddImage(handler, now)
+ else:
+ self.copyImage(handler, now)
+ except Exception, e:
+ self.status.emit(e.args[0])
+ self.status.emit(_("LiveUSB creation failed!"))
+ self.live.log.exception(e)
+
+ self.live.log.removeHandler(handler)
+ self.progressThread.terminate()
+
+ def ddImage(self, handler, now):
+ self.parent.progressBar.setRange(0, 0)
+ self.live.dd_image()
+ self.live.log.removeHandler(handler)
+ duration = str(datetime.now() - now).split('.')[0]
+ self.status.emit(_("Complete! (%s)") % duration)
+ self.parent.progressBar.setRange(0, 1)
+ return
+
+ def copyImage(self, handler, now):
+ self.live.verify_filesystem()
+ if not self.live.drive['uuid'] and not self.live.label:
+ self.status.emit(_("Error: Cannot set the label or obtain "
+ "the UUID of your device. Unable to continue."))
+ self.live.log.removeHandler(handler)
+ return
+
+ self.live.check_free_space()
+
+ if not self.parent.opts.noverify:
+ # Verify the MD5 checksum inside of the ISO image
+ if not self.live.verify_iso_md5():
+ self.live.log.removeHandler(handler)
+ return
+
+ # If we know about this ISO, and it's SHA1 -- verify it
+ release = self.live.get_release_from_iso()
+ if release and ('sha1' in release or 'sha256' in release):
+ if not self.live.verify_iso_sha1(progressThread=self):
+ self.live.log.removeHandler(handler)
+ return
+
+ # Setup the progress bar
+ self.progressThread.set_data(size=self.live.totalsize,
+ drive=self.live.drive['device'],
+ freebytes=self.live.get_free_bytes)
+ self.progressThread.start()
+
+ self.live.extract_iso()
+ self.live.create_persistent_overlay()
+ self.live.update_configs()
+ self.live.install_bootloader()
+ self.live.bootable_partition()
+
+ if self.parent.opts.device_checksum:
+ self.live.calculate_device_checksum(progressThread=self)
+ if self.parent.opts.liveos_checksum:
+ self.live.calculate_liveos_checksum()
+
+ self.progressThread.stop()
+
+ # Flush all filesystem buffers and unmount
+ self.live.flush_buffers()
+ self.live.unmount_device()
+
+ duration = str(datetime.now() - now).split('.')[0]
+ self.status.emit(_("Complete! (%s)" % duration))
+
+class LiveUSBLogHandler(logging.Handler):
+
+ def __init__(self, cb):
+ logging.Handler.__init__(self)
+ self.cb = cb
+
+ def emit(self, record):
+ if record.levelname in ('INFO', 'ERROR', 'WARN'):
+ self.cb(record.msg)
class LiveUSBData(QObject):
@@ -285,10 +392,10 @@ class LiveUSBData(QObject):
def __init__(self, opts):
QObject.__init__(self)
self.live = LiveUSBCreator(opts=opts)
- self._downloader = IsoDownloader(self, self.live)
- self.releaseData = [Release(self, name='Custom OS...', shortDescription='<pick from file chooser>', fullDescription='Here you can choose a OS image from your hard drive to be written to your flash disk', hasDetails=False, logo='../../data/icon-folder.svg')]
+ self.releaseData = [Release(self, self.live, name='Custom OS...', shortDescription='<pick from file chooser>', fullDescription='Here you can choose a OS image from your hard drive to be written to your flash disk', isLocal=True, logo='../../data/icon-folder.svg')]
for release in releases:
self.releaseData.append(Release(self,
+ self.live,
name='Fedora '+release['variant'],
shortDescription='Fedora '+release['variant']+' '+release['version']+(' 64bit' if release['arch']=='x86_64' else ' 32bit'),
arch=release['arch'],
@@ -304,10 +411,6 @@ class LiveUSBData(QObject):
def titleReleases(self):
return QQmlListProperty(Release, self, self.releaseData[0:4])
- @pyqtProperty(IsoDownloader, constant=True)
- def downloader(self):
- return self._downloader
-
@pyqtProperty(int, notify=currentImageChanged)
def currentIndex(self):
return self._currentIndex
@@ -327,7 +430,7 @@ class LiveUSBApp(QApplication):
""" Main application class """
def __init__(self, opts, args):
QApplication.__init__(self, args)
- qmlRegisterUncreatableType(IsoDownloader, "LiveUSB", 1, 0, "Downloader", "Not creatable directly, use the liveUSBData instance instead")
+ qmlRegisterUncreatableType(ReleaseDownload, "LiveUSB", 1, 0, "Download", "Not creatable directly, use the liveUSBData instance instead")
qmlRegisterUncreatableType(Release, "LiveUSB", 1, 0, "Release", "Not creatable directly, use the liveUSBData instance instead")
qmlRegisterUncreatableType(LiveUSBData, "LiveUSB", 1, 0, "Data", "Use the liveUSBData root instance")
view = QQmlApplicationEngine()
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-privacy/packages/tails-installer.git
More information about the Pkg-privacy-commits
mailing list