diff --git a/core/controller.py b/core/controller.py index cf78c298..fe028d80 100755 --- a/core/controller.py +++ b/core/controller.py @@ -12,7 +12,7 @@ class FlatpakController: return self.model.read_installed() def update(self, package_refs: List[str]) -> List[dict]: - return self.model.update_packages(package_refs) + return self.model.update_apps(package_refs) def check_installed(self) -> bool: version = self.model.get_version() diff --git a/core/flatpak.py b/core/flatpak.py index d50acbea..89b4a6f5 100755 --- a/core/flatpak.py +++ b/core/flatpak.py @@ -3,7 +3,7 @@ import subprocess from typing import List -def _package_str_to_json(line: str, version: str) -> dict: +def app_str_to_json(line: str, version: str) -> dict: app_array = line.split('\t') @@ -24,7 +24,7 @@ def _package_str_to_json(line: str, version: str) -> dict: else: raise Exception('Unsupported version') - info = re.findall('\w+:\s.+', get_info(app['id'])) + info = re.findall('\w+:\s.+', get_app_info(app['id'])) fields_to_get = ['origin', 'arch', 'ref'] for field in info: @@ -50,29 +50,24 @@ def get_version(): return res.split(' ')[1].strip() if res else None -def get_info(app_id: str): +def get_app_info(app_id: str): return _run_cmd('flatpak info ' + app_id) -def list_installed() -> List[str]: +def list_installed() -> List[dict]: apps_str = _run_cmd('flatpak list') if apps_str: version = get_version() app_lines = apps_str.split('\n') - return [_package_str_to_json(line, version) for line in app_lines if line] + return [app_str_to_json(line, version) for line in app_lines if line] return None -def check_update(pak_id: dict) -> bool: - res = _run_cmd('flatpak update ' + pak_id) - return 'Updating in system' in res - - def update(ref: str): return bool(_run_cmd('flatpak update -y ' + ref)) -def list_updates(): +def list_updates_as_str(): return _run_cmd('flatpak update', ignore_return_code=True) diff --git a/core/model.py b/core/model.py index 71747001..505ba6f9 100755 --- a/core/model.py +++ b/core/model.py @@ -14,8 +14,8 @@ __FLATHUB_API_URL__ = __FLATHUB_URL__ + '/api/v1' class FlatpakManager: def __init__(self): - self.packages = [] - self.packages_db = {} + self.apps = [] + self.apps_db = {} self.http_session = requests.Session() self._load_database() @@ -25,48 +25,48 @@ class FlatpakManager: if res.status_code == 200: for app in res.json(): - self.packages_db[app['flatpakAppId']] = app + self.apps_db[app['flatpakAppId']] = app def get_version(self): return flatpak.get_version() def read_installed(self) -> List[dict]: - packages = flatpak.list_installed() + installed = flatpak.list_installed() - if packages: - packages.sort(key=lambda p: p['name'].lower()) + if installed: + installed.sort(key=lambda p: p['name'].lower()) - available_updates = flatpak.list_updates() + available_updates = flatpak.list_updates_as_str() - for pak in packages: + for app in installed: - if self.packages_db: - pak_data = self.packages_db.get(pak['id'], None) + if self.apps_db: + app_data = self.apps_db.get(app['id'], None) else: - pak_data = None + app_data = None - if not pak_data: - pak['latest_version'] = None - pak['icon'] = None + if not app_data: + app['latest_version'] = None + app['icon'] = None else: - pak['latest_version'] = pak_data['currentReleaseVersion'] - pak['icon'] = pak_data['iconDesktopUrl'] + app['latest_version'] = app_data['currentReleaseVersion'] + app['icon'] = app_data['iconMobileUrl'] - if pak['icon'].startswith('/'): - pak['icon'] = __FLATHUB_URL__ + pak['icon'] + if app['icon'].startswith('/'): + app['icon'] = __FLATHUB_URL__ + app['icon'] - pak['update'] = pak['id'] in available_updates + app['update'] = app['id'] in available_updates - self.packages = packages - return [*self.packages] + self.apps = installed + return [*self.apps] - def update_packages(self, refs: List[str]) -> List[dict]: + def update_apps(self, refs: List[str]) -> List[dict]: - if self.packages: + if self.apps: for ref in refs: - package_found = [pak for pak in self.packages if pak['ref'] == ref] + package_found = [app for app in self.apps if app['ref'] == ref] if package_found: package_found = package_found[0] @@ -75,6 +75,6 @@ class FlatpakManager: if updated: package_found['update'] = not updated - return [*self.packages] + return [*self.apps] return [] diff --git a/core/updater.py b/core/updater.py deleted file mode 100755 index e6736b52..00000000 --- a/core/updater.py +++ /dev/null @@ -1,16 +0,0 @@ -from model import flatpak - - -def list_packages(): - packages = flatpak.list_installed() - - if packages: - packages = [pak for pak in packages if not pak['runtime']] - - if packages: - packages.sort(key=lambda p: p['name'].lower()) - - for pak in packages: - pak['update'] = flatpak.check_update(pak['ref']) - - return packages diff --git a/resources/img/flathub_25.svg b/resources/img/flathub_25.svg new file mode 100644 index 00000000..15e46ff5 --- /dev/null +++ b/resources/img/flathub_25.svg @@ -0,0 +1,179 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/img/flathub_logo.svg b/resources/img/flathub_45.svg similarity index 100% rename from resources/img/flathub_logo.svg rename to resources/img/flathub_45.svg diff --git a/view/qt/systray.py b/view/qt/systray.py index 739b6bbf..8c438d51 100755 --- a/view/qt/systray.py +++ b/view/qt/systray.py @@ -1,4 +1,3 @@ -import sys import time from PyQt5.QtCore import QThread, pyqtSignal, QCoreApplication @@ -38,24 +37,25 @@ class UpdateCheck(QThread): class TrayIcon(QSystemTrayIcon): def __init__(self, controller: FlatpakController, check_interval: int = 60, parent=None): - self.icon_default = QIcon(resource.get_path('img/flathub_logo.svg')) + self.controller = controller + + self.icon_default = QIcon(resource.get_path('img/flathub_45.svg')) self.icon_update = QIcon(resource.get_path('img/update_logo.svg')) QSystemTrayIcon.__init__(self, self.icon_default, parent) - self.menu = QMenu(parent) + self.menu = QMenu(parent) self.action_manage = self.menu.addAction("Manage applications") self.action_manage.triggered.connect(self.show_manage_window) - self.action_exit = self.menu.addAction("Exit") self.action_exit.triggered.connect(lambda: QCoreApplication.exit()) self.setContextMenu(self.menu) - self.controller = controller - self.check_thread = UpdateCheck(check_interval=check_interval, controller=self.controller) - self.check_thread.signal.connect(self.notify_update) - self.check_thread.start() - self.manage_window = ManageWindow(controller=controller, tray_icon=self) - def notify_update(self, updates: int): + self.manage_window = ManageWindow(controller=controller, tray_icon=self) + self.check_thread = UpdateCheck(check_interval=check_interval, controller=self.controller) + self.check_thread.signal.connect(self.notify_updates) + self.check_thread.start() + + def notify_updates(self, updates: int): if updates > 0: if self.icon() != self.icon_update: self.setIcon(self.icon_update) diff --git a/view/qt/window.py b/view/qt/window.py index 9e2527bb..fa06bab4 100755 --- a/view/qt/window.py +++ b/view/qt/window.py @@ -38,7 +38,7 @@ class UpdateToggleButton(QToolButton): class ManageWindow(QWidget): - __COLUMNS__ = ['Package', 'Version', 'Latest Version', 'Branch', 'Arch', 'Ref', 'Origin', 'Update ?'] + __COLUMNS__ = ['Name', 'Version', 'Latest Version', 'Branch', 'Arch', 'Ref', 'Origin', 'Update ?'] __BASE_HEIGHT__ = 400 def __init__(self, controller: FlatpakController, tray_icon = None): @@ -46,11 +46,15 @@ class ManageWindow(QWidget): self.controller = controller self.icon_cache = {} self.tray_icon = tray_icon + self.thread_lock = Lock() + self.working = False # restrict the number of threaded actions + self.apps = [] + self.label_flatpak = None self.network_man = QNetworkAccessManager() self.network_man.finished.connect(self._load_icon) - self.icon_flathub = QIcon(resource.get_path('img/flathub_logo.svg')) + self.icon_flathub = QIcon(resource.get_path('img/flathub_45.svg')) self._check_flatpak_installed() self.resize(ManageWindow.__BASE_HEIGHT__, ManageWindow.__BASE_HEIGHT__) self.setWindowTitle('fpakman ({})'.format(__version__)) @@ -67,17 +71,17 @@ class ManageWindow(QWidget): toolbar = QToolBar() toolbar.addWidget(self.checkbox_only_apps) - spacer_1 = QWidget() - spacer_1.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) - toolbar.addWidget(spacer_1) + spacer = QWidget() + spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) + toolbar.addWidget(spacer) self.label_status = QLabel() self.label_status.setText('') toolbar.addWidget(self.label_status) - spacer_2 = QWidget() - spacer_2.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) - toolbar.addWidget(spacer_2) + spacer = QWidget() + spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) + toolbar.addWidget(spacer) self.bt_refresh = QToolButton() self.bt_refresh.setIcon(QIcon(resource.get_path('img/refresh_orange.svg'))) @@ -107,14 +111,11 @@ class ManageWindow(QWidget): self.layout.addWidget(self.table_apps) - self.apps = [] - self.centralize() + self.thread_update = UpdateSelectedApps(self.controller) + self.thread_update.signal.connect(self._finish_update_selected) - self.update_thread = UpdateSelectedPackages(self.controller) - self.update_thread.signal.connect(self._finish_update_selected) - - self.refresh_thread = RefreshPackages(self.controller) - self.refresh_thread.signal.connect(self._finish_refresh) + self.thread_refresh = RefreshApps(self.controller) + self.thread_refresh.signal.connect(self._finish_refresh) self.toolbar_bottom = QToolBar() self.label_updates = QLabel('') @@ -123,11 +124,11 @@ class ManageWindow(QWidget): spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.toolbar_bottom.addWidget(spacer) - self.toolbar_bottom.addWidget(QLabel('flatpak: ' + self.controller.get_version())) + self.label_flatpak = QLabel(self._get_flatpak_label()) + self.toolbar_bottom.addWidget(self.label_flatpak) self.layout.addWidget(self.toolbar_bottom) - self.thread_lock = Lock() - self.working = False # restrict the number of threaded actions + self.centralize() def closeEvent(self, event): @@ -159,6 +160,12 @@ class ManageWindow(QWidget): error_msg.exec_() exit(1) + if self.label_flatpak: + self.label_flatpak.setText(self._get_flatpak_label()) + + def _get_flatpak_label(self): + return 'flatpak: ' + self.controller.get_version() + def _acquire_lock(self): self.thread_lock.acquire() @@ -183,11 +190,11 @@ class ManageWindow(QWidget): if self._acquire_lock(): self._check_flatpak_installed() self._begin_action('Refreshing...') - self.refresh_thread.start() + self.thread_refresh.start() def _finish_refresh(self): - self.update_packages(self.refresh_thread.apps) + self.update_apps(self.thread_refresh.apps) self.finish_action() self._release_lock() @@ -228,7 +235,7 @@ class ManageWindow(QWidget): geo.moveCenter(center_point) self.move(geo.topLeft()) - def update_packages(self, apps: List[dict]): + def update_apps(self, apps: List[dict]): self._check_flatpak_installed() self.table_apps.setEnabled(True) @@ -315,15 +322,15 @@ class ManageWindow(QWidget): if to_update: self._begin_action('Updating...') - self.update_thread.refs_to_update = to_update - self.update_thread.start() + self.thread_update.refs_to_update = to_update + self.thread_update.start() def _finish_update_selected(self): - self.update_packages(self.update_thread.updated_apps) + self.update_apps(self.thread_update.updated_apps) self.finish_action() - if self.tray_icon and self.update_thread.updated_apps: - self.tray_icon.notify_update(len([app for app in self.update_thread.updated_apps if app['update']])) + if self.tray_icon and self.thread_update.updated_apps: + self.tray_icon.notify_updates(len([app for app in self.thread_update.updated_apps if app['update']])) self._release_lock() @@ -343,12 +350,12 @@ class ManageWindow(QWidget): # Threaded actions -class UpdateSelectedPackages(QThread): +class UpdateSelectedApps(QThread): signal = pyqtSignal() def __init__(self, controller: FlatpakController): - super(UpdateSelectedPackages, self).__init__() + super(UpdateSelectedApps, self).__init__() self.controller = controller self.refs_to_update = [] self.updated_apps = None @@ -358,12 +365,12 @@ class UpdateSelectedPackages(QThread): self.signal.emit() -class RefreshPackages(QThread): +class RefreshApps(QThread): signal = pyqtSignal() def __init__(self, controller: FlatpakController): - super(RefreshPackages, self).__init__() + super(RefreshApps, self).__init__() self.controller = controller self.apps = None