Imported updater module directly from socializer
This commit is contained in:
		@@ -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))]
 | 
			
		||||
 
 | 
			
		||||
@@ -1,31 +1,31 @@
 | 
			
		||||
from logging import getLogger
 | 
			
		||||
logger = getLogger('update')
 | 
			
		||||
 | 
			
		||||
import sys
 | 
			
		||||
import contextlib
 | 
			
		||||
import io
 | 
			
		||||
import os
 | 
			
		||||
import platform
 | 
			
		||||
import requests
 | 
			
		||||
import tempfile
 | 
			
		||||
import widgetUtils
 | 
			
		||||
import webbrowser
 | 
			
		||||
try:
 | 
			
		||||
	import czipfile as zipfile
 | 
			
		||||
except ImportError:
 | 
			
		||||
	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)
 | 
			
		||||
	available_update = find_update(endpoint, requests_session=requests_session)
 | 
			
		||||
	if not available_update:
 | 
			
		||||
		logger.debug("No update available")
 | 
			
		||||
		return False
 | 
			
		||||
	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")
 | 
			
		||||
	available_version, available_description, update_url = find_version_data(update_type, current_version, available_update)
 | 
			
		||||
	if available_version == 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)
 | 
			
		||||
	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.")
 | 
			
		||||
@@ -55,6 +55,23 @@ def find_update(endpoint, requests_session):
 | 
			
		||||
	content = response.json()
 | 
			
		||||
	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):
 | 
			
		||||
	total_downloaded = total_size = 0
 | 
			
		||||
	with io.open(update_destination, 'w+b') as outfile:
 | 
			
		||||
 
 | 
			
		||||
@@ -1,14 +1,24 @@
 | 
			
		||||
# -*- coding: utf-8 -*-
 | 
			
		||||
import sys
 | 
			
		||||
import application
 | 
			
		||||
import platform
 | 
			
		||||
import logging
 | 
			
		||||
from requests.exceptions import ConnectionError
 | 
			
		||||
from .import update
 | 
			
		||||
from . import update
 | 
			
		||||
from .wxUpdater import *
 | 
			
		||||
logger = logging.getLogger("updater")
 | 
			
		||||
 | 
			
		||||
def do_update(endpoint=application.update_url):
 | 
			
		||||
	try:
 | 
			
		||||
		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)
 | 
			
		||||
	except ConnectionError:
 | 
			
		||||
		logger.exception("Update failed.")
 | 
			
		||||
def do_update(update_type="alpha"):
 | 
			
		||||
 # Updates cannot be performed in the source code version.
 | 
			
		||||
 if hasattr(sys, "frozen") == False:
 | 
			
		||||
  return
 | 
			
		||||
 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.")
 | 
			
		||||
@@ -1,42 +1,43 @@
 | 
			
		||||
# -*- coding: utf-8 -*-
 | 
			
		||||
from __future__ import unicode_literals
 | 
			
		||||
 | 
			
		||||
def convert_bytes(n):
 | 
			
		||||
	K, M, G, T, P = 1 << 10, 1 << 20, 1 << 30, 1 << 40, 1 << 50
 | 
			
		||||
	if   n >= P:
 | 
			
		||||
		return '%.2fPb' % (float(n) / T)
 | 
			
		||||
	elif   n >= T:
 | 
			
		||||
		return '%.2fTb' % (float(n) / T)
 | 
			
		||||
	elif n >= G:
 | 
			
		||||
		return '%.2fGb' % (float(n) / G)
 | 
			
		||||
	elif n >= M:
 | 
			
		||||
		return '%.2fMb' % (float(n) / M)
 | 
			
		||||
	elif n >= K:
 | 
			
		||||
		return '%.2fKb' % (float(n) / K)
 | 
			
		||||
	else:
 | 
			
		||||
		return '%d' % n
 | 
			
		||||
 K, M, G, T, P = 1 << 10, 1 << 20, 1 << 30, 1 << 40, 1 << 50
 | 
			
		||||
 if   n >= P:
 | 
			
		||||
  return '%.2fPb' % (float(n) / T)
 | 
			
		||||
 elif   n >= T:
 | 
			
		||||
  return '%.2fTb' % (float(n) / T)
 | 
			
		||||
 elif n >= G:
 | 
			
		||||
  return '%.2fGb' % (float(n) / G)
 | 
			
		||||
 elif n >= M:
 | 
			
		||||
  return '%.2fMb' % (float(n) / M)
 | 
			
		||||
 elif n >= K:
 | 
			
		||||
  return '%.2fKb' % (float(n) / K)
 | 
			
		||||
 else:
 | 
			
		||||
  return '%d' % n
 | 
			
		||||
 | 
			
		||||
def seconds_to_string(seconds, precision=0):
 | 
			
		||||
	day = seconds // 86400
 | 
			
		||||
	hour = seconds // 3600
 | 
			
		||||
	min = (seconds // 60) % 60
 | 
			
		||||
	sec = seconds - (hour * 3600) - (min * 60)
 | 
			
		||||
	sec_spec = "." + str(precision) + "f"
 | 
			
		||||
	sec_string = sec.__format__(sec_spec)
 | 
			
		||||
	string = ""
 | 
			
		||||
	if day == 1:
 | 
			
		||||
		string += _(u"%d day, ") % day
 | 
			
		||||
	elif day >= 2:
 | 
			
		||||
		string += _(u"%d days, ") % day
 | 
			
		||||
	if (hour == 1):
 | 
			
		||||
		string += _(u"%d hour, ") % hour
 | 
			
		||||
	elif (hour >= 2):
 | 
			
		||||
		string += _("%d hours, ") % hour
 | 
			
		||||
	if (min == 1):
 | 
			
		||||
		string += _(u"%d minute, ") % min
 | 
			
		||||
	elif (min >= 2):
 | 
			
		||||
		string += _(u"%d minutes, ") % min
 | 
			
		||||
	if sec >= 0 and sec <= 2:
 | 
			
		||||
		string += _(u"%s second") % sec_string
 | 
			
		||||
	else:
 | 
			
		||||
		string += _(u"%s seconds") % sec_string
 | 
			
		||||
	return string
 | 
			
		||||
 day = seconds // 86400
 | 
			
		||||
 hour = seconds // 3600
 | 
			
		||||
 min = (seconds // 60) % 60
 | 
			
		||||
 sec = seconds - (hour * 3600) - (min * 60)
 | 
			
		||||
 sec_spec = "." + str(precision) + "f"
 | 
			
		||||
 sec_string = sec.__format__(sec_spec)
 | 
			
		||||
 string = ""
 | 
			
		||||
 if day == 1:
 | 
			
		||||
  string += _("%d day, ") % day
 | 
			
		||||
 elif day >= 2:
 | 
			
		||||
  string += _("%d days, ") % day
 | 
			
		||||
 if (hour == 1):
 | 
			
		||||
  string += _("%d hour, ") % hour
 | 
			
		||||
 elif (hour >= 2):
 | 
			
		||||
  string += _("%d hours, ") % hour
 | 
			
		||||
 if (min == 1):
 | 
			
		||||
  string += _("%d minute, ") % min
 | 
			
		||||
 elif (min >= 2):
 | 
			
		||||
  string += _("%d minutes, ") % min
 | 
			
		||||
 if sec >= 0 and sec <= 2:
 | 
			
		||||
  string += _("%s second") % sec_string
 | 
			
		||||
 else:
 | 
			
		||||
  string += _("%s seconds") % sec_string
 | 
			
		||||
 return string
 | 
			
		||||
@@ -1,22 +1,26 @@
 | 
			
		||||
# -*- coding: utf-8 -*-
 | 
			
		||||
from __future__ import unicode_literals    # at top of module
 | 
			
		||||
from __future__ import division
 | 
			
		||||
from __future__ import unicode_literals
 | 
			
		||||
import wx
 | 
			
		||||
import application
 | 
			
		||||
from .import utils
 | 
			
		||||
from . import utils
 | 
			
		||||
 | 
			
		||||
progress_dialog = None
 | 
			
		||||
 | 
			
		||||
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:
 | 
			
		||||
		return True
 | 
			
		||||
	else:
 | 
			
		||||
		return False
 | 
			
		||||
 | 
			
		||||
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):
 | 
			
		||||
	wx.CallAfter(_progress_callback, total_downloaded, total_size)
 | 
			
		||||
 | 
			
		||||
def _progress_callback(total_downloaded, total_size):
 | 
			
		||||
	global progress_dialog
 | 
			
		||||
	if progress_dialog == None:
 | 
			
		||||
		progress_dialog = create_progress_dialog()
 | 
			
		||||
@@ -24,7 +28,7 @@ def progress_callback(total_downloaded, total_size):
 | 
			
		||||
	if total_downloaded == total_size:
 | 
			
		||||
		progress_dialog.Destroy()
 | 
			
		||||
	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():
 | 
			
		||||
	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()
 | 
			
		||||
		Reference in New Issue
	
	Block a user