changed indentation from tabs to spaces
This commit is contained in:
@@ -3,10 +3,10 @@ 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))]
|
||||
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))]
|
||||
|
@@ -11,123 +11,123 @@ import tempfile
|
||||
import widgetUtils
|
||||
import webbrowser
|
||||
try:
|
||||
import czipfile as zipfile
|
||||
import czipfile as zipfile
|
||||
except ImportError:
|
||||
import zipfile
|
||||
import zipfile
|
||||
|
||||
from platform_utils import paths
|
||||
|
||||
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, available_description, update_url = find_version_data(update_type, current_version, available_update)
|
||||
if available_version == False:
|
||||
return False
|
||||
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.")
|
||||
return
|
||||
base_path = tempfile.mkdtemp()
|
||||
download_path = os.path.join(base_path, 'update.zip')
|
||||
update_path = os.path.join(base_path, 'update')
|
||||
downloaded = download_update(update_url, download_path, requests_session=requests_session, progress_callback=progress_callback)
|
||||
extracted = extract_update(downloaded, update_path, password=password)
|
||||
bootstrap_path = move_bootstrap(extracted)
|
||||
execute_bootstrap(bootstrap_path, extracted)
|
||||
logger.info("Update prepared for installation.")
|
||||
if callable(update_complete_callback):
|
||||
update_complete_callback()
|
||||
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, available_description, update_url = find_version_data(update_type, current_version, available_update)
|
||||
if available_version == False:
|
||||
return False
|
||||
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.")
|
||||
return
|
||||
base_path = tempfile.mkdtemp()
|
||||
download_path = os.path.join(base_path, 'update.zip')
|
||||
update_path = os.path.join(base_path, 'update')
|
||||
downloaded = download_update(update_url, download_path, requests_session=requests_session, progress_callback=progress_callback)
|
||||
extracted = extract_update(downloaded, update_path, password=password)
|
||||
bootstrap_path = move_bootstrap(extracted)
|
||||
execute_bootstrap(bootstrap_path, extracted)
|
||||
logger.info("Update prepared for installation.")
|
||||
if callable(update_complete_callback):
|
||||
update_complete_callback()
|
||||
|
||||
def create_requests_session(app_name=None, version=None):
|
||||
user_agent = ''
|
||||
session = requests.session()
|
||||
if app_name:
|
||||
user_agent = ' %s/%r' % (app_name, version)
|
||||
session.headers['User-Agent'] = session.headers['User-Agent'] + user_agent
|
||||
return session
|
||||
user_agent = ''
|
||||
session = requests.session()
|
||||
if app_name:
|
||||
user_agent = ' %s/%r' % (app_name, version)
|
||||
session.headers['User-Agent'] = session.headers['User-Agent'] + user_agent
|
||||
return session
|
||||
|
||||
def find_update(endpoint, requests_session):
|
||||
response = requests_session.get(endpoint)
|
||||
response.raise_for_status()
|
||||
content = response.json()
|
||||
return content
|
||||
response = requests_session.get(endpoint)
|
||||
response.raise_for_status()
|
||||
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)
|
||||
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:
|
||||
download = requests_session.get(update_url, stream=True)
|
||||
total_size = int(download.headers.get('content-length', 0))
|
||||
logger.debug("Total update size: %d" % total_size)
|
||||
download.raise_for_status()
|
||||
for chunk in download.iter_content(chunk_size):
|
||||
outfile.write(chunk)
|
||||
total_downloaded += len(chunk)
|
||||
if callable(progress_callback):
|
||||
call_callback(progress_callback, total_downloaded, total_size)
|
||||
logger.debug("Update downloaded")
|
||||
return update_destination
|
||||
total_downloaded = total_size = 0
|
||||
with io.open(update_destination, 'w+b') as outfile:
|
||||
download = requests_session.get(update_url, stream=True)
|
||||
total_size = int(download.headers.get('content-length', 0))
|
||||
logger.debug("Total update size: %d" % total_size)
|
||||
download.raise_for_status()
|
||||
for chunk in download.iter_content(chunk_size):
|
||||
outfile.write(chunk)
|
||||
total_downloaded += len(chunk)
|
||||
if callable(progress_callback):
|
||||
call_callback(progress_callback, total_downloaded, total_size)
|
||||
logger.debug("Update downloaded")
|
||||
return update_destination
|
||||
|
||||
def extract_update(update_archive, destination, password=None):
|
||||
"""Given an update archive, extracts it. Returns the directory to which it has been extracted"""
|
||||
with contextlib.closing(zipfile.ZipFile(update_archive)) as archive:
|
||||
if password:
|
||||
archive.setpassword(password)
|
||||
archive.extractall(path=destination)
|
||||
logger.debug("Update extracted")
|
||||
return destination
|
||||
"""Given an update archive, extracts it. Returns the directory to which it has been extracted"""
|
||||
with contextlib.closing(zipfile.ZipFile(update_archive)) as archive:
|
||||
if password:
|
||||
archive.setpassword(password)
|
||||
archive.extractall(path=destination)
|
||||
logger.debug("Update extracted")
|
||||
return destination
|
||||
|
||||
def move_bootstrap(extracted_path):
|
||||
working_path = os.path.abspath(os.path.join(extracted_path, '..'))
|
||||
if platform.system() == 'Darwin':
|
||||
extracted_path = os.path.join(extracted_path, 'Contents', 'Resources')
|
||||
downloaded_bootstrap = os.path.join(extracted_path, bootstrap_name())
|
||||
new_bootstrap_path = os.path.join(working_path, bootstrap_name())
|
||||
os.rename(downloaded_bootstrap, new_bootstrap_path)
|
||||
return new_bootstrap_path
|
||||
working_path = os.path.abspath(os.path.join(extracted_path, '..'))
|
||||
if platform.system() == 'Darwin':
|
||||
extracted_path = os.path.join(extracted_path, 'Contents', 'Resources')
|
||||
downloaded_bootstrap = os.path.join(extracted_path, bootstrap_name())
|
||||
new_bootstrap_path = os.path.join(working_path, bootstrap_name())
|
||||
os.rename(downloaded_bootstrap, new_bootstrap_path)
|
||||
return new_bootstrap_path
|
||||
|
||||
def execute_bootstrap(bootstrap_path, source_path):
|
||||
arguments = r'"%s" "%s" "%s" "%s"' % (os.getpid(), source_path, paths.app_path(), paths.get_executable())
|
||||
if platform.system() == 'Windows':
|
||||
import win32api
|
||||
win32api.ShellExecute(0, 'open', bootstrap_path, arguments, '', 5)
|
||||
else:
|
||||
import subprocess
|
||||
make_executable(bootstrap_path)
|
||||
subprocess.Popen(['%s %s' % (bootstrap_path, arguments)], shell=True)
|
||||
logger.info("Bootstrap executed")
|
||||
arguments = r'"%s" "%s" "%s" "%s"' % (os.getpid(), source_path, paths.app_path(), paths.get_executable())
|
||||
if platform.system() == 'Windows':
|
||||
import win32api
|
||||
win32api.ShellExecute(0, 'open', bootstrap_path, arguments, '', 5)
|
||||
else:
|
||||
import subprocess
|
||||
make_executable(bootstrap_path)
|
||||
subprocess.Popen(['%s %s' % (bootstrap_path, arguments)], shell=True)
|
||||
logger.info("Bootstrap executed")
|
||||
|
||||
def bootstrap_name():
|
||||
if platform.system() == 'Windows': return 'bootstrap.exe'
|
||||
if platform.system() == 'Darwin': return 'bootstrap-mac.sh'
|
||||
return 'bootstrap-lin.sh'
|
||||
if platform.system() == 'Windows': return 'bootstrap.exe'
|
||||
if platform.system() == 'Darwin': return 'bootstrap-mac.sh'
|
||||
return 'bootstrap-lin.sh'
|
||||
|
||||
def make_executable(path):
|
||||
import stat
|
||||
st = os.stat(path)
|
||||
os.chmod(path, st.st_mode | stat.S_IEXEC)
|
||||
import stat
|
||||
st = os.stat(path)
|
||||
os.chmod(path, st.st_mode | stat.S_IEXEC)
|
||||
|
||||
def call_callback(callback, *args, **kwargs):
|
||||
# try:
|
||||
callback(*args, **kwargs)
|
||||
callback(*args, **kwargs)
|
||||
# except:
|
||||
# logger.exception("Failed calling callback %r with args %r and kwargs %r" % (callback, args, kwargs))
|
||||
|
@@ -10,17 +10,17 @@ from .wxUpdater import *
|
||||
logger = logging.getLogger("updater")
|
||||
|
||||
def do_update(update_type="stable"):
|
||||
# Updates cannot be performed in the source code version of Socializer.
|
||||
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.")
|
||||
output.speak("An exception occurred while attempting to update " + application.name + ". If this message persists, contact the " + application.name + " developers. More information about the exception has been written to the error log.",True)
|
||||
# Updates cannot be performed in the source code version of Socializer.
|
||||
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.")
|
||||
output.speak("An exception occurred while attempting to update " + application.name + ". If this message persists, contact the " + application.name + " developers. More information about the exception has been written to the error log.",True)
|
||||
|
@@ -2,42 +2,42 @@
|
||||
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 += _("%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
|
||||
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
|
||||
|
@@ -8,27 +8,27 @@ from . import utils
|
||||
progress_dialog = None
|
||||
|
||||
def available_update_dialog(version, description):
|
||||
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
|
||||
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(_("Download in Progress"), _("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)
|
||||
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()
|
||||
progress_dialog.Show()
|
||||
if total_downloaded == total_size:
|
||||
progress_dialog.Destroy()
|
||||
else:
|
||||
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)))
|
||||
global progress_dialog
|
||||
if progress_dialog == None:
|
||||
progress_dialog = create_progress_dialog()
|
||||
progress_dialog.Show()
|
||||
if total_downloaded == total_size:
|
||||
progress_dialog.Destroy()
|
||||
else:
|
||||
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():
|
||||
return wx.MessageDialog(None, _("The update has been downloaded and installed successfully. Press OK to continue."), _("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