def list_warnings(self, internet_available: bool = None) -> List[str]: warnings = [] int_available = internet.is_available() if int_available: updates_msg = check_for_update(self.logger, self.http_client, self.i18n) if updates_msg: warnings.append(updates_msg) if self.managers: for man in self.managers: if man.is_enabled(): man_warnings = man.list_warnings( internet_available=int_available) if man_warnings: if warnings is None: warnings = [] warnings.extend(man_warnings) return warnings
def search(self, word: str, disk_loader: DiskCacheLoader = None, limit: int = -1) -> SearchResult: ti = time.time() self._wait_to_be_ready() res = SearchResult([], [], 0) if internet.is_available(self.context.http_client, self.context.logger): norm_word = word.strip().lower() disk_loader = self.disk_loader_factory.new() disk_loader.start() threads = [] for man in self.managers: t = Thread(target=self._search, args=(norm_word, man, disk_loader, res)) t.start() threads.append(t) for t in threads: t.join() if disk_loader: disk_loader.stop_working() disk_loader.join() res.installed = self._sort(res.installed, norm_word) res.new = self._sort(res.new, norm_word) res.total = len(res.installed) + len(res.new) else: raise NoInternetException() tf = time.time() self.logger.info('Took {0:.2f} seconds'.format(tf - ti)) return res
def _gen_installation_response(self, success: bool, pkg: SnapApplication, installed: Set[str], disk_loader: DiskCacheLoader): if success: new_installed = [pkg] if installed: try: current_installed = self.read_installed( disk_loader=disk_loader, internet_available=internet.is_available()).installed except: current_installed = None if current_installed and ( not installed or len(current_installed) > len(installed) + 1): for p in current_installed: if p.name != pkg.name and (not installed or p.name not in installed): new_installed.append(p) return TransactionResult(success=success, installed=new_installed, removed=[]) else: return TransactionResult.fail()
def change_channel(self, pkg: SnapApplication, root_password: str, watcher: ProcessWatcher) -> bool: if not internet.is_available(): raise NoInternetException() try: channel = self._request_channel_installation( pkg=pkg, snap_config=None, snapd_client=SnapdClient(self.logger), watcher=watcher, exclude_current=True) if not channel: watcher.show_message( title=self.i18n['snap.action.channel.label'], body=self.i18n['snap.action.channel.error.no_channel']) return False return ProcessHandler(watcher).handle_simple( snap.refresh_and_stream(app_name=pkg.name, root_password=root_password, channel=channel))[0] except: return False
def download_databases(self): if self.task_man: self.task_man.register_task(self.task_id, self.i18n['appimage.task.db_update'], get_icon_path()) self.task_man.update_progress(self.task_id, 10, None) try: if not internet.is_available(): self._finish_task() return except requests.exceptions.ConnectionError: self.logger.warning('The internet connection seems to be off.') self._finish_task() return self.logger.info('Retrieving AppImage databases') try: res = self.http_client.get(self.URL_DB, session=False) except Exception as e: self.logger.error("An error ocurred while downloading the AppImage database: {}".format(e.__class__.__name__)) res = None if res: Path(LOCAL_PATH).mkdir(parents=True, exist_ok=True) with open(self.COMPRESS_FILE_PATH, 'wb+') as f: f.write(res.content) self.logger.info("Database file saved at {}".format(self.COMPRESS_FILE_PATH)) old_db_files = glob.glob(LOCAL_PATH + '/*.db') if old_db_files: self.logger.info('Deleting old database files') for f in old_db_files: self.db_locks[f].acquire() try: os.remove(f) finally: self.db_locks[f].release() self.logger.info('Old database files deleted') self.logger.info('Uncompressing {}'.format(self.COMPRESS_FILE_PATH)) try: tf = tarfile.open(self.COMPRESS_FILE_PATH) tf.extractall(LOCAL_PATH) self.logger.info('Successfully uncompressed file {}'.format(self.COMPRESS_FILE_PATH)) except: self.logger.error('Could not extract file {}'.format(self.COMPRESS_FILE_PATH)) traceback.print_exc() finally: self.logger.info('Deleting {}'.format(self.COMPRESS_FILE_PATH)) os.remove(self.COMPRESS_FILE_PATH) self.logger.info('Successfully removed {}'.format(self.COMPRESS_FILE_PATH)) self._finish_task() else: self.logger.warning('Could not download the database file {}'.format(self.URL_DB)) self._finish_task()
def prepare(self, task_manager: TaskManager, root_password: str, internet_available: bool): if self.managers: internet_on = internet.is_available() for man in self.managers: if man not in self._already_prepared and self._can_work(man): if task_manager: man.prepare(task_manager, root_password, internet_on) self._already_prepared.append(man)
def prepare(self, task_manager: TaskManager, root_password: str, internet_available: bool): if self.managers: internet_on = internet.is_available() taskman = task_manager if task_manager else TaskManager( ) # empty task manager to prevent null pointers for man in self.managers: if man not in self._already_prepared and self._can_work(man): man.prepare(taskman, root_password, internet_on) self._already_prepared.append(man)
def download_databases(self): try: if not internet.is_available(self.http_client, self.logger): return except requests.exceptions.ConnectionError: self.logger.warning('The internet connection seems to be off.') return self.logger.info('Retrieving AppImage databases') res = self.http_client.get(self.URL_DB) if res: Path(LOCAL_PATH).mkdir(parents=True, exist_ok=True) with open(self.COMPRESS_FILE_PATH, 'wb+') as f: f.write(res.content) self.logger.info("Database file saved at {}".format(self.COMPRESS_FILE_PATH)) old_db_files = glob.glob(LOCAL_PATH + '/*.db') if old_db_files: self.logger.info('Deleting old database files') for f in old_db_files: self.db_locks[f].acquire() try: os.remove(f) finally: self.db_locks[f].release() self.logger.info('Old database files deleted') self.logger.info('Uncompressing {}'.format(self.COMPRESS_FILE_PATH)) try: tf = tarfile.open(self.COMPRESS_FILE_PATH) tf.extractall(LOCAL_PATH) self.logger.info('Successfully uncompressed file {}'.format(self.COMPRESS_FILE_PATH)) except: self.logger.error('Could not extract file {}'.format(self.COMPRESS_FILE_PATH)) traceback.print_exc() finally: self.logger.info('Deleting {}'.format(self.COMPRESS_FILE_PATH)) os.remove(self.COMPRESS_FILE_PATH) self.logger.info('Successfully removed {}'.format(self.COMPRESS_FILE_PATH)) else: self.logger.warning('Could not download the database file {}'.format(self.URL_DB))
def list_suggestions(self, limit: int) -> List[PackageSuggestion]: if self.managers and internet.is_available(self.context.http_client, self.context.logger): suggestions, threads = [], [] for man in self.managers: t = Thread(target=self._fill_suggestions, args=(suggestions, man, SUGGESTIONS_LIMIT)) t.start() threads.append(t) for t in threads: t.join() if suggestions: suggestions.sort(key=lambda s: s.priority.value, reverse=True) return suggestions
def list_updates(self, internet_available: bool = None) -> List[PackageUpdate]: self._wait_to_be_ready() updates = [] if self.managers: net_available = internet.is_available() for man in self.managers: if self._can_work(man): man_updates = man.list_updates( internet_available=net_available) if man_updates: updates.extend(man_updates) return updates
def list_warnings(self, internet_available: bool = None) -> List[str]: warnings = [] if self.managers: int_available = internet.is_available(self.context.http_client, self.context.logger) for man in self.managers: if man.is_enabled(): man_warnings = man.list_warnings(internet_available=int_available) if man_warnings: if warnings is None: warnings = [] warnings.extend(man_warnings) return warnings
def list_suggestions(self, limit: int, filter_installed: bool) -> List[PackageSuggestion]: if bool(self.config['suggestions']['enabled']): if self.managers and internet.is_available(self.context.http_client, self.context.logger): suggestions, threads = [], [] for man in self.managers: t = Thread(target=self._fill_suggestions, args=(suggestions, man, int(self.config['suggestions']['by_type']), filter_installed)) t.start() threads.append(t) for t in threads: t.join() if suggestions: suggestions.sort(key=lambda s: s.priority.value, reverse=True) return suggestions return []
def read_installed(self, disk_loader: DiskCacheLoader = None, limit: int = -1, only_apps: bool = False, pkg_types: Set[Type[SoftwarePackage]] = None, internet_available: bool = None) -> SearchResult: ti = time.time() self._wait_to_be_ready() res = SearchResult([], None, 0) disk_loader = None net_available = internet.is_available() if not pkg_types: # any type for man in self.managers: if self._can_work(man): if not disk_loader: disk_loader = self.disk_loader_factory.new() disk_loader.start() mti = time.time() man_res = man.read_installed( disk_loader=disk_loader, pkg_types=None, internet_available=net_available) mtf = time.time() self.logger.info(man.__class__.__name__ + " took {0:.2f} seconds".format(mtf - mti)) res.installed.extend(man_res.installed) res.total += man_res.total else: man_already_used = [] for t in pkg_types: man = self.map.get(t) if man and (man not in man_already_used) and self._can_work(man): if not disk_loader: disk_loader = self.disk_loader_factory.new() disk_loader.start() mti = time.time() man_res = man.read_installed( disk_loader=disk_loader, pkg_types=None, internet_available=net_available) mtf = time.time() self.logger.info(man.__class__.__name__ + " took {0:.2f} seconds".format(mtf - mti)) res.installed.extend(man_res.installed) res.total += man_res.total if disk_loader: disk_loader.stop_working() disk_loader.join() if res.installed: for p in res.installed: if p.is_update_ignored(): if p.categories is None: p.categories = ['updates_ignored'] elif 'updates_ignored' not in p.categories: p.categories.append('updates_ignored') tf = time.time() self.logger.info('Took {0:.2f} seconds'.format(tf - ti)) return res
def _is_internet_available(self, res: dict): res['available'] = internet.is_available(self.context.http_client, self.context.logger)
def install(self, pkg: FlatpakApplication, root_password: str, disk_loader: DiskCacheLoader, watcher: ProcessWatcher) -> TransactionResult: config = read_config() install_level = config['installation_level'] if install_level is not None: self.logger.info("Default Flaptak installation level defined: {}".format(install_level)) if install_level not in ('user', 'system'): watcher.show_message(title=self.i18n['error'].capitalize(), body=self.i18n['flatpak.install.bad_install_level.body'].format(field=bold('installation_level'), file=bold(CONFIG_FILE)), type_=MessageType.ERROR) return TransactionResult(success=False, installed=[], removed=[]) pkg.installation = install_level else: user_level = watcher.request_confirmation(title=self.i18n['flatpak.install.install_level.title'], body=self.i18n['flatpak.install.install_level.body'].format(bold(pkg.name)), confirmation_label=self.i18n['no'].capitalize(), deny_label=self.i18n['yes'].capitalize()) pkg.installation = 'user' if user_level else 'system' remotes = flatpak.list_remotes() handler = ProcessHandler(watcher) if pkg.installation == 'user' and not remotes['user']: handler.handle_simple(flatpak.set_default_remotes('user')) elif pkg.installation == 'system' and not remotes['system']: if user.is_root(): handler.handle_simple(flatpak.set_default_remotes('system')) else: user_password, valid = watcher.request_root_password() if not valid: watcher.print('Operation aborted') return TransactionResult(success=False, installed=[], removed=[]) else: if not handler.handle_simple(flatpak.set_default_remotes('system', user_password))[0]: watcher.show_message(title=self.i18n['error'].capitalize(), body=self.i18n['flatpak.remotes.system_flathub.error'], type_=MessageType.ERROR) watcher.print("Operation cancelled") return TransactionResult(success=False, installed=[], removed=[]) # retrieving all installed so it will be possible to know the additional installed runtimes after the operation succeeds flatpak_version = flatpak.get_version() installed = flatpak.list_installed(flatpak_version) installed_by_level = {'{}:{}:{}'.format(p['id'], p['name'], p['branch']) for p in installed if p['installation'] == pkg.installation} if installed else None if not self._make_exports_dir(handler.watcher): return TransactionResult(success=False, installed=[], removed=[]) installed, output = handler.handle_simple(flatpak.install(str(pkg.id), pkg.origin, pkg.installation)) if not installed and 'error: No ref chosen to resolve matches' in output: ref_opts = RE_INSTALL_REFS.findall(output) if ref_opts and len(ref_opts) > 1: view_opts = [InputOption(label=o, value=o.strip()) for o in ref_opts if o] ref_select = SingleSelectComponent(type_=SelectViewType.RADIO, options=view_opts, default_option=view_opts[0], label='') if watcher.request_confirmation(title=self.i18n['flatpak.install.ref_choose.title'], body=self.i18n['flatpak.install.ref_choose.body'].format(bold(pkg.name)), components=[ref_select], confirmation_label=self.i18n['proceed'].capitalize(), deny_label=self.i18n['cancel'].capitalize()): ref = ref_select.get_selected() installed, output = handler.handle_simple(flatpak.install(ref, pkg.origin, pkg.installation)) pkg.ref = ref pkg.runtime = 'runtime' in ref else: watcher.print('Aborted by the user') return TransactionResult.fail() else: return TransactionResult.fail() if installed: try: fields = flatpak.get_fields(str(pkg.id), pkg.branch, ['Ref', 'Branch']) if fields: pkg.ref = fields[0] pkg.branch = fields[1] except: traceback.print_exc() if installed: new_installed = [pkg] current_installed = flatpak.list_installed(flatpak_version) current_installed_by_level = [p for p in current_installed if p['installation'] == pkg.installation] if current_installed else None if current_installed_by_level and (not installed_by_level or len(current_installed_by_level) > len(installed_by_level) + 1): pkg_key = '{}:{}:{}'.format(pkg.id, pkg.name, pkg.branch) net_available = internet.is_available() for p in current_installed_by_level: current_key = '{}:{}:{}'.format(p['id'], p['name'], p['branch']) if current_key != pkg_key and (not installed_by_level or current_key not in installed_by_level): new_installed.append(self._map_to_model(app_json=p, installed=True, disk_loader=disk_loader, internet=net_available)) return TransactionResult(success=installed, installed=new_installed, removed=[]) else: return TransactionResult.fail()