cloudmatrix / esky

an auto-update framework for frozen python apps
BSD 3-Clause "New" or "Revised" License
362 stars 74 forks source link

Esky differential patches not working #136

Closed julianx closed 6 years ago

julianx commented 8 years ago

I'm trying to auto update using Esky differential patches, but I haven't been able to get the app to update using only those differential patches. It seems like a full version is always needed for a correct update.

So, if I have version 0.1 and patches plus full file versions up to 0.3 in the updates server, the client app will fetch both the patches AND the full latest version file:

updatesServer/
  App-0.1.win32.zip (client version running)
  App-0.2.win32.zip (this isn't fetched)
  App-0.2.win32.from-0.1.patch (this is fetched first)
  App-0.3.win32.zip (this is fetched third)
  App-0.3.win32.from-0.2.patch (this is fetched second)

Also, if the latest version weren't to be available (App-0.3.win32.zip in this case), the update would fail.

The behavior I would expect is for Esky to get the patch file and update while ignoring the other full file version available so the update is blazing fast. Is there a way to achieve this?

Environment info: the freezer I'm using is cx_freeze and my Python version is 3.4.

Update-routine code:

from esky import *
from esky.util import appexe_from_executable

def restart_this_app():
    appexe = appexe_from_executable(sys.executable)
    os.execv(appexe,[appexe] + sys.argv[1:])

if hasattr(sys, "frozen"):
    app = esky.Esky(sys.executable, UPDATES_URL)
    print("You are running version "+app.active_version)
    print("Looking for updates...")
    if app.find_update() is None:
        print("No updates have been found.")
    else:
        print("Updates available. Updating...")
        try:
            app.auto_update()
        except Exception as e:
            print("Error while updating:", e)
        else:
            print("Update complete.")
            print("Restarting app...")
            time.sleep(3)
            restart_this_app()
JPFrancoia commented 8 years ago

Ok, first, we will need more information about why esky fails to update with patches. Can you provide the 'e' string please (in your exception) ?

Also, I use a recipe of my own to handle exceptions (you will have to import the traceback module):

except Exception as e:
            log(traceback.format_exc()) # Or:
            print(traceback.format_exc())

So I can log the complete stacktrace. It would be helpful to have yours.

JPFrancoia commented 8 years ago

Ok since nobody is posting his file, I'm posting mine:

  File "C:\Users\djipey\Desktop\ChemBrows_freeze\updater.py", line 61, in run
    self.app.auto_update()
  File "C:\Python34\lib\site-packages\esky\__init__.py", line 626, in auto_update
    self._do_auto_update(version, callback)
  File "C:\Python34\lib\site-packages\esky\__init__.py", line 674, in _do_auto_update
    self.fetch_version(version, callback)
  File "C:\Python34\lib\site-packages\esky\__init__.py", line 716, in fetch_version
    loc = self.version_finder.fetch_version(self, version, callback)
  File "C:\Python34\lib\site-packages\esky\finder.py", line 79, in fetch_version
    for status in self.fetch_version_iter(app,version):
  File "C:\Python34\lib\site-packages\esky\finder.py", line 235, in fetch_version_iter
    self._prepare_version(app,version,local_path)
  File "C:\Python34\lib\site-packages\esky\finder.py", line 337, in _prepare_version
    apply_patch(uppath,f)
  File "C:\Python34\lib\site-packages\esky\patch.py", line 299, in apply_patch
    Patcher(target,stream,**kwds).patch()
  File "C:\Python34\lib\site-packages\esky\patch.py", line 628, in patch
    getattr(self,"_do_" + _COMMANDS[cmd])()
  File "C:\Python34\lib\site-packages\esky\patch.py", line 648, in _do_END
    self._context_stack.pop()()
  File "C:\Python34\lib\site-packages\esky\patch.py", line 878, in end_contents
    create_zipfile(t_temp,z_temp,members=zfmeta[0].infolist())
  File "C:\Python34\lib\site-packages\esky\util.py", line 415, in create_zipfile
    zf.writestr(zinfo,f.read())
  File "C:\Python34\lib\zipfile.py", line 1442, in writestr
    self._writecheck(zinfo)
  File "C:\Python34\lib\zipfile.py", line 1300, in _writecheck
    warnings.warn('Duplicate name: %r' % zinfo.filename, stacklevel=3)
  File "c:\python\32-bit\3.4\lib\warnings.py", line 15, in showwarning
AttributeError: 'NoneType' object has no attribute 'write'

My update with a patch crashes like that. The issue seems to come from the file c:\python\32-bit\3.4\lib\warnings.py, but this file does not exist. Look at the path, it's a lower c:.

Any idea ?

Hadi58 commented 8 years ago

In windows and with python 2.7 and esky 0.9.9 and py2exe 0.6.9, when i use complete zip file it works and update, but by patch file not work. when i trace 'download' and 'unpack' folders, all is OK and i see the patch file in 'download' and new updated version folder in 'unpack' folder. but after few seconds all of them were cleaned. and out of 'updates' folder don't change any things and not updated. Even wen i stop the program before it delete inner 'unpack' folder, and then run 'unpack' folder exe file of program, it work. but i don't understand why it is deleted by esky after unpacked.

JMSwag commented 8 years ago

@Hadi58 @JPFrancoia @julianx Check out PyUpdater, which is being actively developed. It may provided the functionality that you are looking for. Please note that PyUpdater doesn't support the sudo functionality that esky has. It's also only compatible with pyinstaller one file mode.

Hadi58 commented 8 years ago

It shows this error: Traceback (most recent call last): File "main.py", line 841, in File "main.py", line 333, in bootstrap File "main.py", line 360, in chainload File "main.py", line 837, in _chainload File "Media.py", line 40, in File "Media.py", line 36, in main File "Media.py", line 26, in run_main File "MainApp.pyc", line 127, in init File "eskyinit.pyc", line 673, in _do_auto_update File "eskyinit.pyc", line 715, in fetch_version File "esky\finder.pyc", line 80, in fetch_version File "esky\finder.pyc", line 221, in fetch_version_iter esky.errors.EskyVersionError: 2.1.6

rfk commented 6 years ago

Thanks for reaching out. Unfortunately this project is no longer actively maintained, so I'm going to move it into archive mode:

https://rfk.id.au/blog/entry/archiving-open-source-projects/