Retrieving app information and history

This commit is contained in:
Vinícius Moreira
2019-06-26 15:52:26 -03:00
committed by GitHub
parent f9f47d1429
commit c2e59ba757
12 changed files with 694 additions and 69 deletions

View File

@@ -1,12 +1,13 @@
import json
from typing import List
from PyQt5.QtCore import Qt, QUrl
from PyQt5.QtCore import Qt, QUrl, QThread, pyqtSignal
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
QMessageBox, QHeaderView, QDialog, QLineEdit, QVBoxLayout, QPlainTextEdit
from fpakman.core import resource
from fpakman.core import resource, flatpak
from fpakman.core.controller import FlatpakController
from fpakman.view.qt import dialog
@@ -48,8 +49,6 @@ class AppsTable(QTableWidget):
self.setHorizontalHeaderLabels(columns)
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.icon_flathub = QIcon(resource.get_path('img/flathub_45.svg'))
self.icon_uninstall = QIcon(resource.get_path('img/uninstall.svg'))
self.icon_downgrade = QIcon(resource.get_path('img/downgrade.svg'))
self.network_man = QNetworkAccessManager()
self.network_man.finished.connect(self._load_icon)
@@ -59,28 +58,41 @@ class AppsTable(QTableWidget):
def contextMenuEvent(self, QContextMenuEvent): # selected row right click event
menu_row = QMenu()
action_info = QAction(self.parent.locale_keys["manage_window.apps_table.row.actions.info"])
action_info.setIcon(QIcon(resource.get_path('img/info.svg')))
action_info.triggered.connect(self._get_app_info)
menu_row.addAction(action_info)
action_history = QAction(self.parent.locale_keys["manage_window.apps_table.row.actions.history"])
action_history.setIcon(QIcon(resource.get_path('img/history.svg')))
action_history.triggered.connect(self._get_app_history)
menu_row.addAction(action_history)
action_uninstall = QAction(self.parent.locale_keys["manage_window.apps_table.row.actions.uninstall"])
action_uninstall.setIcon(self.icon_uninstall)
action_uninstall.setIcon(QIcon(resource.get_path('img/uninstall.svg')))
action_uninstall.triggered.connect(self._uninstall_app)
menu_row.addAction(action_uninstall)
app = self._get_selected_app()
app = self.get_selected_app()
if not app['model']['runtime']: # downgrade only allowed for apps
action_downgrade = QAction(self.parent.locale_keys["manage_window.apps_table.row.actions.downgrade"])
action_downgrade.triggered.connect(self._downgrade_app)
action_downgrade.setIcon(self.icon_downgrade)
action_downgrade.setIcon(QIcon(resource.get_path('img/downgrade.svg')))
menu_row.addAction(action_downgrade)
menu_row.adjustSize()
menu_row.popup(QCursor.pos())
menu_row.exec_()
def _get_selected_app(self):
def get_selected_app(self):
return self.parent.apps[self.currentRow()]
def get_selected_app_icon(self):
return self.item(self.currentRow(), 0).icon()
def _uninstall_app(self):
selected_app = self._get_selected_app()
selected_app = self.get_selected_app()
if dialog.ask_confirmation(title=self.parent.locale_keys['manage_window.apps_table.row.actions.uninstall.popup.title'],
body=self.parent.locale_keys['manage_window.apps_table.row.actions.uninstall.popup.body'].format(selected_app['model']['name']),
@@ -88,13 +100,19 @@ class AppsTable(QTableWidget):
self.parent.uninstall_app(selected_app['model']['ref'])
def _downgrade_app(self):
selected_app = self._get_selected_app()
selected_app = self.get_selected_app()
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'])
def _get_app_info(self):
self.parent.get_app_info(self.get_selected_app())
def _get_app_history(self):
self.parent.get_app_history(self.get_selected_app())
def _load_icon(self, http_response):
icon_url = http_response.url().toString()
pixmap = QPixmap()

View File

@@ -0,0 +1,52 @@
import operator
from functools import reduce
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QDialog, QVBoxLayout, QTableWidget, QTableWidgetItem, QHeaderView
class HistoryDialog(QDialog):
def __init__(self, app: dict, app_icon: QIcon, locale_keys: dict):
super(HistoryDialog, self).__init__()
self.setWindowTitle('{} - {} '.format(locale_keys['popup.history.title'], app['model']['name']))
self.setWindowIcon(app_icon)
layout = QVBoxLayout()
self.setLayout(layout)
table_history = QTableWidget()
table_history.setFocusPolicy(Qt.NoFocus)
table_history.setShowGrid(False)
table_history.verticalHeader().setVisible(False)
table_history.setAlternatingRowColors(True)
table_history.setColumnCount(len(app['commits'][0]))
table_history.setRowCount(len(app['commits']))
table_history.setHorizontalHeaderLabels([locale_keys['flatpak.info.' + key].capitalize() for key in sorted(app['commits'][0].keys())])
for row, commit in enumerate(app['commits']):
current_app_commit = app['model']['commit'] == commit['commit']
for col, key in enumerate(sorted(commit.keys())):
item = QTableWidgetItem()
item.setText(commit[key])
item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
if current_app_commit:
item.setBackground(Qt.darkYellow)
item.setToolTip(locale_keys['popup.history.selected.tooltip'])
table_history.setItem(row, col, item)
layout.addWidget(table_history)
header_horizontal = table_history.horizontalHeader()
for i in range(0, table_history.columnCount()):
header_horizontal.setSectionResizeMode(i, QHeaderView.Stretch)
new_width = reduce(operator.add, [table_history.columnWidth(i) for i in range(table_history.columnCount())])
self.resize(new_width, table_history.height())

34
fpakman/view/qt/info.py Normal file
View File

@@ -0,0 +1,34 @@
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QDialog, QVBoxLayout, QFormLayout, QGroupBox, \
QLineEdit, QLabel
class InfoDialog(QDialog):
def __init__(self, app: dict, app_icon: QIcon, locale_keys: dict):
super(InfoDialog, self).__init__()
self.setWindowTitle(app['name'])
self.setWindowIcon(app_icon)
layout = QVBoxLayout()
self.setLayout(layout)
gbox_info_layout = QFormLayout()
gbox_info = QGroupBox()
gbox_info.setLayout(gbox_info_layout)
layout.addWidget(gbox_info)
for attr in sorted(app.keys()):
if attr != 'name':
text = QLineEdit()
text.setText(app[attr])
text.setStyleSheet("width: 400px")
text.setReadOnly(True)
text.setCursorPosition(0)
label = QLabel("{}: ".format(locale_keys.get('flatpak.info.' + attr, attr)).capitalize())
label.setStyleSheet("font-weight: bold")
gbox_info_layout.addRow(label, text)
self.adjustSize()

View File

@@ -1,19 +1,22 @@
import json
import operator
from functools import reduce
from threading import Lock
from typing import List
from PyQt5.QtCore import QThread, pyqtSignal, QEvent
from PyQt5.QtCore import QThread, pyqtSignal, QEvent, Qt
from PyQt5.QtGui import QIcon, QWindowStateChangeEvent
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QApplication, QCheckBox, QHeaderView, QToolButton, QToolBar, \
QSizePolicy, QLabel, QMessageBox, QPlainTextEdit
from fpakman.core.model import FlatpakManager, ImpossibleDowngradeException
QSizePolicy, QLabel, QPlainTextEdit, QDialog, QGroupBox, QFormLayout, QLineEdit, QTableWidget, QTableWidgetItem
from fpakman import __version__
from fpakman.core import resource
from fpakman.core import resource, flatpak
from fpakman.core.controller import FlatpakController
from fpakman.core.model import FlatpakManager, ImpossibleDowngradeException
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
@@ -21,17 +24,17 @@ 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, controller: FlatpakController, manager: FlatpakManager, tray_icon=None):
super(ManageWindow, self).__init__()
self.locale_keys = locale_keys
self.column_names = [locale_keys['manage_window.columns.name'],
locale_keys['manage_window.columns.version'],
locale_keys['manage_window.columns.latest_version'],
locale_keys['manage_window.columns.branch'],
locale_keys['manage_window.columns.arch'],
locale_keys['manage_window.columns.ref'],
locale_keys['manage_window.columns.origin'],
locale_keys['manage_window.columns.update']]
self.column_names = [locale_keys[key].capitalize() for key in ['flatpak.info.name',
'flatpak.info.version',
'manage_window.columns.latest_version',
'flatpak.info.branch',
'flatpak.info.arch',
'flatpak.info.ref',
'flatpak.info.origin',
'manage_window.columns.update']]
self.controller = controller
self.manager = manager
self.tray_icon = tray_icon
@@ -112,6 +115,12 @@ class ManageWindow(QWidget):
self.thread_downgrade.signal_output.connect(self._update_action_output)
self.thread_downgrade.signal_finished.connect(self._finish_downgrade)
self.thread_get_info = GetAppInfo()
self.thread_get_info.signal_finished.connect(self._finish_get_info)
self.thread_get_history = GetAppHistory()
self.thread_get_history.signal_finished.connect(self._finish_get_history)
self.toolbar_bottom = QToolBar()
self.label_updates = QLabel('')
self.toolbar_bottom.addWidget(self.label_updates)
@@ -174,7 +183,7 @@ class ManageWindow(QWidget):
if self._acquire_lock():
self._check_flatpak_installed()
self._begin_action(self.locale_keys['manage_window.status.refreshing'] + '...')
self._begin_action(self.locale_keys['manage_window.status.refreshing'])
if clear_output:
self.textarea_output.clear()
@@ -194,7 +203,7 @@ class ManageWindow(QWidget):
if self._acquire_lock():
self.textarea_output.clear()
self.textarea_output.setVisible(True)
self._begin_action(self.locale_keys['manage_window.status.uninstalling'] + '...')
self._begin_action(self.locale_keys['manage_window.status.uninstalling'])
self.thread_uninstall.app_ref = app_ref
self.thread_uninstall.start()
@@ -303,7 +312,7 @@ class ManageWindow(QWidget):
self.textarea_output.clear()
self.textarea_output.setVisible(True)
self._begin_action(self.locale_keys['manage_window.status.upgrading'] + '...')
self._begin_action(self.locale_keys['manage_window.status.upgrading'])
self.thread_update.refs_to_update = to_update
self.thread_update.start()
@@ -316,7 +325,7 @@ class ManageWindow(QWidget):
self.textarea_output.appendPlainText(output)
def _begin_action(self, action_label: str):
self.label_status.setText(action_label)
self.label_status.setText(action_label + "...")
self.bt_upgrade.setEnabled(False)
self.bt_refresh.setEnabled(False)
self.checkbox_only_apps.setEnabled(False)
@@ -345,12 +354,44 @@ class ManageWindow(QWidget):
self.textarea_output.clear()
self.textarea_output.setVisible(True)
self._begin_action(self.locale_keys['manage_window.status.downgrading'] + '...')
self._begin_action(self.locale_keys['manage_window.status.downgrading'])
self.thread_downgrade.app_ref = app_ref
self.thread_downgrade.root_password = pwd
self.thread_downgrade.start()
def get_app_info(self, app: dict):
if self._acquire_lock():
self.textarea_output.clear()
self.textarea_output.setVisible(False)
self._begin_action(self.locale_keys['manage_window.status.info'])
self.thread_get_info.app = app
self.thread_get_info.start()
def get_app_history(self, app: dict):
if self._acquire_lock():
self.textarea_output.clear()
self.textarea_output.setVisible(False)
self._begin_action(self.locale_keys['manage_window.status.history'])
self.thread_get_history.app = app
self.thread_get_history.start()
def _finish_get_info(self, app_info: dict):
self._release_lock()
self.finish_action()
dialog_info = InfoDialog(app_info, self.table_apps.get_selected_app_icon(), self.locale_keys)
dialog_info.exec_()
def _finish_get_history(self, app: dict):
self._release_lock()
self.finish_action()
dialog_history = HistoryDialog(app, self.table_apps.get_selected_app_icon(), self.locale_keys)
dialog_history.exec_()
# Threaded actions
class UpdateSelectedApps(QThread):
@@ -433,3 +474,33 @@ class DowngradeApp(QThread):
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