Refactoring and improvements (#12)

* Removing controller

* Refactoring FlatpakManager

* Retrieving only installed apps data from the API

* Removing wrong password logs
This commit is contained in:
Vinícius Moreira
2019-06-26 18:32:49 -03:00
committed by GitHub
parent c2e59ba757
commit 97477c4274
15 changed files with 268 additions and 330 deletions

View File

@@ -1,14 +1,12 @@
import json
from typing import List
from PyQt5.QtCore import Qt, QUrl, QThread, pyqtSignal
from PyQt5.QtCore import Qt, QUrl
from PyQt5.QtGui import QPixmap, QIcon, QColor, QCursor
from PyQt5.QtNetwork import QNetworkRequest, QNetworkAccessManager
from PyQt5.QtWidgets import QTableWidget, QTableView, QMenu, QAction, QTableWidgetItem, QToolButton, QWidget, \
QMessageBox, QHeaderView, QDialog, QLineEdit, QVBoxLayout, QPlainTextEdit
QHeaderView
from fpakman.core import resource, flatpak
from fpakman.core.controller import FlatpakController
from fpakman.core import resource
from fpakman.view.qt import dialog
@@ -36,10 +34,9 @@ class UpdateToggleButton(QToolButton):
class AppsTable(QTableWidget):
def __init__(self, parent: QWidget, controller: FlatpakController, columns: List[str]):
def __init__(self, parent: QWidget, columns: List[str]):
super(AppsTable, self).__init__()
self.parent = parent
self.controller = controller
self.columns = columns
self.setColumnCount(len(columns))
self.setFocusPolicy(Qt.NoFocus)
@@ -105,7 +102,7 @@ class AppsTable(QTableWidget):
if dialog.ask_confirmation(title=self.parent.locale_keys['manage_window.apps_table.row.actions.downgrade'],
body=self.parent.locale_keys['manage_window.apps_table.row.actions.downgrade.popup.body'].format(selected_app['model']['name']),
locale_keys=self.parent.locale_keys):
self.parent.downgrade_app(selected_app['model']['ref'])
self.parent.downgrade_app(selected_app)
def _get_app_info(self):
self.parent.get_app_info(self.get_selected_app())

View File

@@ -12,12 +12,13 @@ def show_error(title: str, body: str, icon: QIcon = QIcon(resource.get_path('img
if icon:
error_msg.setWindowIcon(icon)
error_msg.exec_()
def ask_confirmation(title: str, body: str, locale_keys: dict, icon: QIcon = QIcon(resource.get_path('img/flathub_45.svg'))):
dialog_confirmation = QMessageBox()
dialog_confirmation.setIcon(QMessageBox.Critical)
dialog_confirmation.setIcon(QMessageBox.Question)
dialog_confirmation.setWindowTitle(title)
dialog_confirmation.setText(body)
bt_yes = dialog_confirmation.addButton(locale_keys['popup.button.yes'], QMessageBox.YesRole)

View File

@@ -1,3 +1,4 @@
import io
import os
import subprocess
@@ -32,8 +33,13 @@ def ask_root_password(locale_keys: dict):
def validate_password(password: str) -> bool:
f = os.popen('echo {} | sudo -S whoami'.format(password))
res = f.read()
f.close()
proc = subprocess.Popen('echo {} | sudo -S whoami'.format(password),
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.DEVNULL,
bufsize=-1)
stream = os._wrap_close(io.TextIOWrapper(proc.stdout), proc)
res = stream.read()
stream.close()
return bool(res.strip())

View File

@@ -4,10 +4,9 @@ import time
from PyQt5.QtCore import QThread, pyqtSignal, QCoreApplication
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QSystemTrayIcon, QMenu
from fpakman.core.model import FlatpakManager
from fpakman.core.controller import FlatpakManager
from fpakman.core import resource
from fpakman.core.controller import FlatpakController
from fpakman.view.qt.window import ManageWindow
@@ -15,16 +14,16 @@ class UpdateCheck(QThread):
signal = pyqtSignal(int)
def __init__(self, check_interval: int, controller: FlatpakController, parent=None):
def __init__(self, manager: FlatpakManager, check_interval: int, parent=None):
super(UpdateCheck, self).__init__(parent)
self.controller = controller
self.check_interval = check_interval
self.manager = manager
def run(self):
while True:
apps = self.controller.refresh()
apps = self.manager.read_installed()
updates = len([app for app in apps if app['update']])
@@ -35,10 +34,9 @@ class UpdateCheck(QThread):
class TrayIcon(QSystemTrayIcon):
def __init__(self, locale_keys: dict, controller: FlatpakController, manager: FlatpakManager, check_interval: int = 60):
def __init__(self, locale_keys: dict, manager: FlatpakManager, check_interval: int = 60):
super(TrayIcon, self).__init__()
self.locale_keys = locale_keys
self.controller = controller
self.manager = manager
self.icon_default = QIcon(resource.get_path('img/flathub_45.svg'))
@@ -52,8 +50,8 @@ class TrayIcon(QSystemTrayIcon):
self.action_exit.triggered.connect(lambda: QCoreApplication.exit())
self.setContextMenu(self.menu)
self.manage_window = ManageWindow(locale_keys=self.locale_keys, controller=controller, manager=self.manager, tray_icon=self)
self.check_thread = UpdateCheck(check_interval=check_interval, controller=self.controller)
self.manage_window = ManageWindow(locale_keys=self.locale_keys, manager=self.manager, tray_icon=self)
self.check_thread = UpdateCheck(check_interval=check_interval, manager=self.manager)
self.check_thread.signal.connect(self.notify_updates)
self.check_thread.start()
@@ -78,7 +76,9 @@ class TrayIcon(QSystemTrayIcon):
def show_manage_window(self):
if not self.manage_window:
self.manage_window = ManageWindow(controller=self.controller)
self.manage_window = ManageWindow(locale_keys=self.locale_keys,
manager=self.manager,
tray_icon=self)
self.manage_window.refresh()
self.manage_window.show()

115
fpakman/view/qt/thread.py Normal file
View File

@@ -0,0 +1,115 @@
from PyQt5.QtCore import QThread, pyqtSignal
from fpakman.core import flatpak
from fpakman.core.controller import FlatpakManager
from fpakman.view.qt import dialog
class UpdateSelectedApps(QThread):
signal_finished = pyqtSignal()
signal_output = pyqtSignal(str)
def __init__(self):
super(UpdateSelectedApps, self).__init__()
self.refs_to_update = []
def run(self):
for app_ref in self.refs_to_update:
for output in flatpak.update_and_stream(app_ref):
line = output.decode().strip()
if line:
self.signal_output.emit(line)
self.signal_finished.emit()
class RefreshApps(QThread):
signal = pyqtSignal(list)
def __init__(self, manager: FlatpakManager):
super(RefreshApps, self).__init__()
self.manager = manager
def run(self):
self.signal.emit(self.manager.read_installed())
class UninstallApp(QThread):
signal_finished = pyqtSignal()
signal_output = pyqtSignal(str)
def __init__(self):
super(UninstallApp, self).__init__()
self.app_ref = None
def run(self):
if self.app_ref:
for output in flatpak.uninstall_and_stream(self.app_ref):
line = output.decode().strip()
if line:
self.signal_output.emit(line)
self.signal_finished.emit()
class DowngradeApp(QThread):
signal_finished = pyqtSignal()
signal_output = pyqtSignal(str)
def __init__(self, manager: FlatpakManager, locale_keys: dict):
super(DowngradeApp, self).__init__()
self.manager = manager
self.app = None
self.root_password = None
self.locale_keys = locale_keys
def run(self):
if self.app:
stream = self.manager.downgrade_app(self.app['model'], self.root_password)
if stream is None:
dialog.show_error(title=self.locale_keys['popup.downgrade.impossible.title'],
body=self.locale_keys['popup.downgrade.impossible.body'])
else:
for output in self.manager.downgrade_app(self.app['model'], self.root_password):
line = output.decode().strip()
if line:
self.signal_output.emit(line)
self.app = None
self.root_password = None
self.signal_finished.emit()
class GetAppInfo(QThread):
signal_finished = pyqtSignal(dict)
def __init__(self):
super(GetAppInfo, self).__init__()
self.app = None
def run(self):
if self.app:
app_info = flatpak.get_app_info_fields(self.app['model']['id'], self.app['model']['branch'])
app_info['name'] = self.app['model']['name']
app_info['type'] = 'runtime' if self.app['model']['runtime'] else 'app'
self.signal_finished.emit(app_info)
self.app = None
class GetAppHistory(QThread):
signal_finished = pyqtSignal(dict)
def __init__(self):
super(GetAppHistory, self).__init__()
self.app = None
def run(self):
if self.app:
commits = flatpak.get_app_commits_data(self.app['model']['ref'], self.app['model']['origin'])
self.signal_finished.emit({'model': self.app['model'], 'commits': commits})
self.app = None

View File

@@ -1,30 +1,30 @@
import json
import operator
from functools import reduce
from threading import Lock
from typing import List
from PyQt5.QtCore import QThread, pyqtSignal, QEvent, Qt
from PyQt5.QtCore import QEvent
from PyQt5.QtGui import QIcon, QWindowStateChangeEvent
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QApplication, QCheckBox, QHeaderView, QToolButton, QToolBar, \
QSizePolicy, QLabel, QPlainTextEdit, QDialog, QGroupBox, QFormLayout, QLineEdit, QTableWidget, QTableWidgetItem
QSizePolicy, QLabel, QPlainTextEdit
from fpakman import __version__
from fpakman.core import resource, flatpak
from fpakman.core.controller import FlatpakController
from fpakman.core.model import FlatpakManager, ImpossibleDowngradeException
from fpakman.core.controller import FlatpakManager
from fpakman.view.qt import dialog
from fpakman.view.qt.apps_table import AppsTable
from fpakman.view.qt.history import HistoryDialog
from fpakman.view.qt.info import InfoDialog
from fpakman.view.qt.root import is_root, ask_root_password
from fpakman.view.qt.thread import UpdateSelectedApps, RefreshApps, UninstallApp, DowngradeApp, GetAppInfo, \
GetAppHistory
class ManageWindow(QWidget):
__BASE_HEIGHT__ = 400
def __init__(self, locale_keys: dict, controller: FlatpakController, manager: FlatpakManager, tray_icon=None):
def __init__(self, locale_keys: dict, manager: FlatpakManager, tray_icon=None):
super(ManageWindow, self).__init__()
self.locale_keys = locale_keys
self.column_names = [locale_keys[key].capitalize() for key in ['flatpak.info.name',
@@ -35,7 +35,6 @@ class ManageWindow(QWidget):
'flatpak.info.ref',
'flatpak.info.origin',
'manage_window.columns.update']]
self.controller = controller
self.manager = manager
self.tray_icon = tray_icon
self.thread_lock = Lock()
@@ -88,7 +87,7 @@ class ManageWindow(QWidget):
self.layout.addWidget(toolbar)
self.table_apps = AppsTable(self, self.controller, self.column_names)
self.table_apps = AppsTable(self, self.column_names)
self.table_apps.change_headers_policy()
self.layout.addWidget(self.table_apps)
@@ -100,18 +99,18 @@ class ManageWindow(QWidget):
self.textarea_output.setVisible(False)
self.textarea_output.setReadOnly(True)
self.thread_update = UpdateSelectedApps(self.controller)
self.thread_update = UpdateSelectedApps()
self.thread_update.signal_output.connect(self._update_action_output)
self.thread_update.signal_finished.connect(self._finish_update_selected)
self.thread_refresh = RefreshApps(self.controller)
self.thread_refresh = RefreshApps(self.manager)
self.thread_refresh.signal.connect(self._finish_refresh)
self.thread_uninstall = UninstallApp(self.controller)
self.thread_uninstall = UninstallApp()
self.thread_uninstall.signal_output.connect(self._update_action_output)
self.thread_uninstall.signal_finished.connect(self._finish_uninstall)
self.thread_downgrade = DowngradeApp(self.manager)
self.thread_downgrade = DowngradeApp(self.manager, self.locale_keys)
self.thread_downgrade.signal_output.connect(self._update_action_output)
self.thread_downgrade.signal_finished.connect(self._finish_downgrade)
@@ -148,7 +147,7 @@ class ManageWindow(QWidget):
def _check_flatpak_installed(self):
if not self.controller.check_installed():
if not flatpak.is_installed():
dialog.show_error(title=self.locale_keys['popup.flatpak_not_installed.title'],
body=self.locale_keys['popup.flatpak_not_installed.msg'] + '...',
icon=self.icon_flathub)
@@ -158,7 +157,7 @@ class ManageWindow(QWidget):
self.label_flatpak.setText(self._get_flatpak_label())
def _get_flatpak_label(self):
return 'flatpak: ' + self.controller.get_version()
return 'flatpak: ' + flatpak.get_version()
def _acquire_lock(self):
@@ -191,9 +190,9 @@ class ManageWindow(QWidget):
self.thread_refresh.start()
def _finish_refresh(self):
def _finish_refresh(self, apps: List[dict]):
self.update_apps(self.thread_refresh.apps)
self.update_apps(apps)
self.finish_action()
self._release_lock()
@@ -337,7 +336,7 @@ class ManageWindow(QWidget):
self.table_apps.setEnabled(True)
self.label_status.setText('')
def downgrade_app(self, app_ref: str):
def downgrade_app(self, app: dict):
self._check_flatpak_installed()
@@ -356,7 +355,7 @@ class ManageWindow(QWidget):
self.textarea_output.setVisible(True)
self._begin_action(self.locale_keys['manage_window.status.downgrading'])
self.thread_downgrade.app_ref = app_ref
self.thread_downgrade.app = app
self.thread_downgrade.root_password = pwd
self.thread_downgrade.start()
@@ -391,116 +390,3 @@ class ManageWindow(QWidget):
dialog_history = HistoryDialog(app, self.table_apps.get_selected_app_icon(), self.locale_keys)
dialog_history.exec_()
# Threaded actions
class UpdateSelectedApps(QThread):
signal_finished = pyqtSignal()
signal_output = pyqtSignal(str)
def __init__(self, controller: FlatpakController):
super(UpdateSelectedApps, self).__init__()
self.controller = controller
self.refs_to_update = []
def run(self):
for app_ref in self.refs_to_update:
for output in self.controller.update(app_ref):
line = output.decode().strip()
if line:
self.signal_output.emit(line)
self.signal_finished.emit()
class RefreshApps(QThread):
signal = pyqtSignal()
def __init__(self, controller: FlatpakController):
super(RefreshApps, self).__init__()
self.controller = controller
self.apps = None
def run(self):
self.apps = self.controller.refresh()
self.signal.emit()
class UninstallApp(QThread):
signal_finished = pyqtSignal()
signal_output = pyqtSignal(str)
def __init__(self, controller: FlatpakController):
super(UninstallApp, self).__init__()
self.controller = controller
self.app_ref = None
def run(self):
if self.app_ref:
for output in self.controller.uninstall(self.app_ref):
line = output.decode().strip()
if line:
self.signal_output.emit(line)
self.signal_finished.emit()
class DowngradeApp(QThread):
signal_finished = pyqtSignal()
signal_output = pyqtSignal(str)
def __init__(self, manager: FlatpakManager):
super(DowngradeApp, self).__init__()
self.manager = manager
self.app_ref = None
self.root_password = None
def run(self):
if self.app_ref:
try:
for output in self.manager.downgrade_app(self.app_ref, self.root_password):
line = output.decode().strip()
if line:
self.signal_output.emit(line)
except ImpossibleDowngradeException:
dialog.show_error(title=self.locale_keys['popup.downgrade.impossible.title'],
body=self.locale_keys['popup.downgrade.impossible.body'],
icon=self.icon_flathub)
self.app_ref = None
self.root_password = None
self.signal_finished.emit()
class GetAppInfo(QThread):
signal_finished = pyqtSignal(dict)
def __init__(self):
super(GetAppInfo, self).__init__()
self.app = None
def run(self):
if self.app:
app_info = flatpak.get_app_info_fields(self.app['model']['id'], self.app['model']['branch'])
app_info['name'] = self.app['model']['name']
app_info['type'] = 'runtime' if self.app['model']['runtime'] else 'app'
self.signal_finished.emit(app_info)
self.app = None
class GetAppHistory(QThread):
signal_finished = pyqtSignal(dict)
def __init__(self):
super(GetAppHistory, self).__init__()
self.app = None
def run(self):
if self.app:
commits = flatpak.get_app_commits_data(self.app['model']['ref'], self.app['model']['origin'])
self.signal_finished.emit({'model': self.app['model'], 'commits': commits})
self.app = None