Imported updater module directly from socializer

This commit is contained in:
Manuel Cortez 2020-07-17 17:50:18 -05:00
parent 12a4ee65c3
commit f0f23c9b05
5 changed files with 100 additions and 56 deletions

View File

@ -0,0 +1,12 @@
import glob
import os.path
import platform
def find_datafiles():
system = platform.system()
if system == 'Windows':
file_ext = '*.exe'
else:
file_ext = '*.sh'
path = os.path.abspath(os.path.join(__path__[0], 'bootstrappers', file_ext))
return [('', glob.glob(path))]

View File

@ -1,31 +1,31 @@
from logging import getLogger from logging import getLogger
logger = getLogger('update') logger = getLogger('update')
import sys
import contextlib import contextlib
import io import io
import os import os
import platform import platform
import requests import requests
import tempfile import tempfile
import widgetUtils
import webbrowser
try: try:
import czipfile as zipfile import czipfile as zipfile
except ImportError: except ImportError:
import zipfile import zipfile
import paths from platform_utils import paths
def perform_update(endpoint, current_version, app_name='', password=None, update_available_callback=None, progress_callback=None, update_complete_callback=None): def perform_update(endpoint, current_version, update_type="stable", app_name='', password=None, update_available_callback=None, progress_callback=None, update_complete_callback=None):
requests_session = create_requests_session(app_name=app_name, version=current_version) requests_session = create_requests_session(app_name=app_name, version=current_version)
available_update = find_update(endpoint, requests_session=requests_session) available_update = find_update(endpoint, requests_session=requests_session)
if not available_update: if not available_update:
logger.debug("No update available") logger.debug("No update available")
return False return False
available_version = float(available_update['current_version']) available_version, available_description, update_url = find_version_data(update_type, current_version, available_update)
if not float(available_version) > float(current_version) or platform.system()+platform.architecture()[0][:2] not in available_update['downloads']: if available_version == False:
logger.debug("No update for this architecture")
return False return False
available_description = available_update.get('description', None)
update_url = available_update ['downloads'][platform.system()+platform.architecture()[0][:2]]
logger.info("A new update is available. Version %s" % available_version) logger.info("A new update is available. Version %s" % available_version)
if callable(update_available_callback) and not update_available_callback(version=available_version, description=available_description): #update_available_callback should return a falsy value to stop the process if callable(update_available_callback) and not update_available_callback(version=available_version, description=available_description): #update_available_callback should return a falsy value to stop the process
logger.info("User canceled update.") logger.info("User canceled update.")
@ -55,6 +55,23 @@ def find_update(endpoint, requests_session):
content = response.json() content = response.json()
return content return content
def find_version_data(update_type, current_version, available_update):
if update_type == "stable":
available_version = float(available_update['current_version'])
if not float(available_version) > float(current_version) or platform.system()+platform.architecture()[0][:2] not in available_update['downloads']:
logger.debug("No update for this architecture")
return (False, False, False)
available_description = available_update.get('description', None)
update_url = available_update ['downloads'][platform.system()+platform.architecture()[0][:2]]
return (available_version, available_description, update_url)
else: # Unstable versions, based in commits instead of version numbers.
available_version = available_update["current_version"]
if available_version == current_version:
return (False, False, False)
available_description = available_update["description"]
update_url = available_update ['downloads'][platform.system()+platform.architecture()[0][:2]]
return (available_version, available_description, update_url)
def download_update(update_url, update_destination, requests_session, progress_callback=None, chunk_size=io.DEFAULT_BUFFER_SIZE): def download_update(update_url, update_destination, requests_session, progress_callback=None, chunk_size=io.DEFAULT_BUFFER_SIZE):
total_downloaded = total_size = 0 total_downloaded = total_size = 0
with io.open(update_destination, 'w+b') as outfile: with io.open(update_destination, 'w+b') as outfile:

View File

@ -1,14 +1,24 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import sys
import application import application
import platform import platform
import logging import logging
from requests.exceptions import ConnectionError from requests.exceptions import ConnectionError
from .import update from . import update
from .wxUpdater import * from .wxUpdater import *
logger = logging.getLogger("updater") logger = logging.getLogger("updater")
def do_update(endpoint=application.update_url): def do_update(update_type="alpha"):
try: # Updates cannot be performed in the source code version.
return update.perform_update(endpoint=endpoint, current_version=application.version, app_name=application.name, update_available_callback=available_update_dialog, progress_callback=progress_callback, update_complete_callback=update_finished) if hasattr(sys, "frozen") == False:
except ConnectionError: return
logger.exception("Update failed.") if update_type == "stable":
endpoint = application.update_stable_url
version = application.version
else:
endpoint = application.update_next_url
version = application.update_next_version
try:
return update.perform_update(endpoint=endpoint, current_version=version, app_name=application.name, update_type=update_type, update_available_callback=available_update_dialog, progress_callback=progress_callback, update_complete_callback=update_finished)
except ConnectionError:
logger.exception("Update failed.")

View File

@ -1,42 +1,43 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals
def convert_bytes(n): def convert_bytes(n):
K, M, G, T, P = 1 << 10, 1 << 20, 1 << 30, 1 << 40, 1 << 50 K, M, G, T, P = 1 << 10, 1 << 20, 1 << 30, 1 << 40, 1 << 50
if n >= P: if n >= P:
return '%.2fPb' % (float(n) / T) return '%.2fPb' % (float(n) / T)
elif n >= T: elif n >= T:
return '%.2fTb' % (float(n) / T) return '%.2fTb' % (float(n) / T)
elif n >= G: elif n >= G:
return '%.2fGb' % (float(n) / G) return '%.2fGb' % (float(n) / G)
elif n >= M: elif n >= M:
return '%.2fMb' % (float(n) / M) return '%.2fMb' % (float(n) / M)
elif n >= K: elif n >= K:
return '%.2fKb' % (float(n) / K) return '%.2fKb' % (float(n) / K)
else: else:
return '%d' % n return '%d' % n
def seconds_to_string(seconds, precision=0): def seconds_to_string(seconds, precision=0):
day = seconds // 86400 day = seconds // 86400
hour = seconds // 3600 hour = seconds // 3600
min = (seconds // 60) % 60 min = (seconds // 60) % 60
sec = seconds - (hour * 3600) - (min * 60) sec = seconds - (hour * 3600) - (min * 60)
sec_spec = "." + str(precision) + "f" sec_spec = "." + str(precision) + "f"
sec_string = sec.__format__(sec_spec) sec_string = sec.__format__(sec_spec)
string = "" string = ""
if day == 1: if day == 1:
string += _(u"%d day, ") % day string += _("%d day, ") % day
elif day >= 2: elif day >= 2:
string += _(u"%d days, ") % day string += _("%d days, ") % day
if (hour == 1): if (hour == 1):
string += _(u"%d hour, ") % hour string += _("%d hour, ") % hour
elif (hour >= 2): elif (hour >= 2):
string += _("%d hours, ") % hour string += _("%d hours, ") % hour
if (min == 1): if (min == 1):
string += _(u"%d minute, ") % min string += _("%d minute, ") % min
elif (min >= 2): elif (min >= 2):
string += _(u"%d minutes, ") % min string += _("%d minutes, ") % min
if sec >= 0 and sec <= 2: if sec >= 0 and sec <= 2:
string += _(u"%s second") % sec_string string += _("%s second") % sec_string
else: else:
string += _(u"%s seconds") % sec_string string += _("%s seconds") % sec_string
return string return string

View File

@ -1,22 +1,26 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals # at top of module from __future__ import division
from __future__ import unicode_literals
import wx import wx
import application import application
from .import utils from . import utils
progress_dialog = None progress_dialog = None
def available_update_dialog(version, description): def available_update_dialog(version, description):
dialog = wx.MessageDialog(None, _(u"There's a new %s version available. Would you like to download it now?\n\n %s version: %s\n\nChanges:\n%s") % (application.name, application.name, version, description), _(u"New version for %s") % application.name, style=wx.YES|wx.NO|wx.ICON_WARNING) dialog = wx.MessageDialog(None, _("There's a new {app_name} version available. Would you like to download it now?\n\n {app_name} version: {app_version}\n\nChanges:\n{changes}").format(app_name=application.name, app_version=version, changes=description), _("New version for %s") % application.name, style=wx.YES|wx.NO|wx.ICON_WARNING)
if dialog.ShowModal() == wx.ID_YES: if dialog.ShowModal() == wx.ID_YES:
return True return True
else: else:
return False return False
def create_progress_dialog(): def create_progress_dialog():
return wx.ProgressDialog(_(u"Download in Progress"), _(u"Downloading the new version..."), parent=None, maximum=100) return wx.ProgressDialog(_("Download in Progress"), _("Downloading the new version..."), parent=None, maximum=100)
def progress_callback(total_downloaded, total_size): def progress_callback(total_downloaded, total_size):
wx.CallAfter(_progress_callback, total_downloaded, total_size)
def _progress_callback(total_downloaded, total_size):
global progress_dialog global progress_dialog
if progress_dialog == None: if progress_dialog == None:
progress_dialog = create_progress_dialog() progress_dialog = create_progress_dialog()
@ -24,7 +28,7 @@ def progress_callback(total_downloaded, total_size):
if total_downloaded == total_size: if total_downloaded == total_size:
progress_dialog.Destroy() progress_dialog.Destroy()
else: else:
progress_dialog.Update((total_downloaded*100)/total_size, _(u"Updating... %s of %s") % (str(utils.convert_bytes(total_downloaded)), str(utils.convert_bytes(total_size)))) progress_dialog.Update((total_downloaded*100)/total_size, _("Updating... {total_transferred} of {total_size}").format(total_transferred=utils.convert_bytes(total_downloaded), total_size=utils.convert_bytes(total_size)))
def update_finished(): def update_finished():
ms = wx.MessageDialog(None, _(u"The update has been downloaded and installed successfully. Press OK to continue."), _(u"Done!")).ShowModal() return wx.MessageDialog(None, _("The update has been downloaded and installed successfully. Press OK to continue."), _("Done!")).ShowModal()