Get progress by Esky tasks

272 views Asked by At

I'm using Esky with my frozen app. It has the following properties and methods are available on the Esky class:

app.version:                the current best available version.

app.active_version:         the currently-executing version, or None
                            if the esky isn't for the current app.

app.find_update():          find the best available update, or None
                            if no updates are available.

app.fetch_version(v):       fetch the specified version into local storage.

app.install_version(v):     install and activate the specified version.

Now, that's nice and all, but I want to show the progress of the download task in my Gui.

How can I achieve that?

2

There are 2 answers

0
iTayb On BEST ANSWER

Not properly documenated, there is the fetch_version_iter generator function:

fetch_version_iter: like fetch_version but yielding progress updates during its execution

It yields the following values:

yield {"status": "downloading", "size": infile_size, "received": partfile.tell(), }

yield {"status":"retrying","size":None}

yield {"status":"ready","path":name}

Also, you can get the filename like that:

app.version_finder.version_graph.get_best_path(app.version,v)

0
flutefreak7 On

wxPython has wrapped Esky in their own SoftwareUpdate method:

https://github.com/wxWidgets/wxPython/blob/master/wx/lib/softwareupdate.py

In their implementation, the application checks for new versions, and asks the user if they'd like to update (using wx GUI for interaction). If the user chooses to update, the code simply calls esky's auto_update() method to handle the rest, but they provide it with an _updateProgress method which updates a progress bar and provides messages indicating Esky's progress:

self._esky.auto_update(self._updateProgress)

...

def _updateProgress(self, status):
    # Show progress of the download and install. This function is passed to Esky
    # functions to use as a callback.
    if self._pd is None and status.get('status') != 'done':
        self._pd = wx.ProgressDialog('Software Update', ' '*40, 
                                      style=wx.PD_CAN_ABORT|wx.PD_APP_MODAL,
                                      parent=self._parentWindow)
        self._pd.Update(0, '')

        if self._parentWindow:
            self._pd.CenterOnParent()

    simpleMsgMap = { 'searching'   : 'Searching...',
                     'retrying'    : 'Retrying...',
                     'ready'       : 'Download complete...',
                     'installing'  : 'Installing...',
                     'cleaning up' : 'Cleaning up...',}

    if status.get('status') in simpleMsgMap:
        self._doUpdateProgress(True, simpleMsgMap[status.get('status')])

    elif status.get('status') == 'found':
        self._doUpdateProgress(True, 'Found version %s...' % status.get('new_version'))

    elif status.get('status') == 'downloading':
        received = status.get('received')
        size = status.get('size')
        currentPercentage = 1.0 * received / size * 100
        if currentPercentage > 99.5:
            self._doUpdateProgress(False, "Unzipping...", int(currentPercentage))
        else:
            self._doUpdateProgress(False, "Downloading...", int(currentPercentage))

    elif status.get('status') == 'done': 
        if self._pd:
            self._pd.Destroy()
        self._pd = None

    wx.Yield()


def _doUpdateProgress(self, pulse, message, value=0):
    if pulse:
        keepGoing, skip = self._pd.Pulse(message)
    else:
        keepGoing, skip = self._pd.Update(value, message)
    if not keepGoing: # user pressed the cancel button
        self._pd.Destroy()
        self._pd = None
        raise UpdateAbortedError()

The code above was take directly from https://github.com/wxWidgets/wxPython/blob/master/wx/lib/softwareupdate.py.

This feature is documented in the Esky source, file: init.py, line: 689.

The code itself shows what your callback can expect to see throughout an update. Here are some excerpts where your callback would be called:

callback({"status":"searching"})
callback({"status":"found", "new_version":version})
callback({"status":"installing", "new_version":version})
for status in self.sudo_proxy.fetch_version_iter(version):
    if callback is not None:
        callback(status)
callback({"status":"cleaning up"})
callback({"status":"cleaning up"})
callback({"status":"error","exception":e})
callback({"status":"done"})