示例#1
0
    def install(self, pkg: AppImage, root_password: str,
                watcher: ProcessWatcher) -> bool:
        handler = ProcessHandler(watcher)

        out_dir = INSTALLATION_PATH + pkg.name.lower()
        counter = 0
        while True:
            if os.path.exists(out_dir):
                self.logger.info(
                    "Installation dir '{}' already exists. Generating a different one"
                    .format(out_dir))
                out_dir += '-{}'.format(counter)
                counter += 1
            else:
                break

        Path(out_dir).mkdir(parents=True, exist_ok=True)
        pkg.install_dir = out_dir

        if pkg.imported:

            downloaded, file_name = True, pkg.local_file_path.split('/')[-1]

            file_path = out_dir + '/' + file_name

            try:
                moved, output = handler.handle_simple(
                    SimpleProcess(['mv', pkg.local_file_path, file_path]))
            except:
                self.logger.error("Could not rename file '' as '{}'".format(
                    pkg.local_file_path, file_path))
                moved = False

            if not moved:
                watcher.show_message(
                    title=self.i18n['error'].capitalize(),
                    body=self.i18n['appimage.install.imported.rename_error'].
                    format(bold(pkg.local_file_path.split('/')[-1]),
                           bold(output)),
                    type_=MessageType.ERROR)
                return False

        else:
            appimage_url = pkg.url_download_latest_version if pkg.update else pkg.url_download
            file_name = appimage_url.split('/')[-1]
            pkg.version = pkg.latest_version
            pkg.url_download = appimage_url

            file_path = out_dir + '/' + file_name
            downloaded = self.file_downloader.download(
                file_url=pkg.url_download,
                watcher=watcher,
                output_path=file_path,
                cwd=str(Path.home()))

        if downloaded:
            watcher.change_substatus(
                self.i18n['appimage.install.permission'].format(
                    bold(file_name)))
            permission_given = handler.handle(
                SystemProcess(new_subprocess(['chmod', 'a+x', file_path])))

            if permission_given:

                watcher.change_substatus(
                    self.i18n['appimage.install.extract'].format(
                        bold(file_name)))

                try:
                    res, output = handler.handle_simple(
                        SimpleProcess([file_path, '--appimage-extract'],
                                      cwd=out_dir))

                    if 'Error: Failed to register AppImage in AppImageLauncherFS' in output:
                        watcher.show_message(
                            title=self.i18n['error'],
                            body=self.
                            i18n['appimage.install.appimagelauncher.error'].
                            format(appimgl=bold('AppImageLauncher'),
                                   app=bold(pkg.name)),
                            type_=MessageType.ERROR)
                        handler.handle(
                            SystemProcess(
                                new_subprocess(['rm', '-rf', out_dir])))
                        return False
                except:
                    watcher.show_message(title=self.i18n['error'],
                                         body=traceback.format_exc(),
                                         type_=MessageType.ERROR)
                    traceback.print_exc()
                    handler.handle(
                        SystemProcess(new_subprocess(['rm', '-rf', out_dir])))
                    return False

                watcher.change_substatus(
                    self.i18n['appimage.install.desktop_entry'])
                extracted_folder = '{}/{}'.format(out_dir, 'squashfs-root')

                if os.path.exists(extracted_folder):
                    desktop_entry = self._find_desktop_file(extracted_folder)

                    with open('{}/{}'.format(extracted_folder,
                                             desktop_entry)) as f:
                        de_content = f.read()

                    de_content = RE_DESKTOP_EXEC.sub(
                        'Exec={}\n'.format(file_path), de_content)

                    extracted_icon = self._find_icon_file(extracted_folder)

                    if extracted_icon:
                        icon_path = out_dir + '/logo.' + extracted_icon.split(
                            '.')[-1]
                        shutil.copy(
                            '{}/{}'.format(extracted_folder, extracted_icon),
                            icon_path)
                        de_content = RE_DESKTOP_ICON.sub(
                            'Icon={}\n'.format(icon_path), de_content)
                        pkg.icon_path = icon_path

                    Path(DESKTOP_ENTRIES_PATH).mkdir(parents=True,
                                                     exist_ok=True)

                    with open(self._gen_desktop_entry_path(pkg), 'w+') as f:
                        f.write(de_content)

                    shutil.rmtree(extracted_folder)
                    return True
                else:
                    watcher.show_message(
                        title=self.i18n['error'],
                        body='Could extract content from {}'.format(
                            bold(file_name)),
                        type_=MessageType.ERROR)
        else:
            watcher.show_message(
                title=self.i18n['error'],
                body=self.i18n['appimage.install.download.error'].format(
                    bold(pkg.url_download)),
                type_=MessageType.ERROR)

        handler.handle(SystemProcess(new_subprocess(['rm', '-rf', out_dir])))
        return False
示例#2
0
    def _install(self, pkg: AppImage, watcher: ProcessWatcher, pre_downloaded_file: Optional[Tuple[str, str]] = None) \
            -> TransactionResult:

        handler = ProcessHandler(watcher)
        out_dir = f'{INSTALLATION_DIR}/{pkg.get_clean_name()}'
        counter = 0
        while True:
            if os.path.exists(out_dir):
                self.logger.info(f"Installation dir '{out_dir}' already exists. Generating a different one")
                out_dir += f'-{counter}'
                counter += 1
            else:
                break

        Path(out_dir).mkdir(parents=True, exist_ok=True)
        pkg.install_dir = out_dir

        if pkg.imported:

            downloaded, file_name = True, pkg.local_file_path.split('/')[-1]

            install_file_path = out_dir + '/' + file_name

            try:
                moved, output = handler.handle_simple(SimpleProcess(['mv', pkg.local_file_path, install_file_path]))
            except:
                output = ''
                self.logger.error(f"Could not rename file '{pkg.local_file_path}' as '{install_file_path}'")
                moved = False

            if not moved:
                watcher.show_message(title=self.i18n['error'].capitalize(),
                                     body=self.i18n['appimage.install.imported.rename_error'].format(bold(pkg.local_file_path.split('/')[-1]),
                                                                                                     bold(output)),
                                     type_=MessageType.ERROR)

                return TransactionResult.fail()

        else:
            download_data = pre_downloaded_file if pre_downloaded_file else self._download(pkg, watcher)

            if not download_data:
                return TransactionResult.fail()

            file_name, download_path = download_data[0], download_data[1]

            install_file_path = f'{out_dir}/{file_name}'

            try:
                shutil.move(download_path, install_file_path)
            except OSError:
                watcher.show_message(title=self.i18n['error'],
                                     body=self.i18n['error.mvfile'].formmat(src=bold(download_path),
                                                                            dest=bold(install_file_path)))
                return TransactionResult.fail()

        watcher.change_substatus(self.i18n['appimage.install.permission'].format(bold(file_name)))
        permission_given = handler.handle(SystemProcess(new_subprocess(['chmod', 'a+x', install_file_path])))

        if permission_given:

            watcher.change_substatus(self.i18n['appimage.install.extract'].format(bold(file_name)))

            try:
                res, output = handler.handle_simple(
                    SimpleProcess([install_file_path, '--appimage-extract'], cwd=out_dir))

                if 'Error: Failed to register AppImage in AppImageLauncherFS' in output:
                    watcher.show_message(title=self.i18n['error'],
                                         body=self.i18n['appimage.install.appimagelauncher.error'].format(
                                             appimgl=bold('AppImageLauncher'), app=bold(pkg.name)),
                                         type_=MessageType.ERROR)
                    handler.handle(SystemProcess(new_subprocess(['rm', '-rf', out_dir])))
                    return TransactionResult.fail()
            except:
                watcher.show_message(title=self.i18n['error'],
                                     body=traceback.format_exc(),
                                     type_=MessageType.ERROR)
                traceback.print_exc()
                handler.handle(SystemProcess(new_subprocess(['rm', '-rf', out_dir])))
                return TransactionResult.fail()

            watcher.change_substatus(self.i18n['appimage.install.desktop_entry'])
            extracted_folder = f'{out_dir}/squashfs-root'

            if os.path.exists(extracted_folder):
                desktop_entry = self._find_desktop_file(extracted_folder)

                with open(f'{extracted_folder}/{desktop_entry}') as f:
                    de_content = f.read()

                if de_content:
                    de_content = replace_desktop_entry_exec_command(desktop_entry=de_content,
                                                                    appname=pkg.name,
                                                                    file_path=install_file_path)
                extracted_icon = self._find_icon_file(extracted_folder)

                if extracted_icon:
                    icon_path = out_dir + '/logo.' + extracted_icon.split('/')[-1].split('.')[-1]
                    shutil.copy(extracted_icon, icon_path)

                    if de_content:
                        de_content = RE_DESKTOP_ICON.sub(f'Icon={icon_path}\n', de_content)

                    pkg.icon_path = icon_path

                if not de_content:
                    de_content = pkg.to_desktop_entry()

                Path(DESKTOP_ENTRIES_DIR).mkdir(parents=True, exist_ok=True)

                with open(self._gen_desktop_entry_path(pkg), 'w+') as f:
                    f.write(de_content)

                try:
                    shutil.rmtree(extracted_folder)
                except:
                    traceback.print_exc()

                SymlinksVerifier.create_symlink(app=pkg, file_path=install_file_path, logger=self.logger,
                                                watcher=watcher)
                return TransactionResult(success=True, installed=[pkg], removed=[])
            else:
                watcher.show_message(title=self.i18n['error'],
                                     body=f'Could extract content from {bold(file_name)}',
                                     type_=MessageType.ERROR)

        handler.handle(SystemProcess(new_subprocess(['rm', '-rf', out_dir])))
        return TransactionResult.fail()