def _overwrite(self): # Unix: Overwrites the running applications binary if get_system() == 'mac': if self._current_app_dir.endswith('MacOS') is True: log.debug('Looks like we\'re dealing with a Mac Gui') temp_dir = get_mac_dot_app_dir(self._current_app_dir) self._current_app_dir = temp_dir app_update = os.path.join(self.update_folder, self.name) # Must be dealing with Mac .app application if not os.path.exists(app_update): app_update += '.app' log.debug('Update Location:\n%s', os.path.dirname(app_update)) log.debug('Update Name: %s', os.path.basename(app_update)) current_app = os.path.join(self._current_app_dir, self.name) # Must be dealing with Mac .app application if not os.path.exists(current_app): current_app += '.app' log.debug('Current App location:\n\n%s', current_app) # Remove current app to prevent errors when moving # update to new location if os.path.exists(current_app): remove_any(current_app) log.debug('Moving app to new location:\n\n%s', self._current_app_dir) shutil.move(app_update, self._current_app_dir)
def _archive(self, args, temp_name): # Now archive the file with ChDir(self.new_dir): if os.path.exists(temp_name + '.app'): log.debug('Got mac .app') app_name = temp_name + '.app' Builder._mac_binary_rename(app_name, self.app_name) elif os.path.exists(temp_name + '.exe'): log.debug('Got win .exe') app_name = temp_name + '.exe' else: app_name = temp_name version = args.app_version log.debug('Temp Name: %s', temp_name) log.debug('Appname: %s', app_name) log.debug('Version: %s', version) # Time for some archive creation! filename = make_archive(self.app_name, app_name, version) log.debug('Archive name: %s', filename) if args.keep is False: if os.path.exists(temp_name): log.debug('Removing: %s', temp_name) remove_any(temp_name) if os.path.exists(app_name): log.debug('Removing: %s', temp_name) remove_any(app_name) log.info('%s has been placed in your new folder\n', filename)
def _overwrite(self): # pragma: no cover # Unix: Overwrites the running applications binary if dsdev_utils.system.get_system() == 'mac': if self.current_app_dir.endswith('MacOS') is True: log.debug('Looks like we\'re dealing with a Mac Gui') temp_dir = get_mac_dot_app_dir(self.current_app_dir) self.current_app_dir = temp_dir app_update = os.path.join(self.update_folder, self.name) # Must be dealing with Mac .app application if not os.path.exists(app_update): app_update += '.app' log.debug('Update Location:\n%s', os.path.dirname(app_update)) log.debug('Update Name: %s', os.path.basename(app_update)) current_app = os.path.join(self.current_app_dir, self.name) # Must be dealing with Mac .app application if not os.path.exists(current_app): current_app += '.app' log.debug('Current App location:\n\n%s', current_app) # Remove current app to prevent errors when moving # update to new location if os.path.exists(current_app): remove_any(current_app) log.debug('Moving app to new location:\n\n%s', self.current_app_dir) shutil.move(app_update, self.current_app_dir)
def upload(self): """Uploads all files in file_list""" failed_uploads = [] self.files_completed = 1 self.file_count = len(self.files) log.info('Plugin: %s', self.uploader.name) log.info('Author: %s', self.uploader.author) for f in self.files: basename = os.path.basename(f) msg = '\n\nUploading: {}'.format(basename) msg2 = ' - File {} of {}\n'.format(self.files_completed, self.file_count) print(msg + msg2) complete = self.uploader.upload_file(f) if complete: log.debug('%s uploaded successfully', basename) if self.keep is False: remove_any(f) self.files_completed += 1 else: log.debug('%s failed to upload. will retry', basename) failed_uploads.append(f) if len(failed_uploads) > 0: failed_uploads = self._retry_upload(failed_uploads) if len(failed_uploads) < 1: print("\nUpload Complete") return True else: print('The following files were not uploaded') for i in failed_uploads: log.error('%s failed to upload', os.path.basename(i)) print(i) return False
def upload(self): """Uploads all files in file_list""" failed_uploads = [] self.files_completed = 1 self.file_count = len(self.files) log.info('Plugin: %s', self.uploader.name) log.info('Author: %s', self.uploader.author) for f in self.files: basename = os.path.basename(f) msg = '\n\nUploading: {}' .format(basename) msg2 = ' - File {} of {}\n'.format(self.files_completed, self.file_count) print(msg + msg2) complete = self.uploader.upload_file(f) if complete: log.debug('%s uploaded successfully', basename) if self.keep is False: remove_any(f) self.files_completed += 1 else: log.debug('%s failed to upload. will retry', basename) failed_uploads.append(f) if len(failed_uploads) > 0: failed_uploads = self._retry_upload(failed_uploads) if len(failed_uploads) < 1: print("\nUpload Complete") time.sleep(3) return True else: print('The following files were not uploaded') for i in failed_uploads: log.error('%s failed to upload', os.path.basename(i)) print(i) return False
def _archive(self, args, temp_name): # Now archive the file with dsdev_utils.paths.ChDir(self.new_dir): if os.path.exists(temp_name + '.app'): log.debug('Got mac .app') app_name = temp_name + '.app' self._mac_binary_rename(app_name, self.app_name) elif os.path.exists(temp_name + '.exe'): log.debug('Got win .exe') app_name = temp_name + '.exe' else: app_name = temp_name version = args.app_version log.debug('Temp Name: %s', temp_name) log.debug('Appname: %s', app_name) log.debug('Version: %s', version) # Time for some archive creation! filename = make_archive(self.app_name, app_name, version) log.debug('Archive name: %s', filename) if args.keep is False: if os.path.exists(temp_name): log.debug('Removing: %s', temp_name) remove_any(temp_name) if os.path.exists(app_name): log.debug('Removing: %s', temp_name) remove_any(app_name) log.info('%s has been placed in your new folder\n', filename)
def remove_previous_versions(directory, filename): """Removes previous version of named file""" log.debug("In remove_previous_versions") if filename is None: log.debug("Cleanup Failed - Filename is None") return log.debug("Filename: %s", filename) if directory is None: log.debug("Cleanup Failed - Directory is None") return log.debug("Directory: %s", directory) try: # We set the full path here because Package() checks if filename exists package_info = Package(os.path.join(directory, filename)) except (UtilsError, VersionError): log.debug("Cleanup Failed: %s - Cannot parse package info.", filename) return if package_info.info["status"] is False: log.debug( "Not an archive format: %s - %s", package_info.name, package_info.info["reason"], ) return log.debug("Current version: %s", package_info.version) assert package_info.name is not None log.debug("Name to search for: %s", package_info.name) with ChDir(directory): temp = os.listdir(os.getcwd()) for t in temp: log.debug("Checking: %s", t) # Only attempt to remove old files of the one we # are updating temp_pkg = Package(t) if temp_pkg.info["status"] is False: continue if package_info.name != temp_pkg.name: log.debug("File does not match name of current binary") continue if package_info.channel != temp_pkg.channel: continue log.debug("Found possible match") log.debug("Latest name: %s", package_info.filename) log.debug("Old name: %s", temp_pkg.filename) if temp_pkg.version < package_info.version: old_path = os.path.join(directory, t) log.debug("Removing old update: %s", old_path) remove_any(old_path) else: log.debug("Old version: %s", temp_pkg.version) log.debug("Current version: %s", package_info.version)
def _archive(self, temp_name): # Now archive the file with ChDir(self.new_dir): if os.path.exists(temp_name + ".app"): log.debug("Got mac .app") app_name = temp_name + ".app" Builder._mac_binary_rename(app_name, self.app_name) elif os.path.exists(temp_name + ".exe"): log.debug("Got win .exe") app_name = temp_name + ".exe" else: app_name = temp_name version = self.args.app_version log.debug("Temp Name: %s", temp_name) log.debug("Appname: %s", app_name) log.debug("Version: %s", version) # Time for some archive creation! filename = make_archive(self.app_name, app_name, version, self.args.archive_format) log.debug("Archive name: %s", filename) if self.args.keep is False: if os.path.exists(temp_name): log.debug("Removing: %s", temp_name) remove_any(temp_name) if os.path.exists(app_name): log.debug("Removing: %s", temp_name) remove_any(app_name) log.debug("%s has been placed in your new folder\n", filename)
def make_archive(name, target, version, external=False): """Used to make archives of file or dir. Zip on windows and tar.gz on all other platforms Args: name - Name to rename binary. version - Version of app. Used to create archive filename target - Name of file to archive. external - True when archiving external binary otherwise false Returns: (str) - name of archive """ file_dir = os.path.dirname(os.path.abspath(target)) filename = '{}-{}-{}'.format(os.path.splitext(name)[0], dsdev_utils.system.get_system(), version) filename_path = os.path.join(file_dir, filename) log.debug('starting archive') # ToDo: Fix this stuff. This seems janky temp_file = name if external is False: ext = os.path.splitext(target)[1] temp_file = name + ext # Remove file if it exists. Found during testing... log.debug('Temp file: %s', temp_file) if os.path.exists(temp_file): remove_any(temp_file) if os.path.isfile(target): shutil.copy(target, temp_file) else: shutil.copytree(target, temp_file) # End ToDo: End of janky # Only use zip on windows. # Zip doens't preserve file permissions on nix & mac # tar.gz creates full file path if dsdev_utils.system.get_system() == 'win': ext = '.zip' with zipfile.ZipFile(filename_path + '.zip', 'w') as zf: zf.write(target, temp_file) else: ext = '.tar.gz' if os.path.isfile(target): with tarfile.open(filename_path + '.tar.gz', 'w:gz') as tar: tar.add(target, temp_file) else: shutil.make_archive(filename, 'gztar', file_dir, temp_file) if os.path.exists(temp_file): remove_any(temp_file) output_filename = filename + ext log.debug('Archive output filename: %s', output_filename) return output_filename
def make_archive(name, target, version): """Used to make archives of file or dir. Zip on windows and tar.gz on all other platforms Args: name - Name to rename binary. version - Version of app. Used to create archive filename target - Name of file to archive. Returns: (str) - name of archive """ log.debug('starting archive') ext = os.path.splitext(target)[1] temp_file = name + ext log.debug('Temp file: %s', temp_file) # Remove file if it exists. Found during testing... if os.path.exists(temp_file): paths.remove_any(temp_file) if os.path.isfile(target): shutil.copy(target, temp_file) else: shutil.copytree(target, temp_file) # renames the entry-point executable file_ext = '.exe' if system.get_system() == 'win' else '' src_executable = temp_file + os.sep + target + file_ext dst_executable = temp_file + os.sep + name + file_ext # is an osx bundle app so does not need to fix the executable name if ext != '.app': shutil.move(src_executable, dst_executable) # is a win folder so the manifest need to be renamed too if system.get_system() == 'win': src_manifest = src_executable + '.manifest' dst_manifest = dst_executable + '.manifest' shutil.move(src_manifest, dst_manifest) file_dir = os.path.dirname(os.path.abspath(target)) filename = '{}-{}-{}'.format( os.path.splitext(name)[0], system.get_system(), version) # Only use zip on windows. # Zip does not preserve file permissions on nix & mac # tar.gz creates full file path with paths.ChDir(file_dir): ext = 'gztar' if system.get_system() == 'win': ext = 'zip' output_filename = shutil.make_archive(filename, ext, file_dir, temp_file) if os.path.exists(temp_file): paths.remove_any(temp_file) log.debug('Archive output filename: %s', output_filename) return output_filename
def test_extract_no_file(self, client): update = client.update_check(client.app_name, '0.0.1') assert update is not None assert update.download() is True with ChDir(update.update_folder): files = os.listdir(os.getcwd()) for f in files: remove_any(f) if get_system() != 'win': assert update.extract() is False
def make_archive(name, target, version): """Used to make archives of file or dir. Zip on windows and tar.gz on all other platforms Args: name - Name to rename binary. version - Version of app. Used to create archive filename target - Name of file to archive. Returns: (str) - name of archive """ log.debug('starting archive') ext = os.path.splitext(target)[1] temp_file = name + ext log.debug('Temp file: %s', temp_file) # Remove file if it exists. Found during testing... if os.path.exists(temp_file): paths.remove_any(temp_file) if os.path.isfile(target): shutil.copy(target, temp_file) else: shutil.copytree(target, temp_file) file_dir = os.path.dirname(os.path.abspath(target)) filename = '{}-{}-{}'.format(os.path.splitext(name)[0], system.get_system(), version) # Only use zip on windows. # Zip doens't preserve file permissions on nix & mac # tar.gz creates full file path with paths.ChDir(file_dir): if system.get_system() == 'win': ext = '.zip' with zipfile.ZipFile(filename + ext, 'w') as zf: zf.write(target, temp_file) else: ext = '.tar.gz' with tarfile.open(filename + ext, 'w:gz', compresslevel=0) as tar: tar.add(target, temp_file) if os.path.exists(temp_file): paths.remove_any(temp_file) output_filename = filename + ext log.debug('Archive output filename: %s', output_filename) return output_filename
def dir_requires_admin(dir): """ Check if a dir required admin permissions to write. If dir is a file test it's directory. """ dir = os.path.dirname(dir) dummy_filepath = os.path.join(dir, str(uuid.uuid4())) try: with open(dummy_filepath, 'w'): pass remove_any(dummy_filepath) return False except IOError: return True
def _clean(): cleaned = False if os.path.exists(settings.CONFIG_DATA_FOLDER): cleaned = True remove_any(settings.CONFIG_DATA_FOLDER) log.info('Removed %s folder', settings.CONFIG_DATA_FOLDER) if os.path.exists(settings.USER_DATA_FOLDER): cleaned = True remove_any(settings.USER_DATA_FOLDER) log.info('Removed %s folder', settings.USER_DATA_FOLDER) if cleaned is True: log.info('Clean complete...') else: log.info('Nothing to clean...')
def _setup(self): # Create required directories self.pyi_dir = os.path.join(os.getcwd(), settings.USER_DATA_FOLDER) self.new_dir = os.path.join(self.pyi_dir, 'new') self.build_dir = os.path.join(os.getcwd(), settings.CONFIG_DATA_FOLDER) self.spec_dir = os.path.join(self.build_dir, 'spec') self.work_dir = os.path.join(self.build_dir, 'work') for d in [self.build_dir, self.spec_dir, self.work_dir, self.pyi_dir, self.new_dir]: if os.path.exists(self.work_dir): remove_any(self.work_dir) if not os.path.exists(d): log.debug('Creating directory: %s', d) os.mkdir(d)
def archive(args): check = check_repo() if check is False: _repo_error() new_dir = os.path.join(CWD, settings.USER_DATA_FOLDER, 'new') name = args.name version = args.version with ChDir(new_dir): if not os.path.exists(name): log.error('%s does not exists', name) return ex_lib = ExternalLib(name, version) ex_lib.archive() if args.keep is False: remove_any(name) log.info('Removed: %s', name)
def _clean(*args): cleaned = False # The .pyupdater folder if os.path.exists(settings.CONFIG_DATA_FOLDER): cleaned = True remove_any(settings.CONFIG_DATA_FOLDER) log.info('Removed %s folder', settings.CONFIG_DATA_FOLDER) # The pyu-data folder if os.path.exists(settings.USER_DATA_FOLDER): cleaned = True remove_any(settings.USER_DATA_FOLDER) log.info('Removed %s folder', settings.USER_DATA_FOLDER) if cleaned is True: log.info('Clean complete...') else: log.info('Nothing to clean...')
def _retry_upload(self, failed_uploads): # Takes list of failed downloads and tries to re upload them retry = failed_uploads[:] failed_uploads = [] failed_count = len(retry) count = 1 for f in retry: msg = 'Retyring: {} - File {} of {}'.format(f, count, failed_count) log.info(msg) complete = self.uploader.upload_file(f) if complete: log.debug('%s uploaded on retry', f) if self.keep is False: remove_any(f) count += 1 else: failed_uploads.append(f) return failed_uploads
def main(): with ChDir(DEST_DIR): files = os.listdir(os.getcwd()) for f in files: remove_any(f) with ChDir(HTML_DIR): files = os.listdir(os.getcwd()) for f in files: if f.startswith(u'.'): continue if f.startswith('__init__'): continue if os.path.isfile(f): shutil.copy(f, os.path.join(DEST_DIR, f)) elif os.path.isdir(f): shutil.copytree(f, DEST_DIR + os.sep + f) shutil.rmtree(HTML_DIR)
def _retry_upload(self, failed_uploads): # Takes list of failed downloads and tries to re upload them retry = failed_uploads[:] failed_uploads = [] failed_count = len(retry) count = 1 for f in retry: msg = "Retyring: {} - File {} of {}".format(f, count, failed_count) log.info(msg) complete = self.uploader.upload_file(f) if complete: log.debug("%s uploaded on retry", f) if self.keep is False: remove_any(f) count += 1 else: failed_uploads.append(f) return failed_uploads
def _cmd_archive(*args): check_repo_ex(exit_on_error=True) ns = args[0] new_dir = os.path.join(CWD, settings.USER_DATA_FOLDER, 'new') name = ns.name version = ns.version with ChDir(new_dir): if not os.path.exists(name): log.error('%s does not exists', name) return # Creating a pyupdater compatible archive. # See pyupdater.builder for more info. ex_lib = ExternalLib(name, version) ex_lib.archive() if ns.keep is False: remove_any(name) log.info('Removed: %s', name)
def _write_update_to_disk(self): # pragma: no cover # Writes updated binary to disk log.debug("Writing update to disk") filename_key = "{}*{}*{}*{}*{}".format( settings.UPDATES_KEY, self.name, self.latest_version, self.platform, "filename", ) filename = self.star_access_update_data.get(filename_key) if filename is None: raise PatcherError("Filename missing in version file") with ChDir(self.update_folder): try: with open(filename, "wb") as f: f.write(self.og_binary) log.debug("Wrote update file") except IOError: # Removes file if it got created if os.path.exists(filename): remove_any(filename) log.debug("Failed to open file for writing") raise PatcherError("Failed to open file for writing") else: file_info = self._get_info(self.name, self.latest_version, option="file") new_file_hash = file_info["file_hash"] log.debug("checking file hash match") if new_file_hash != get_package_hashes(filename): log.debug("Version file hash: %s", new_file_hash) log.debug("Actual file hash: %s", get_package_hashes(filename)) log.debug("File hash does not match") remove_any(filename) raise PatcherError("Bad hash on patched file", expected=True)
def _cmd_archive(*args): check_repo_ex(exit_on_error=True) log.info("Archiving asset...") ns = args[0] new_dir = os.path.join(CWD, settings.USER_DATA_FOLDER, 'new') name = ns.name version = ns.version with ChDir(new_dir): if not os.path.exists(name): log.error('%s does not exists', name) return # Creating a pyupdater compatible archive. # See pyupdater.builder for more info. ex_lib = ExternalLib(name, version) ex_lib.archive() if ns.keep is False: remove_any(name) log.info('Removed: %s', name) log.info("Archiving complete")
def _overwrite(self): # Unix: Overwrites the running applications binary if get_system() == 'mac': if self._current_app_dir.endswith('MacOS') is True: log.debug('Looks like we\'re dealing with a Mac Gui') temp_dir = get_mac_dot_app_dir(self._current_app_dir) self._current_app_dir = temp_dir app_update = os.path.join(self.update_folder, self.name) # Must be dealing with Mac .app application if not os.path.exists(app_update) and sys.platform == "darwin": app_update += '.app' log.debug('Update Location:\n%s', os.path.dirname(app_update)) log.debug('Update Name: %s', os.path.basename(app_update)) current_app = os.path.join(self._current_app_dir, self.name) # Must be dealing with Mac .app application if not os.path.exists(current_app): current_app += '.app' log.debug('Current App location:\n\n%s', current_app) # Remove current app to prevent errors when moving # update to new location # if update_app is a directory, then we are updating a directory if os.path.isdir(app_update): if (os.path.isdir(current_app)): shutil.rmtree(current_app) else: shutil.rmtree(os.path.dirname(current_app)) if os.path.exists(current_app): remove_any(current_app) log.debug('Moving app to new location:\n\n%s', self._current_app_dir) shutil.move(app_update, self._current_app_dir)
def _overwrite(self): # Unix: Overwrites the running applications binary if get_system() == "mac": if self._current_app_dir.endswith("MacOS") is True: log.debug("Looks like we're dealing with a Mac Gui") temp_dir = get_mac_dot_app_dir(self._current_app_dir) self._current_app_dir = temp_dir app_update = os.path.join(self.update_folder, self.name) # Must be dealing with Mac .app application if not os.path.exists(app_update) and sys.platform == "darwin": app_update += ".app" log.debug("Update Location:\n%s", os.path.dirname(app_update)) log.debug("Update Name: %s", os.path.basename(app_update)) current_app = os.path.join(self._current_app_dir, self.name) # Must be dealing with Mac .app application if not os.path.exists(current_app): current_app += ".app" log.debug("Current App location:\n\n%s", current_app) # Remove current app to prevent errors when moving # update to new location # if update_app is a directory, then we are updating a directory if os.path.isdir(app_update): if os.path.isdir(current_app): shutil.rmtree(current_app) else: shutil.rmtree(os.path.dirname(current_app)) if os.path.exists(current_app): remove_any(current_app) log.debug("Moving app to new location:\n\n%s", self._current_app_dir) shutil.move(app_update, self._current_app_dir)
def _write_update_to_disk(self): # pragma: no cover # Writes updated binary to disk log.debug('Writing update to disk') filename_key = '{}*{}*{}*{}*{}'.format(settings.UPDATES_KEY, self.name, self.latest_version, self.platform, 'filename') filename = self.star_access_update_data.get(filename_key) if filename is None: raise PatcherError('Filename missing in version file') with ChDir(self.update_folder): try: with open(filename, 'wb') as f: f.write(self.og_binary) log.debug('Wrote update file') except IOError: # Removes file if it got created if os.path.exists(filename): remove_any(filename) log.debug('Failed to open file for writing') raise PatcherError('Failed to open file for writing') else: file_info = self._get_info(self.name, self.latest_version, option='file') new_file_hash = file_info['file_hash'] log.debug('checking file hash match') if new_file_hash != get_package_hashes(filename): log.debug('Version file hash: %s', new_file_hash) log.debug('Actual file hash: %s', get_package_hashes(filename)) log.debug('File hash does not match') remove_any(filename) raise PatcherError('Bad hash on patched file', expected=True)
def upload(self, files=None): """Uploads all files in file_list""" self._get_files_to_upload(files) failed_uploads = [] files_completed = 1 file_count = len(self.files) log.info("Plugin: %s", self.uploader.name) log.info("Author: %s", self.uploader.author) for f in self.files: basename = os.path.basename(f) msg = "\n\nUploading: {}".format(basename) msg2 = " - File {} of {}\n".format(files_completed, file_count) print(msg + msg2) complete = self.uploader.upload_file(f) if complete: log.debug("%s uploaded successfully", basename) if self.keep is False: remove_any(f) files_completed += 1 else: log.debug("%s failed to upload. will retry", basename) failed_uploads.append(f) if len(failed_uploads) > 0: failed_uploads = self._retry_upload(failed_uploads) if len(failed_uploads) < 1: return True else: log.error("The following files were not uploaded") for i in failed_uploads: log.error("%s failed to upload", os.path.basename(i)) return False
def remove_previous_versions(directory, filename): "Removes previous version of named file" if filename is None: log.debug('Cleanup Failed - Filename is None') return log.debug('Filename: %s', filename) if directory is None: log.debug('Cleanup Failed - Directory is None') return log.debug('Directory: %s', directory) try: current_version = Version(filename) except (UtilsError, VersionError): # pragma: no cover log.warning('Cleanup Failed - Cannot parse version info.') return try: # We set the full path here because Package() checks if filename exists package_info = Package(os.path.join(directory, filename)) except (UtilsError, VersionError): log.warning('Cleanup Failed - Cannot parse package info.') return if package_info.info['status'] is False: log.debug('Not an archive format: %s', package_info.name) return log.debug('Current version: %s', str(current_version)) assert package_info.name is not None log.debug('Name to search for: %s', package_info.name) with ChDir(directory): temp = os.listdir(os.getcwd()) for t in temp: log.debug('Checking: %s', t) # Only attempt to remove old files of the one we # are updating if package_info.name not in t: log.debug('File does not match name of current binary') continue else: log.debug('Found possible match') log.debug('Latest name: %s', package_info.name) log.debug('Old name: %s', t) try: old_version = Version(t) except (UtilsError, VersionError): # pragma: no cover log.warning('Cannot parse version info') # Skip file since we can't parse continue log.debug('Found version: %s', str(old_version)) if old_version < current_version: old_path = os.path.join(directory, t) log.debug('Removing old update: %s', old_path) remove_any(old_path) else: log.debug('Old version: %s', old_version) log.debug('Current version: %s', current_version)
def test_execution_one_dir_restart( self, cleandir, shared_datadir, simpleserver, pyu, custom_dir, port, windowed, split_version, ): data_dir = shared_datadir / "update_repo_restart" pyu.setup() # We are moving all of the files from the deploy directory to the # cwd. We will start a simple http server to use for updates with ChDir(data_dir): simpleserver.start(port) with open("pyu.log", "w") as f: f.write("") cmd = "python build_onedir_restart.py %s %s %s %s" % ( custom_dir, port, windowed, split_version, ) os.system(cmd) # Moving all files from the deploy directory to the cwd # since that is where we will start the simple server deploy_dir = os.path.join("pyu-data", "deploy") assert os.path.exists(deploy_dir) test_cwd = os.getcwd() with ChDir(deploy_dir): files = os.listdir(os.getcwd()) for f in files: if f == ".DS_Store": continue shutil.move(f, test_cwd) dir_name = "Acme" if not os.path.exists(dir_name): dir_name = dir_name + ".app" assert os.path.exists(dir_name) assert os.path.isdir(dir_name) app_name = "Acme" if sys.platform == "darwin" and windowed: pass else: app_name = os.path.join(dir_name, app_name) if sys.platform != "win32": app_name = "./{}".format(app_name) if sys.platform == "win32": app_name += ".exe" app_run_command = app_name if sys.platform != "win32": app_run_command = "./{}".format(app_name) if sys.platform == "darwin" and windowed: app_run_command = "./{}.app/Contents/MacOS/{}".format( app_name, app_name ) app_name = "{}.app".format(app_name) if custom_dir: # update with custom_dir is multiprocessing-safe lock_path = "pyu.lock" else: if not os.path.exists(appdirs.user_data_dir(APP_NAME)): os.makedirs(appdirs.user_data_dir(APP_NAME), exist_ok=True) lock_path = os.path.join(appdirs.user_data_dir(APP_NAME), "pyu.lock") update_lock = filelock.FileLock(lock_path, LOCK_TIMEOUT) version_file = "version2.txt" with update_lock.acquire(LOCK_TIMEOUT, 5): count = 0 while count < 5: # Call the binary to self update subprocess.call(app_run_command, shell=True) if os.path.exists(version_file): break count += 1 print("Retrying app launch!") # Allow enough time for update process to complete. time.sleep(AUTO_UPDATE_PAUSE) simpleserver.stop() # Detect if it was an overwrite error assert os.path.exists(app_name) assert os.path.exists(version_file) with open(version_file, "r") as f: output = f.read().strip() assert output == "4.2" if os.path.exists(app_name): if os.path.isdir(app_name): remove_any(app_name) else: remove_any(os.path.dirname(app_name)) if os.path.exists(version_file): remove_any(version_file)
def remove_previous_versions(directory, filename): """Removes previous version of named file""" if filename is None: log.debug('Cleanup Failed - Filename is None') return log.debug('Filename: %s', filename) if directory is None: log.debug('Cleanup Failed - Directory is None') return log.debug('Directory: %s', directory) try: current_version = Version(filename) except (UtilsError, VersionError): # pragma: no cover log.debug('Cleanup Failed: %s - Cannot parse version info.', filename) return try: # We set the full path here because Package() checks if filename exists package_info = Package(os.path.join(directory, filename)) except (UtilsError, VersionError): log.debug('Cleanup Failed: %s - Cannot parse package info.', filename) return if package_info.info['status'] is False: log.debug('Not an archive format: %s', package_info.name) return log.debug('Current version: %s', str(current_version)) assert package_info.name is not None log.debug('Name to search for: %s', package_info.name) with ChDir(directory): temp = os.listdir(os.getcwd()) for t in temp: log.debug('Checking: %s', t) # Only attempt to remove old files of the one we # are updating if package_info.name not in t: log.debug('File does not match name of current binary') continue else: log.debug('Found possible match') log.debug('Latest name: %s', package_info.name) log.debug('Old name: %s', t) try: old_version = Version(t) except (UtilsError, VersionError): # pragma: no cover log.warning('Cannot parse version info') # Skip file since we can't parse continue log.debug('Found version: %s', str(old_version)) if old_version < current_version: old_path = os.path.join(directory, t) log.debug('Removing old update: %s', old_path) remove_any(old_path) else: log.debug('Old version: %s', old_version) log.debug('Current version: %s', current_version)
def test_execution_one_file_extract(self, cleandir, shared_datadir, simpleserver, pyu, custom_dir, port, windowed): data_dir = shared_datadir / 'update_repo_extract' pyu.setup() # We are moving all of the files from the deploy directory to the # cwd. We will start a simple http server to use for updates with ChDir(data_dir): simpleserver.start(port) cmd = 'python build_onefile_extract.py %s %s %s' % (custom_dir, port, windowed) os.system(cmd) # Moving all files from the deploy directory to the cwd # since that is where we will start the simple server deploy_dir = os.path.join('pyu-data', 'deploy') assert os.path.exists(deploy_dir) test_cwd = os.getcwd() with ChDir(deploy_dir): files = os.listdir(os.getcwd()) for f in files: if f == '.DS_Store': continue shutil.move(f, test_cwd) app_name = 'Acme' if sys.platform == 'win32': app_name += '.exe' with open('pyu.log', 'w') as f: f.write('') app_run_command = app_name if sys.platform != 'win32': app_run_command = './{}'.format(app_name) if sys.platform == 'darwin' and windowed: app_run_command = './{}.app/Contents/MacOS/{}'.format(app_name, app_name) app_name = '{}.app'.format(app_name) if custom_dir: # update with custom_dir is multiprocessing-safe lock_path = 'pyu.lock' else: if not os.path.exists(appdirs.user_data_dir(APP_NAME)): os.makedirs(appdirs.user_data_dir(APP_NAME)) lock_path = os.path.join(appdirs.user_data_dir(APP_NAME), 'pyu.lock') update_lock = filelock.FileLock(lock_path, LOCK_TIMEOUT) output_file = 'version1.txt' with update_lock.acquire(LOCK_TIMEOUT, 5): count = 0 while count < 5: # Call the binary to self update subprocess.call(app_run_command, shell=True) if os.path.exists(output_file): break count += 1 print("Retrying app launch") # Allow enough time for update process to complete. time.sleep(AUTO_UPDATE_PAUSE) # Call the binary to ensure it's # the updated binary subprocess.call(app_run_command, shell=True) simpleserver.stop() # Detect if it was an overwrite error assert os.path.exists(app_name) assert os.path.exists(output_file) with open(output_file, 'r') as f: output = f.read().strip() assert output == '4.2' if os.path.exists(app_name): if os.path.isdir(app_name): remove_any(app_name) else: remove_any(app_name) if os.path.exists(output_file): remove_any(output_file)