示例#1
0
    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
示例#2
0
    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
示例#3
0
    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()
示例#4
0
    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
示例#5
0
文件: worker.py 项目: alesmuc/bauh
    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()
示例#6
0
 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)
示例#7
0
 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)
示例#8
0
    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))
示例#9
0
    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
示例#10
0
    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
示例#11
0
    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
示例#12
0
    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 []
示例#13
0
    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
示例#14
0
 def _is_internet_available(self, res: dict):
     res['available'] = internet.is_available(self.context.http_client,
                                              self.context.logger)
示例#15
0
    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()