Exemplo n.º 1
0
    def read_installed(self, disk_loader: DiskCacheLoader, limit: int = -1, only_apps: bool = False, pkg_types: Set[Type[SoftwarePackage]] = None, internet_available: bool = None) -> SearchResult:
        version = flatpak.get_version()

        updates = []

        if internet_available:
            thread_updates = Thread(target=self._add_updates, args=(version, updates))
            thread_updates.start()
        else:
            thread_updates = None

        installed = flatpak.list_installed(version)
        models = []

        if installed:
            if thread_updates:
                thread_updates.join()

            for app_json in installed:
                model = self._map_to_model(app_json=app_json, installed=True,
                                           disk_loader=disk_loader, internet=internet_available)
                if version >= '1.5.0':
                    model.update = '{}/{}'.format(app_json['id'], app_json['branch']) in updates[0] if updates else None
                else:
                    model.update = app_json['ref'] in updates[0] if updates else None

                models.append(model)

        return SearchResult(models, None, len(models))
Exemplo n.º 2
0
    def read_installed(self, disk_loader: DiskCacheLoader, limit: int = -1, only_apps: bool = False, pkg_types: Set[Type[SoftwarePackage]] = None, internet_available: bool = None) -> SearchResult:
        version = flatpak.get_version()

        updates = []

        if internet_available:
            thread_updates = Thread(target=self._add_updates, args=(version, updates))
            thread_updates.start()
        else:
            thread_updates = None

        installed = flatpak.list_installed(version)
        models = []

        if installed:
            update_map = None
            if thread_updates:
                thread_updates.join()
                update_map = updates[0]

            for app_json in installed:
                model = self._map_to_model(app_json=app_json, installed=True,
                                           disk_loader=disk_loader, internet=internet_available)
                model.update = None
                models.append(model)

                if update_map and (update_map['full'] or update_map['partial']):
                    if version >= '1.4.0':
                        update_id = '{}/{}/{}'.format(app_json['id'], app_json['branch'], app_json['installation'])

                        if update_map['full'] and update_id in update_map['full']:
                            model.update = True

                        if update_map['partial']:
                            for partial in update_map['partial']:
                                partial_data = partial.split('/')
                                if app_json['id'] in partial_data[0] and\
                                        app_json['branch'] == partial_data[1] and\
                                        app_json['installation'] == partial_data[2]:
                                    partial_model = model.gen_partial(partial.split('/')[0])
                                    partial_model.update = True
                                    models.append(partial_model)
                    else:
                        model.update = '{}/{}'.format(app_json['installation'], app_json['ref']) in update_map['full']

        if models:
            ignored = self._read_ignored_updates()

            if ignored:
                for model in models:
                    if model.get_update_ignore_key() in ignored:
                        model.updates_ignored = True

        return SearchResult(models, None, len(models))
Exemplo n.º 3
0
    def install(self, pkg: FlatpakApplication, root_password: str,
                disk_loader: DiskCacheLoader,
                watcher: ProcessWatcher) -> TransactionResult:
        flatpak_config = self.configman.get_config()

        install_level = flatpak_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:
                valid, user_password = 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 = self.context.is_internet_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()
Exemplo n.º 4
0
    def read_installed(self, disk_loader: Optional[DiskCacheLoader], limit: int = -1, only_apps: bool = False, pkg_types: Set[Type[SoftwarePackage]] = None,
                       internet_available: bool = None, wait_async_data: bool = False) -> SearchResult:
        version = flatpak.get_version()

        updates, required_runtimes = list(), dict()

        thread_updates, thread_runtimes = None, None
        if internet_available:
            thread_updates = Thread(target=self._add_updates, args=(version, updates))
            thread_updates.start()

            if version >= VERSION_1_12:
                thread_runtimes = Thread(target=self._fill_required_runtime_updates, args=(required_runtimes,))
                thread_runtimes.start()

        installed = flatpak.list_installed(version)

        update_map = None
        if thread_updates:
            thread_updates.join()
            update_map = updates[0]

        models = {}
        data_loaders: Optional[List[FlatpakAsyncDataLoader]] = [] if wait_async_data else None

        if installed:
            for app_json in installed:
                model, loader = self._map_to_model(app_json=app_json, installed=True,
                                                   disk_loader=disk_loader, internet=internet_available)
                model.update = False
                models[model.get_update_id(version)] = model

                if loader and data_loaders is not None:
                    data_loaders.append(loader)

        if update_map:
            for update_id in update_map['full']:
                model_with_update = models.get(update_id)
                if model_with_update:
                    model_with_update.update = True
                else:
                    # it is a new component that must be installed
                    update_id_split = update_id.split('/')
                    new_app = FlatpakApplication(id=update_id_split[0],
                                                 branch=update_id_split[1],
                                                 installation=update_id_split[2],
                                                 name=update_id_split[0].split('.')[-1].strip(),
                                                 version=update_id_split[1],
                                                 arch='x86_64' if self.context.is_system_x86_64() else 'x86',
                                                 origin=update_id_split[3] if len(update_id_split) == 4 else None)
                    new_app.update_component = True  # mark as "update component"
                    new_app.installed = True  # faking the "installed" status to be displayed as an update
                    new_app.update = True
                    new_app.update_ref()
                    models[update_id] = new_app

            if version >= VERSION_1_2:
                for partial_update_id in update_map['partial']:
                    partial_data = partial_update_id.split('/')

                    for model in models.values():
                        if model.installation == partial_data[2] and model.branch == partial_data[1]:
                            if model.id == partial_data[0]:
                                model.update = True
                                break
                            elif model.id in partial_data[0]:
                                partial_model = model.gen_partial(partial_data[0])
                                partial_model.update = True
                                models[partial_update_id] = partial_model
                                break

        if thread_runtimes:
            thread_runtimes.join()

        if required_runtimes:
            for installation in ('system', 'user'):
                installation_runtimes = required_runtimes.get(installation)

                if installation_runtimes:
                    for ref, origin in installation_runtimes:
                        ref_split = ref.split('/')
                        models[f'{installation}.'] = FlatpakApplication(id=ref_split[1],
                                                                        ref=ref,
                                                                        origin=origin,
                                                                        name=ref_split[1],
                                                                        version=ref_split[-1],
                                                                        latest_version=ref_split[-1],
                                                                        runtime=True,
                                                                        installation=installation,
                                                                        installed=False,
                                                                        update_component=True,
                                                                        update=True)

        if models:
            ignored = self._read_ignored_updates()

            if ignored:
                for model in models.values():
                    if model.get_update_ignore_key() in ignored:
                        model.updates_ignored = True

        if data_loaders:
            for loader in data_loaders:
                loader.join()

        return SearchResult([*models.values()], None, len(models))