def _patch_update(self, name, version): # pragma: no cover log.info('Starting patch update') filename = get_filename(name, version, self.platform, self.easy_data) log.debug('Archive filename: %s', filename) if filename is None: log.warning('Make sure version numbers are correct. ' 'Possible TRAP!') return False latest = get_highest_version(name, self.platform, self.channel, self.easy_data) # Just checking to see if the zip for the current version is # available to patch If not we'll just do a full binary download if not os.path.exists(os.path.join(self.update_folder, filename)): log.warning( '%s got deleted. No base binary to start patching ' 'form', filename) return False # Initilize Patch object with all required information p = Patcher(name=name, json_data=self.json_data, current_version=version, latest_version=latest, update_folder=self.update_folder, update_urls=self.update_urls, verify=self.verify, progress_hooks=self.progress_hooks) # Returns True if everything went well # If False is returned then we will just do the full # update. return p.start()
def _patch_update(self, name, version): # pragma: no cover log.debug('Starting patch update') filename = get_filename(name, version, self.platform, self.easy_data) log.debug('Archive filename: %s', filename) if filename is None: log.debug('Make sure version numbers are correct. ' 'Possible TRAP!') return False latest = get_highest_version(name, self.platform, self.channel, self.easy_data) # Just checking to see if the zip for the current version is # available to patch If not we'll just do a full binary download if not os.path.exists(os.path.join(self.update_folder, filename)): log.debug('%s got deleted. No base binary to start patching ' 'form', filename) return False # Initilize Patch object with all required information p = Patcher(name=name, json_data=self.json_data, current_version=version, latest_version=latest, update_folder=self.update_folder, update_urls=self.update_urls, verify=self.verify, progress_hooks=self.progress_hooks) # Returns True if everything went well # If False is returned then we will just do the full # update. return p.start()
def _extract_update(self): with jms_utils.paths.ChDir(self.update_folder): platform_name = self.name # Ensuring we only add .exe when applicable if sys.platform == 'win32' and \ self.name == self.app_name: # pragma: no cover # We only add .exe to app executable. Not libs or dll log.debug('Adding .exe to filename for windows main ' 'app udpate.') platform_name += '.exe' # Ensuring we extract the latest version latest = get_highest_version(self.name, self.platform, self.easy_data) # Get full filename of latest update archive filename = get_filename(self.name, latest, self.platform, self.easy_data) if not os.path.exists(filename): log.error('File does not exists') raise ClientError('File does not exists') log.info('Extracting Update') archive_ext = os.path.splitext(filename)[1].lower() # Handles extracting gzip or zip archives if archive_ext == '.gz': try: with tarfile.open(filename, 'r:gz') as tfile: # Extract file update to current # directory. tfile.extractall() except Exception as err: # pragma: no cover log.error(err) log.debug(str(err), exc_info=True) raise ClientError('Error reading gzip file') elif archive_ext == '.zip': try: with zipfile.ZipFile(filename, 'r') as zfile: # Extract update file to current # directory. zfile.extractall() except Exception as err: # pragma: no cover log.error(str(err)) log.debug(str(err), exc_info=True) raise ClientError('Error reading zip file') else: raise ClientError('Unknown filetype')
def __init__(self, data): self.updates_key = settings.UPDATES_KEY self.update_urls = data.get('update_urls') self.name = data.get('name') self.current_version = data.get('version') self.easy_data = data.get('easy_data') # Raw form of easy_data self.json_data = data.get('json_data') self.data_dir = data.get('data_dir') self.platform = data.get('platform') self.app_name = data.get('app_name') self.channel = data.get('channel', 'stable') self.progress_hooks = data.get('progress_hooks') self.update_folder = os.path.join(self.data_dir, settings.UPDATE_FOLDER) self.verify = data.get('verify', True) self.current_app_dir = os.path.dirname(sys.executable) self.status = False # If user is using async download this will be True. # Future calls to an download methods will not run # until the current download is complete. Which will # set this back to False. self._is_downloading = False # Used to generate file name of archive self.latest = get_highest_version(self.name, self.platform, self.channel, self.easy_data) self.current_archive_filename = get_filename(self.name, self.current_version, self.platform, self.easy_data) # Get full filename of latest update archive self.filename = get_filename(self.name, self.latest, self.platform, self.easy_data) assert self.filename is not None # Removes old versions, of this asset, from # the updates folder. self.cleanup()
def _full_update(self, name): log.info('Starting full update') latest = get_highest_version(name, self.platform, self.easy_data) filename = get_filename(name, latest, self.platform, self.easy_data) hash_key = '{}*{}*{}*{}*{}'.format(self.updates_key, name, latest, self.platform, 'file_hash') file_hash = self.easy_data.get(hash_key) with jms_utils.paths.ChDir(self.update_folder): log.info('Downloading update...') fd = FileDownloader(filename, self.update_urls, file_hash, self.verify, self.progress_hooks) result = fd.download_verify_write() if result: log.info('Download Complete') return True else: # pragma: no cover log.error('Failed To Download Latest Version') return False
def _is_downloaded(self, name): latest = get_highest_version(name, self.platform, self.easy_data) filename = get_filename(name, latest, self.platform, self.easy_data) hash_key = '{}*{}*{}*{}*{}'.format(self.updates_key, name, latest, self.platform, 'file_hash') _hash = self.easy_data.get(hash_key) # Comparing file hashes to ensure security with jms_utils.paths.ChDir(self.update_folder): if not os.path.exists(filename): return False try: with open(filename, 'rb') as f: data = f.read() except Exception as err: log.debug(err, exc_info=True) return False if _hash == get_hash(data): return True else: return False
def __init__(self, data): self.updates_key = settings.UPDATES_KEY self.update_urls = data.get('update_urls') self.name = data.get('name') self.version = data.get('version') self.easy_data = data.get('easy_data') # Raw form of easy_data self.json_data = data.get('json_data') self.data_dir = data.get('data_dir') self.platform = data.get('platform') self.app_name = data.get('app_name') self.channel = data.get('channel', 'stable') self.progress_hooks = data.get('progress_hooks') self.update_folder = os.path.join(self.data_dir, settings.UPDATE_FOLDER) self.verify = data.get('verify', True) self.current_app_dir = os.path.dirname(sys.executable) self.status = False # If user is using async download this will be True. # Future calls to an download methods will not run # until the current download is complete. Which will # set this back to False. self._is_downloading = False # Used to generate file name of archive latest = get_highest_version(self.name, self.platform, self.channel, self.easy_data) # Get full filename of latest update archive self.filename = get_filename(self.name, latest, self.platform, self.easy_data) assert self.filename is not None self.abspath = os.path.join(self.update_folder, self.filename) # Removes old versions, of update being checked, from # updates folder. Since we only start patching from # the current binary this shouldn't be a problem. self.cleanup()
def _update_check(self, name, version, channel): valid_channels = ['alpha', 'beta', 'stable'] if channel not in valid_channels: log.error('Invalid channel. May need to check spelling') channel = 'stable' self.name = name version = Version(version) self.version = str(version) # Will be set to true if we are updating an app and not a lib app = False # No json data is loaded. # User may need to call refresh if self.ready is False: log.warning('No update manifest found') return None # If we are an app we will need restart functionality. # AppUpdate instead of LibUpdate if self.FROZEN is True and self.name == self.app_name: app = True # Checking if version file is verified before # processing data contained in the version file. # This was done by self._get_update_manifest() if self.verified is False: log.error('Failed version file verification') return None log.info('Checking for %s updates...', name) # If None is returned get_highest_version could # not find the supplied name in the version file latest = get_highest_version(name, self.platform, channel, self.easy_data) if latest is None: log.debug('Could not find the latest version') return None latest = Version(latest) log.debug('Current vesion: %s', str(version)) log.debug('Latest version: %s', str(latest)) needed = latest > version log.debug('Update Needed: %s', needed) if latest <= version: log.info('%s already updated to the latest version', name) return None # Hey, finally made it to the bottom! # Looks like its time to do some updating data = { 'update_urls': self.update_urls, 'name': self.name, 'version': self.version, 'easy_data': self.easy_data, 'json_data': self.json_data, 'data_dir': self.data_dir, 'platform': self.platform, 'channel': channel, 'app_name': self.app_name, 'verify': self.verify, # Ensure single occurrence of each callbackc 'progress_hooks': list(set(self.progress_hooks)), } # Return update object with which handles downloading, # extracting updates if app is True: # AppUpdate objects also has methods to restart # the app with the new version return AppUpdate(data) else: return LibUpdate(data)
def _update_check(self, name, version): self.name = name version = Version(version) self.version = str(version) # Will be set to true if we are updating an app and not a lib app = False # No json data is loaded. # User may need to call refresh if self.ready is False: log.warning('No update manifest found') return None # If we are an app we will need restart functionality. # AppUpdate instead of LibUpdate if self.FROZEN is True and self.name == self.app_name: app = True # Checking if version file is verified before # processing data contained in the version file. # This was done by self._get_update_manifest() if self.verified is False: log.error('Failed version file verification') return None log.info('Checking for {} updates...'.format(name)) # If None is returned get_highest_version could # not find the supplied name in the version file latest = get_highest_version(name, self.platform, self.easy_data) if latest is None: log.debug('Could not find the latest version') return None latest = Version(latest) log.debug('Current vesion: {}'.format(str(version))) log.debug('Latest version: {}'.format(str(latest))) log.debug('Update Truth: {}'.format(latest >= version)) if latest <= version: log.info('{} already updated to the latest version'.format(name)) return None # Hey, finally made it to the bottom! # Looks like its time to do some updating log.info('Update available') data = { 'update_urls': self.update_urls, 'name': self.name, 'version': self.version, 'easy_data': self.easy_data, 'json_data': self.json_data, 'data_dir': self.data_dir, 'platform': self.platform, 'app_name': self.app_name, 'verify': self.verify, 'progress_hooks': self.progress_hooks, } # Return update object with which handles downloading, # extracting updates if app is True: # AppUpdate objects also has methods to restart # the app with the new version return AppUpdate(data) else: return LibUpdate(data)
def _update_check(self, name, version, channel): valid_channels = ['alpha', 'beta', 'stable'] if channel not in valid_channels: log.debug('Invalid channel. May need to check spelling') channel = 'stable' self.name = name # Version object used for comparison version = Version(version) self.version = str(version) # Will be set to true if we are updating the currently # running app and not an app's asset app = False if self.ready is False: # No json data is loaded. # User may need to call refresh log.debug('No update manifest found') return None # Checking if version file is verified before # processing data contained in the version file. # This was done by self._get_update_manifest if self.verified is False: log.debug('Failed version file verification') return None # If we are an app we will need restart functionality, so we'll # user AppUpdate instead of LibUpdate if self.FROZEN is True and self.name == self.app_name: app = True log.debug('Checking for %s updates...', name) latest = get_highest_version(name, self.platform, channel, self.easy_data) if latest is None: # If None is returned get_highest_version could # not find the supplied name in the version file log.debug('Could not find the latest version') return None # Change str to version object for easy comparison latest = Version(latest) log.debug('Current vesion: %s', str(version)) log.debug('Latest version: %s', str(latest)) update_needed = latest > version log.debug('Update Needed: %s', update_needed) if latest <= version: log.debug('%s already updated to the latest version', name) return None # Config data to initialize update object data = { 'update_urls': self.update_urls, 'name': self.name, 'version': self.version, 'easy_data': self.easy_data, 'json_data': self.json_data, 'data_dir': self.data_dir, 'platform': self.platform, 'channel': channel, 'app_name': self.app_name, 'verify': self.verify, # Ensure single occurrence of each callbackc 'progress_hooks': list(set(self.progress_hooks)), } # Return update object with which handles downloading, # extracting updates if app is True: # AppUpdate objects also has methods to restart # the app with the new version return AppUpdate(data) else: return LibUpdate(data)