Exemple #1
0
    def confirm_transaction(self,
                            to_install: Optional[Collection[DebianPackage]],
                            removal: Optional[Collection[DebianPackage]],
                            watcher: ProcessWatcher) -> bool:

        components = []

        to_remove_data = self._map_to_remove(removal)

        text_width, select_width = 672, 595

        if to_remove_data:
            to_remove_data[0].sort(key=attrgetter('label'))
            lb_rem = self._i18n['debian.transaction.to_remove'].format(
                no=bold(str(len(to_remove_data[0]))),
                fspace=bold(to_remove_data[1]))

            components.append(TextComponent(html=lb_rem, min_width=text_width))
            components.append(
                MultipleSelectComponent(id_='rem',
                                        options=to_remove_data[0],
                                        label=None,
                                        default_options={*to_remove_data[0]},
                                        max_width=select_width))

        to_install_data = self._map_to_install(to_install)

        if to_install_data:
            to_install_data[0].sort(key=attrgetter('label'))
            lb_deps = self._i18n['debian.transaction.to_install'].format(
                no=bold(str(len(to_install_data[0]))),
                dsize=bold(to_install_data[2]),
                isize=bold(to_install_data[1]))

            components.append(
                TextComponent(html=f'<br/>{lb_deps}', min_width=text_width))
            components.append(
                MultipleSelectComponent(id_='inst',
                                        label='',
                                        options=to_install_data[0],
                                        default_options={*to_install_data[0]},
                                        max_width=select_width))

        return watcher.request_confirmation(
            title=self._i18n['debian.transaction.title'],
            components=components,
            confirmation_label=self._i18n['popup.button.continue'],
            deny_label=self._i18n['popup.button.cancel'],
            body=None,
            min_width=text_width,
            min_height=54)
Exemple #2
0
    def get_settings(self, screen_width: int, screen_height: int) -> ViewComponent:
        tabs = list()

        gem_opts, def_gem_opts, gem_tabs = [], set(), []

        for man in self.managers:
            if man.can_work():
                man_comp = man.get_settings(screen_width, screen_height)
                modname = man.__module__.split('.')[-2]
                icon_path = "{r}/gems/{n}/resources/img/{n}.svg".format(r=ROOT_DIR, n=modname)

                if man_comp:
                    tab_name = self.i18n.get('gem.{}.label'.format(modname), modname.capitalize())
                    gem_tabs.append(TabComponent(label=tab_name, content=man_comp, icon_path=icon_path, id_=modname))

                opt = InputOption(label=self.i18n.get('gem.{}.label'.format(modname), modname.capitalize()),
                                  tooltip=self.i18n.get('gem.{}.info'.format(modname)),
                                  value=modname,
                                  icon_path='{r}/gems/{n}/resources/img/{n}.svg'.format(r=ROOT_DIR, n=modname))
                gem_opts.append(opt)

                if man.is_enabled() and man in self.working_managers:
                    def_gem_opts.add(opt)

        core_config = read_config()

        if gem_opts:
            type_help = TextComponent(html=self.i18n['core.config.types.tip'])
            gem_opts.sort(key=lambda o: o.value)
            gem_selector = MultipleSelectComponent(label=None,
                                                   tooltip=None,
                                                   options=gem_opts,
                                                   max_width=floor(screen_width * 0.22),
                                                   default_options=def_gem_opts,
                                                   id_="gems")
            tabs.append(TabComponent(label=self.i18n['core.config.tab.types'],
                                     content=PanelComponent([type_help, FormComponent([gem_selector], spaces=False)]),
                                     id_='core.types'))

        tabs.append(self._gen_general_settings(core_config, screen_width, screen_height))
        tabs.append(self._gen_ui_settings(core_config, screen_width, screen_height))
        tabs.append(self._gen_tray_settings(core_config, screen_width, screen_height))
        tabs.append(self._gen_adv_settings(core_config, screen_width, screen_height))

        bkp_settings = self._gen_backup_settings(core_config, screen_width, screen_height)

        if bkp_settings:
            tabs.append(bkp_settings)

        for tab in gem_tabs:
            tabs.append(tab)

        return TabGroupComponent(tabs)
Exemple #3
0
    def confirm_removal(self, source_pkg: str,
                        dependencies: Collection[DebianPackage],
                        watcher: ProcessWatcher) -> bool:
        dep_views = []
        freed_space = 0
        for p in sorted(dependencies, key=attrgetter('name')):
            if p.transaction_size is not None:
                size = p.transaction_size * (-1
                                             if p.transaction_size < 0 else 1)
                freed_space += size
                size_str = get_human_size_str(size)
            else:
                size_str = '?'

            dep_views.append(
                InputOption(label=f"{p.name}: -{size_str}",
                            value=p.name,
                            read_only=True,
                            icon_path=DEBIAN_ICON_PATH,
                            tooltip=p.description))

        deps_container = MultipleSelectComponent(id_='deps',
                                                 label='',
                                                 options=dep_views,
                                                 default_options={*dep_views},
                                                 max_width=537)

        freed_space_str = bold('-' + get_human_size_str(freed_space))
        body_text = TextComponent(html=self._i18n['debian.remove_deps'].format(
            no=bold(str(len(dependencies))),
            pkg=bold(source_pkg),
            fspace=freed_space_str),
                                  min_width=653)

        return watcher.request_confirmation(
            title=self._i18n['debian.transaction.title'],
            components=[body_text, deps_container],
            confirmation_label=self._i18n['popup.button.continue'],
            deny_label=self._i18n['popup.button.cancel'],
            min_height=200,
            body=None)
Exemple #4
0
    def run(self):
        if not self.internet_checker.is_available():
            return self._handle_internet_off()

        root_user = user.is_root()
        to_update, upgrade_requires_root, bkp_supported = [], False, False

        for pkg in self.pkgs:
            if pkg.model.update and not pkg.model.is_update_ignored() and pkg.update_checked:
                to_update.append(pkg)

                if not bkp_supported and pkg.model.supports_backup():
                    bkp_supported = True

                if not root_user and not upgrade_requires_root and self.manager.requires_root(SoftwareAction.UPGRADE, pkg.model):
                    upgrade_requires_root = True

        if upgrade_requires_root:
            valid_password, root_password = self._request_password()
        else:
            valid_password, root_password = True, None

        if not valid_password:
            self.notify_finished({'success': False, 'updated': 0, 'types': set(), 'id': None})
            self.pkgs = None
            return

        if len(to_update) > 1:
            self.disable_progress_controll()
        else:
            self.enable_progress_controll()

        success = False

        updated, updated_types = 0, set()

        models = [view.model for view in to_update]

        self.change_substatus(self.i18n['action.update.requirements.status'])
        requirements = self.manager.get_upgrade_requirements(models, root_password, self)

        if not requirements:
            self.pkgs = None
            self.notify_finished({'success': success, 'updated': updated, 'types': updated_types, 'id': None})
            return

        comps, required_size, extra_size = [], 0, 0

        if requirements.cannot_upgrade:
            comps.append(self._gen_cannot_upgrade_form(requirements.cannot_upgrade))

        if requirements.to_install:
            req_form, reqs_size = self._gen_to_install_form(requirements.to_install)
            required_size += reqs_size[0]
            extra_size += reqs_size[1]
            comps.append(req_form)

        if requirements.to_remove:
            comps.append(self._gen_to_remove_form(requirements.to_remove))

        can_upgrade = False
        if requirements.to_upgrade:
            can_upgrade = True
            updates_form, updates_size = self._gen_to_update_form(requirements.to_upgrade)
            required_size += updates_size[0]
            extra_size += updates_size[1]
            comps.append(updates_form)

        disc_size_text = f"{self.i18n['action.update.total_storage_size']}: {get_human_size_str(extra_size, True)}"
        download_size_text = f"{self.i18n['action.update.download_size']}: {get_human_size_str(required_size)}"

        comps.insert(0, TextComponent(f'{disc_size_text} ({download_size_text})', size=14))
        comps.insert(1, TextComponent(''))

        if not self.request_confirmation(title=self.i18n['action.update.summary'].capitalize(), body='', components=comps,
                                         confirmation_label=self.i18n['proceed'].capitalize(), deny_label=self.i18n['cancel'].capitalize(),
                                         confirmation_button=can_upgrade, min_width=int(0.45 * self.screen_width)):
            self.notify_finished({'success': success, 'updated': updated, 'types': updated_types, 'id': None})
            self.pkgs = None
            return

        if not self.internet_checker.is_available():
            return self._handle_internet_off()

        self.change_substatus('')

        app_config = CoreConfigManager().get_config()

        # backup dialog ( if enabled, supported and accepted )
        should_backup = bkp_supported
        should_backup = should_backup and self._check_backup_requirements(app_config=app_config, pkg=None, action_key='upgrade')
        should_backup = should_backup and self._should_backup(action_key='upgrade', app_config=app_config)

        # trim dialog ( if enabled and accepted )
        if app_config['disk']['trim']['after_upgrade'] is not False:
            should_trim = app_config['disk']['trim']['after_upgrade'] or self._ask_for_trim()
        else:
            should_trim = False

        if should_trim and not root_user and root_password is None:  # trim requires root and the password might have not being asked yet
            valid_password, root_password = self._request_password()

            if not valid_password:
                self.notify_finished({'success': False, 'updated': 0, 'types': set(), 'id': None})
                self.pkgs = None
                return

        # performing backup
        if should_backup:
            proceed, root_password = self.request_backup(action_key='upgrade',
                                                         app_config=app_config,
                                                         root_password=root_password,
                                                         pkg=None,
                                                         backup_only=True)
            if not proceed:
                self.notify_finished({'success': False, 'updated': 0, 'types': set(), 'id': None})
                self.pkgs = None
                return

        self.change_substatus('')

        timestamp = datetime.now()
        upgrade_id = 'upgrade_{}{}{}_{}'.format(timestamp.year, timestamp.month, timestamp.day, int(time.time()))

        self._write_summary_log(upgrade_id, requirements)

        success = bool(self.manager.upgrade(requirements, root_password, self))
        self.change_substatus('')

        if success:
            if requirements.to_upgrade:
                updated = len(requirements.to_upgrade)
                updated_types.update((req.pkg.__class__ for req in requirements.to_upgrade))

            if should_trim:
                self._trim_disk(root_password)

            if bool(app_config['updates']['ask_for_reboot']):
                msg = '<p>{}</p>{}</p><br/><p>{}</p>'.format(self.i18n['action.update.success.reboot.line1'],
                                                             self.i18n['action.update.success.reboot.line2'],
                                                             self.i18n['action.update.success.reboot.line3'])
                self.request_reboot(msg)

        self.notify_finished({'success': success, 'updated': updated, 'types': updated_types, 'id': upgrade_id})
        self.pkgs = None
Exemple #5
0
    def run(self):
        valid_password, root_password = self._request_password()

        if not valid_password:
            self.notify_finished({
                'success': False,
                'updated': 0,
                'types': set(),
                'id': None
            })
            self.pkgs = None
            return

        to_update = [
            pkg for pkg in self.pkgs if pkg.model.update
            and not pkg.model.is_update_ignored() and pkg.update_checked
        ]

        if len(to_update) > 1:
            self.disable_progress_controll()
        else:
            self.enable_progress_controll()

        success = False

        updated, updated_types = 0, set()

        models = [view.model for view in to_update]

        self.change_substatus(self.i18n['action.update.requirements.status'])
        requirements = self.manager.get_upgrade_requirements(
            models, root_password, self)

        if not requirements:
            self.pkgs = None
            self.notify_finished({
                'success': success,
                'updated': updated,
                'types': updated_types,
                'id': None
            })
            return

        comps, required_size, extra_size = [], 0, 0

        if requirements.cannot_upgrade:
            comps.append(
                self._gen_cannot_update_form(requirements.cannot_upgrade))

        if requirements.to_install:
            req_form, reqs_size = self._gen_to_install_form(
                requirements.to_install)
            required_size += reqs_size[0]
            extra_size += reqs_size[1]
            comps.append(req_form)

        if requirements.to_remove:
            comps.append(self._gen_to_remove_form(requirements.to_remove))

        updates_form, updates_size = self._gen_to_update_form(
            requirements.to_upgrade)
        required_size += updates_size[0]
        extra_size += updates_size[1]
        comps.append(updates_form)

        extra_size_text = '{}: {}'.format(
            self.i18n['action.update.total_size'].capitalize(),
            get_human_size_str(extra_size))
        req_size_text = '{}: {}'.format(
            self.i18n['action.update.required_size'].capitalize(),
            get_human_size_str(required_size))
        comps.insert(
            0,
            TextComponent('{}  |  {}'.format(extra_size_text, req_size_text),
                          size=14))
        comps.insert(1, TextComponent(''))

        if not self.request_confirmation(
                title=self.i18n['action.update.summary'].capitalize(),
                body='',
                components=comps,
                confirmation_label=self.i18n['proceed'].capitalize(),
                deny_label=self.i18n['cancel'].capitalize()):
            self.notify_finished({
                'success': success,
                'updated': updated,
                'types': updated_types,
                'id': None
            })
            self.pkgs = None
            return

        self.change_substatus('')

        app_config = read_config()

        # trim dialog
        if app_config['disk']['trim']['after_upgrade'] is not False:
            should_trim = app_config['disk']['trim'][
                'after_upgrade'] or self._ask_for_trim()
        else:
            should_trim = False

        # backup process ( if enabled, supported and accepted )
        if bool(app_config['backup']
                ['enabled']) and app_config['backup']['upgrade'] in (
                    True, None) and timeshift.is_available():
            any_requires_bkp = False

            for dep in requirements.to_upgrade:
                if dep.pkg.supports_backup():
                    any_requires_bkp = True
                    break

            if any_requires_bkp:
                if not self.request_backup(app_config, 'upgrade', self.i18n,
                                           root_password):
                    self.notify_finished({
                        'success': success,
                        'updated': updated,
                        'types': updated_types,
                        'id': None
                    })
                    self.pkgs = None
                    return

        self.change_substatus('')

        timestamp = datetime.now()
        upgrade_id = 'upgrade_{}{}{}_{}'.format(timestamp.year,
                                                timestamp.month, timestamp.day,
                                                int(time.time()))

        self._write_summary_log(upgrade_id, requirements)

        success = bool(self.manager.upgrade(requirements, root_password, self))
        self.change_substatus('')

        if success:
            updated = len(requirements.to_upgrade)
            updated_types.update(
                (req.pkg.__class__ for req in requirements.to_upgrade))

            if should_trim:
                self._trim_disk(root_password)

            if bool(app_config['updates']['ask_for_reboot']):
                msg = '<p>{}</p>{}</p><br/><p>{}</p>'.format(
                    self.i18n['action.update.success.reboot.line1'],
                    self.i18n['action.update.success.reboot.line2'],
                    self.i18n['action.update.success.reboot.line3'])
                self.request_reboot(msg)

        self.notify_finished({
            'success': success,
            'updated': updated,
            'types': updated_types,
            'id': upgrade_id
        })
        self.pkgs = None
Exemple #6
0
    def get_settings(self) -> TabGroupComponent:
        tabs = list()

        gem_opts, def_gem_opts, gem_tabs = [], set(), []

        self._settings_views = dict()

        for man in self.managers:
            can_work, reason_not_work = man.can_work()
            modname = man.__module__.split('.')[-2]

            man_settings = man.get_settings() if can_work else None
            if man_settings:
                for view in man_settings:
                    icon_path = view.icon_path

                    if not icon_path:
                        icon_path = f"{ROOT_DIR}/gems/{modname}/resources/img/{modname}.svg"

                    tab_name = view.label if view.label else self.i18n.get(
                        f'gem.{modname}.label', modname.capitalize())
                    gem_tabs.append(
                        TabComponent(label=tab_name,
                                     content=view.component,
                                     icon_path=icon_path))

                    views = self._settings_views.get(man.__class__, list())
                    self._settings_views[man.__class__] = views
                    views.append(view)

            help_tip = reason_not_work if not can_work and reason_not_work else self.i18n.get(
                f'gem.{modname}.info')
            opt = InputOption(
                label=self.i18n.get(f'gem.{modname}.label',
                                    modname.capitalize()),
                tooltip=help_tip,
                value=modname,
                icon_path=
                f'{ROOT_DIR}/gems/{modname}/resources/img/{modname}.svg',
                read_only=not can_work,
                extra_properties={'warning': 'true'} if not can_work else None)
            gem_opts.append(opt)

            if man.is_enabled() and man in self.working_managers:
                def_gem_opts.add(opt)

        core_config = self.configman.get_config()

        if gem_opts:
            type_help = TextComponent(html=self.i18n['core.config.types.tip'])
            gem_opts.sort(key=lambda o: o.value)
            gem_selector = MultipleSelectComponent(
                label=None,
                tooltip=None,
                options=gem_opts,
                max_width=floor(self.context.screen_width * 0.22),
                default_options=def_gem_opts,
                id_="gems")
            tabs.append(
                TabComponent(label=self.i18n['core.config.tab.types'],
                             content=PanelComponent([
                                 type_help,
                                 FormComponent([gem_selector], spaces=False)
                             ]),
                             id_='core.types'))

        tabs.append(self._gen_general_settings(core_config))
        tabs.append(self._gen_interface_settings(core_config))
        tabs.append(self._gen_tray_settings(core_config))
        tabs.append(self._gen_adv_settings(core_config))

        bkp_settings = self._gen_backup_settings(core_config)

        if bkp_settings:
            tabs.append(bkp_settings)

        for tab in gem_tabs:
            tabs.append(tab)

        return TabGroupComponent(tabs)