Example #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,
                       connection: sqlite3.Connection = None) -> SearchResult:
        res = SearchResult([], [], 0)

        if os.path.exists(INSTALLATION_PATH):
            installed = run_cmd('ls {}*/data.json'.format(INSTALLATION_PATH),
                                print_error=False)

            if installed:
                names = set()
                for path in installed.split('\n'):
                    if path:
                        with open(path) as f:
                            app = AppImage(installed=True,
                                           **json.loads(f.read()))
                            app.icon_url = app.icon_path

                        res.installed.append(app)
                        names.add("'{}'".format(app.name.lower()))

                if res.installed:
                    con = self._get_db_connection(
                        DB_APPS_PATH) if not connection else connection

                    if con:
                        try:
                            cursor = con.cursor()
                            cursor.execute(
                                query.FIND_APPS_BY_NAME.format(
                                    ','.join(names)))

                            for tup in cursor.fetchall():
                                for app in res.installed:
                                    if app.name.lower() == tup[0].lower() and (
                                            not app.github
                                            or app.github.lower()
                                            == tup[1].lower()):
                                        app.update = tup[2] > app.version

                                        if app.update:
                                            app.latest_version = tup[2]
                                            app.url_download_latest_version = tup[
                                                3]

                                        break
                        except:
                            traceback.print_exc()
                        finally:
                            if not connection:
                                self._close_connection(DB_APPS_PATH, con)

        res.total = len(res.installed)
        return res
Example #2
0
    def install_file(self, root_password: Optional[str], watcher: ProcessWatcher) -> bool:
        max_width = 350
        file_chooser = FileChooserComponent(label=self.i18n['file'].capitalize(),
                                            allowed_extensions={'AppImage', '*'},
                                            search_path=get_default_manual_installation_file_dir(),
                                            max_width=max_width)
        input_name = TextInputComponent(label=self.i18n['name'].capitalize(), max_width=max_width)
        input_version = TextInputComponent(label=self.i18n['version'].capitalize(), max_width=max_width)
        file_chooser.observers.append(ManualInstallationFileObserver(input_name, input_version))

        input_description = TextInputComponent(label=self.i18n['description'].capitalize(), max_width=max_width)

        cat_ops = [InputOption(label=self.i18n['category.none'].capitalize(), value=0)]
        cat_ops.extend([InputOption(label=self.i18n.get(f'category.{c.lower()}', c.lower()).capitalize(), value=c) for c in self.context.default_categories])
        inp_cat = SingleSelectComponent(label=self.i18n['category'], type_=SelectViewType.COMBO, options=cat_ops,
                                        default_option=cat_ops[0], max_width=max_width)

        form = FormComponent(label='', components=[file_chooser, input_name, input_version, input_description, inp_cat],
                             spaces=False)

        while True:
            if watcher.request_confirmation(title=self.i18n['appimage.custom_action.install_file.details'], body=None,
                                            components=[form],
                                            confirmation_label=self.i18n['proceed'].capitalize(),
                                            deny_label=self.i18n['cancel'].capitalize(),
                                            min_height=100, max_width=max_width + 150):
                if not file_chooser.file_path or not os.path.isfile(file_chooser.file_path) or not file_chooser.file_path.lower().strip().endswith('.appimage'):
                    watcher.request_confirmation(title=self.i18n['error'].capitalize(),
                                                 body=self.i18n['appimage.custom_action.install_file.invalid_file'],
                                                 deny_button=False)
                elif not input_name.get_value() or not input_name.get_value().strip():
                    watcher.request_confirmation(title=self.i18n['error'].capitalize(),
                                                 body=self.i18n['appimage.custom_action.install_file.invalid_name'],
                                                 deny_button=False)
                else:
                    break
            else:
                return False

        appim = AppImage(i18n=self.i18n, imported=True)
        appim.name = input_name.get_value().strip()
        appim.local_file_path = file_chooser.file_path
        appim.version = input_version.get_value()
        appim.latest_version = input_version.get_value()
        appim.description = input_description.get_value()
        appim.categories = ['Imported']

        if inp_cat.get_selected() != cat_ops[0].value:
            appim.categories.append(inp_cat.get_selected())

        res = self.install(root_password=root_password, pkg=appim, disk_loader=None, watcher=watcher).success

        if res:
            appim.installed = True
            self.cache_to_disk(appim, None, False)

        return res
Example #3
0
    def _add_self_latest_version(self, app: AppImage):
        if app.name == self.context.app_name and app.github == self.app_github and not app.url_download_latest_version:
            history = self.get_history(app)

            if not history or not history.history:
                self.logger.warning(f"Could not retrieve '{app.name}' versions. "
                                    f"It will not be possible to determine the current latest version")
            else:
                app.version = history.history[0]['0_version']
                app.latest_version = app.version
                app.url_download = history.history[0]['2_url_download']
                app.url_download_latest_version = app.url_download
Example #4
0
    def downgrade(self, pkg: AppImage, root_password: str,
                  watcher: ProcessWatcher) -> bool:
        versions = self.get_history(pkg)

        if len(versions.history) == 1:
            watcher.show_message(
                title=self.i18n['appimage.downgrade.impossible.title'],
                body=self.i18n['appimage.downgrade.impossible.body'].format(
                    bold(pkg.name)),
                type_=MessageType.ERROR)
            return False
        elif versions.pkg_status_idx == -1:
            watcher.show_message(
                title=self.i18n['appimage.downgrade.impossible.title'],
                body=self.i18n['appimage.downgrade.unknown_version.body'].
                format(bold(pkg.name)),
                type_=MessageType.ERROR)
            return False
        elif versions.pkg_status_idx == len(versions.history) - 1:
            watcher.show_message(
                title=self.i18n['appimage.downgrade.impossible.title'],
                body=self.i18n['appimage.downgrade.first_version'].format(
                    bold(pkg.name)),
                type_=MessageType.ERROR)
            return False
        else:
            if self.uninstall(pkg, root_password, watcher):
                old_release = versions.history[versions.pkg_status_idx + 1]
                pkg.version = old_release['0_version']
                pkg.latest_version = pkg.version
                pkg.url_download = old_release['2_url_download']
                if self.install(pkg, root_password, watcher):
                    self.cache_to_disk(pkg, None, False)
                    return True
                else:
                    watcher.show_message(
                        title=self.i18n['error'],
                        body=self.i18n['appimage.downgrade.install_version'].
                        format(bold(pkg.version), bold(pkg.url_download)),
                        type_=MessageType.ERROR)
            else:
                watcher.show_message(
                    title=self.i18n['error'],
                    body=self.i18n['appimage.error.uninstall_current_version'].
                    format(bold(pkg.name)),
                    type_=MessageType.ERROR)

            return False
Example #5
0
    def install_file(self, root_password: str,
                     watcher: ProcessWatcher) -> bool:
        file_chooser = FileChooserComponent(
            label=self.i18n['file'].capitalize(),
            allowed_extensions={'AppImage'})
        input_name = TextInputComponent(label=self.i18n['name'].capitalize())
        input_version = TextInputComponent(
            label=self.i18n['version'].capitalize())
        input_description = TextInputComponent(
            label=self.i18n['description'].capitalize())

        cat_ops = [
            InputOption(label=self.i18n['category.none'].capitalize(), value=0)
        ]
        cat_ops.extend([
            InputOption(label=self.i18n[c.lower()].capitalize(), value=c)
            for c in self.context.default_categories
        ])
        inp_cat = SingleSelectComponent(label=self.i18n['category'],
                                        type_=SelectViewType.COMBO,
                                        options=cat_ops,
                                        default_option=cat_ops[0])

        form = FormComponent(label='',
                             components=[
                                 file_chooser, input_name, input_version,
                                 input_description, inp_cat
                             ],
                             spaces=False)

        while True:
            if watcher.request_confirmation(
                    title=self.
                    i18n['appimage.custom_action.install_file.details'],
                    body=None,
                    components=[form],
                    confirmation_label=self.i18n['proceed'].capitalize(),
                    deny_label=self.i18n['cancel'].capitalize()):
                if not file_chooser.file_path or not os.path.isfile(
                        file_chooser.file_path):
                    watcher.request_confirmation(
                        title=self.i18n['error'].capitalize(),
                        body=self.i18n[
                            'appimage.custom_action.install_file.invalid_file'],
                        deny_button=False)
                elif not input_name.get_value() or not input_name.get_value(
                ).strip():
                    watcher.request_confirmation(
                        title=self.i18n['error'].capitalize(),
                        body=self.i18n[
                            'appimage.custom_action.install_file.invalid_name'],
                        deny_button=False)
                else:
                    break
            else:
                return False

        appim = AppImage(i18n=self.i18n,
                         imported=True,
                         custom_actions=self.custom_app_actions)
        appim.name = input_name.get_value().strip()
        appim.local_file_path = file_chooser.file_path
        appim.version = input_version.get_value()
        appim.latest_version = input_version.get_value()
        appim.description = input_description.get_value()
        appim.categories = ['Imported']

        if inp_cat.get_selected() != cat_ops[0].value:
            appim.categories.append(inp_cat.get_selected())

        installed = self.install(root_password=root_password,
                                 pkg=appim,
                                 watcher=watcher)

        if installed:
            appim.installed = True
            self.cache_to_disk(appim, None, False)

        return installed
Example #6
0
    def read_installed(self, disk_loader: Optional[DiskCacheLoader], limit: int = -1, only_apps: bool = False,
                       pkg_types: Optional[Set[Type[SoftwarePackage]]] = None, internet_available: bool = None, connection: sqlite3.Connection = None) -> SearchResult:
        installed_apps = []
        res = SearchResult(installed_apps, [], 0)

        if os.path.exists(INSTALLATION_DIR):
            installed = glob.glob(f'{INSTALLATION_DIR}/*/data.json')

            if installed:
                names = set()
                for path in installed:
                    if path:
                        with open(path) as f:
                            app = AppImage(installed=True, i18n=self.i18n, **json.loads(f.read()))
                            app.icon_url = app.icon_path

                        installed_apps.append(app)
                        names.add(f"'{app.name.lower()}'")

                if installed_apps:
                    apps_con = self._get_db_connection(DATABASE_APPS_FILE) if not connection else connection

                    if apps_con:
                        try:
                            cursor = apps_con.cursor()
                            cursor.execute(query.FIND_APPS_BY_NAME.format(','.join(names)))

                            for tup in cursor.fetchall():
                                for app in installed_apps:
                                    if app.name.lower() == tup[0].lower() and (not app.github or app.github.lower() == tup[1].lower()):
                                        continuous_version = app.version == 'continuous'
                                        continuous_update = tup[2] == 'continuous'

                                        if tup[3]:
                                            if continuous_version and not continuous_update:
                                                app.update = True
                                            elif continuous_update and not continuous_version:
                                                app.update = False
                                            else:
                                                try:
                                                    app.update = parse_version(tup[2]) > parse_version(app.version) if tup[2] else False
                                                except:
                                                    app.update = False
                                                    traceback.print_exc()

                                        if app.update:
                                            app.latest_version = tup[2]
                                            app.url_download_latest_version = tup[3]

                                        break
                        except:
                            self.logger.error(f"An exception happened while querying the database file '{DATABASE_APPS_FILE}'")
                            traceback.print_exc()
                        finally:
                            if not connection:  # the connection can only be closed if it was opened within this method
                                apps_con.close()

                    ignored_updates = self._read_ignored_updates()

                    if ignored_updates:
                        for app in installed_apps:
                            if app.supports_ignored_updates() and app.name in ignored_updates:
                                app.updates_ignored = True

        res.total = len(res.installed)
        return res