mirror of
https://github.com/spalencsar/bearhub.git
synced 2026-07-06 21:44:16 +02:00
Retrieving app information and history
This commit is contained in:
@@ -6,6 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||
|
||||
## [0.3.0]
|
||||
### Features
|
||||
- Allows to retrieve app information and history by right clicking it.
|
||||
- Allows app uninstall and downgrade by right clicking it.
|
||||
|
||||
### Improvements
|
||||
|
||||
@@ -4,6 +4,8 @@ from typing import List
|
||||
|
||||
from fpakman.core import system
|
||||
|
||||
BASE_CMD = 'flatpak'
|
||||
|
||||
|
||||
def app_str_to_json(line: str, version: str) -> dict:
|
||||
|
||||
@@ -39,22 +41,24 @@ def app_str_to_json(line: str, version: str) -> dict:
|
||||
return app
|
||||
|
||||
|
||||
def get_app_info_fields(app_id: str, branch: str, fields: List[str], check_runtime: bool = False):
|
||||
def get_app_info_fields(app_id: str, branch: str, fields: List[str] = [], check_runtime: bool = False):
|
||||
info = re.findall(r'\w+:\s.+', get_app_info(app_id, branch))
|
||||
data = {}
|
||||
fields_to_retrieve = len(fields) + (1 if check_runtime and 'ref' not in fields else 0)
|
||||
|
||||
for field in info:
|
||||
|
||||
if fields_to_retrieve == 0:
|
||||
if fields and fields_to_retrieve == 0:
|
||||
break
|
||||
|
||||
field_val = field.split(':')
|
||||
field_name = field_val[0].lower()
|
||||
|
||||
if field_name in fields or (check_runtime and field_name == 'ref'):
|
||||
if not fields or field_name in fields or (check_runtime and field_name == 'ref'):
|
||||
data[field_name] = field_val[1].strip()
|
||||
fields_to_retrieve -= 1
|
||||
|
||||
if fields:
|
||||
fields_to_retrieve -= 1
|
||||
|
||||
if check_runtime and field_name == 'ref':
|
||||
data['runtime'] = data['ref'].startswith('runtime/')
|
||||
@@ -63,16 +67,16 @@ def get_app_info_fields(app_id: str, branch: str, fields: List[str], check_runti
|
||||
|
||||
|
||||
def get_version():
|
||||
res = system.run_cmd('flatpak --version')
|
||||
res = system.run_cmd('{} --version'.format(BASE_CMD))
|
||||
return res.split(' ')[1].strip() if res else None
|
||||
|
||||
|
||||
def get_app_info(app_id: str, branch: str):
|
||||
return system.run_cmd('flatpak info {} {}'.format(app_id, branch))
|
||||
return system.run_cmd('{} info {} {}'.format(BASE_CMD, app_id, branch))
|
||||
|
||||
|
||||
def list_installed() -> List[dict]:
|
||||
apps_str = system.run_cmd('flatpak list')
|
||||
apps_str = system.run_cmd('{} list'.format(BASE_CMD))
|
||||
|
||||
if apps_str:
|
||||
version = get_version()
|
||||
@@ -83,7 +87,7 @@ def list_installed() -> List[dict]:
|
||||
|
||||
|
||||
def update(app_ref: str) -> bool:
|
||||
return bool(system.run_cmd('flatpak update -y ' + app_ref))
|
||||
return bool(system.run_cmd('{} update -y {}'.format(BASE_CMD, app_ref)))
|
||||
|
||||
|
||||
def update_and_stream(app_ref: str):
|
||||
@@ -92,7 +96,7 @@ def update_and_stream(app_ref: str):
|
||||
:param app_ref:
|
||||
:return:
|
||||
"""
|
||||
return system.stream_cmd(['flatpak', 'update', '-y', app_ref])
|
||||
return system.stream_cmd([BASE_CMD, 'update', '-y', app_ref])
|
||||
|
||||
|
||||
def uninstall_and_stream(app_ref: str):
|
||||
@@ -101,11 +105,11 @@ def uninstall_and_stream(app_ref: str):
|
||||
:param app_ref:
|
||||
:return:
|
||||
"""
|
||||
return system.stream_cmd(['flatpak', 'uninstall', app_ref, '-y'])
|
||||
return system.stream_cmd([BASE_CMD, 'uninstall', app_ref, '-y'])
|
||||
|
||||
|
||||
def list_updates_as_str():
|
||||
return system.run_cmd('flatpak update', ignore_return_code=True)
|
||||
return system.run_cmd('{} update'.format(BASE_CMD), ignore_return_code=True)
|
||||
|
||||
|
||||
def downgrade_and_stream(app_ref: str, commit: str, root_password: str):
|
||||
@@ -114,12 +118,31 @@ def downgrade_and_stream(app_ref: str, commit: str, root_password: str):
|
||||
|
||||
if root_password is not None:
|
||||
downgrade_cmd.extend(['sudo', '-S'])
|
||||
pwdin = subprocess.Popen(['echo', root_password], stdout=subprocess.PIPE).stdout
|
||||
pwdin = system.stream_cmd(['echo', root_password])
|
||||
|
||||
downgrade_cmd.extend(['flatpak', 'update', '--commit={}'.format(commit), app_ref, '-y'])
|
||||
downgrade_cmd.extend([BASE_CMD, 'update', '--commit={}'.format(commit), app_ref, '-y'])
|
||||
return subprocess.Popen(downgrade_cmd, stdin=pwdin, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL).stdout
|
||||
|
||||
|
||||
def get_app_commits(app_ref: str, origin: str) -> List[str]:
|
||||
log = system.run_cmd('flatpak remote-info --log {} {}'.format(origin, app_ref))
|
||||
log = system.run_cmd('{} remote-info --log {} {}'.format(BASE_CMD, origin, app_ref))
|
||||
return re.findall(r'Commit+:\s(.+)', log)
|
||||
|
||||
|
||||
def get_app_commits_data(app_ref: str, origin: str) -> List[dict]:
|
||||
log = system.run_cmd('{} remote-info --log {} {}'.format(BASE_CMD, origin, app_ref))
|
||||
|
||||
res = re.findall(r'(Commit|Subject|Date):\s(.+)', log)
|
||||
|
||||
commits = []
|
||||
|
||||
commit = {}
|
||||
|
||||
for idx, data in enumerate(res):
|
||||
commit[data[0].strip().lower()] = data[1].strip()
|
||||
|
||||
if (idx + 1) % 3 == 0:
|
||||
commits.append(commit)
|
||||
commit = {}
|
||||
|
||||
return commits
|
||||
|
||||
@@ -3,9 +3,9 @@ from typing import List
|
||||
|
||||
|
||||
def run_cmd(cmd: str, expected_code: int = 0, ignore_return_code: bool = False) -> str:
|
||||
res = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE)
|
||||
res = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, env={'LANG': 'en'})
|
||||
return res.stdout.decode() if ignore_return_code or res.returncode == expected_code else None
|
||||
|
||||
|
||||
def stream_cmd(cmd: List[str]):
|
||||
return subprocess.Popen(cmd, stdout=subprocess.PIPE).stdout
|
||||
return subprocess.Popen(cmd, stdout=subprocess.PIPE, env={'LANG': 'en'}).stdout
|
||||
|
||||
218
fpakman/resources/img/history.svg
Executable file
218
fpakman/resources/img/history.svg
Executable file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 40 KiB |
154
fpakman/resources/img/info.svg
Executable file
154
fpakman/resources/img/info.svg
Executable file
@@ -0,0 +1,154 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
id="Capa_1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
width="47.999996"
|
||||
height="48.000004"
|
||||
viewBox="0 0 47.999997 48.000005"
|
||||
xml:space="preserve"
|
||||
sodipodi:docname="info.svg"
|
||||
inkscape:version="0.92.3 (2405546, 2018-03-11)"><metadata
|
||||
id="metadata128"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs126"><linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient153"><stop
|
||||
style="stop-color:#0000ff;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop149" /><stop
|
||||
style="stop-color:#0000ff;stop-opacity:0;"
|
||||
offset="1"
|
||||
id="stop151" /></linearGradient><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient153"
|
||||
id="linearGradient155"
|
||||
x1="-180.77992"
|
||||
y1="-30.518711"
|
||||
x2="337.13013"
|
||||
y2="868.49902"
|
||||
gradientUnits="userSpaceOnUse" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient153"
|
||||
id="linearGradient157"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="-180.77992"
|
||||
y1="-30.518711"
|
||||
x2="337.13013"
|
||||
y2="868.49902" /></defs><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1366"
|
||||
inkscape:window-height="739"
|
||||
id="namedview124"
|
||||
showgrid="false"
|
||||
showborder="false"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0"
|
||||
inkscape:zoom="1.8698707"
|
||||
inkscape:cx="239.58875"
|
||||
inkscape:cy="26.740828"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="260"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="Capa_1" />
|
||||
|
||||
<g
|
||||
id="g93"
|
||||
transform="translate(0,-390.534)">
|
||||
</g>
|
||||
<g
|
||||
id="g95"
|
||||
transform="translate(0,-390.534)">
|
||||
</g>
|
||||
<g
|
||||
id="g97"
|
||||
transform="translate(0,-390.534)">
|
||||
</g>
|
||||
<g
|
||||
id="g99"
|
||||
transform="translate(0,-390.534)">
|
||||
</g>
|
||||
<g
|
||||
id="g101"
|
||||
transform="translate(0,-390.534)">
|
||||
</g>
|
||||
<g
|
||||
id="g103"
|
||||
transform="translate(0,-390.534)">
|
||||
</g>
|
||||
<g
|
||||
id="g105"
|
||||
transform="translate(0,-390.534)">
|
||||
</g>
|
||||
<g
|
||||
id="g107"
|
||||
transform="translate(0,-390.534)">
|
||||
</g>
|
||||
<g
|
||||
id="g109"
|
||||
transform="translate(0,-390.534)">
|
||||
</g>
|
||||
<g
|
||||
id="g111"
|
||||
transform="translate(0,-390.534)">
|
||||
</g>
|
||||
<g
|
||||
id="g113"
|
||||
transform="translate(0,-390.534)">
|
||||
</g>
|
||||
<g
|
||||
id="g115"
|
||||
transform="translate(0,-390.534)">
|
||||
</g>
|
||||
<g
|
||||
id="g117"
|
||||
transform="translate(0,-390.534)">
|
||||
</g>
|
||||
<g
|
||||
id="g119"
|
||||
transform="translate(0,-390.534)">
|
||||
</g>
|
||||
<g
|
||||
id="g121"
|
||||
transform="translate(0,-390.534)">
|
||||
</g>
|
||||
<g
|
||||
id="g96"><g
|
||||
style="fill:url(#linearGradient155);fill-opacity:1"
|
||||
transform="scale(0.10945609,0.1094556)"
|
||||
id="g91">
|
||||
<path
|
||||
style="fill:url(#linearGradient157);fill-opacity:1"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path89"
|
||||
d="M 409.133,109.203 C 389.525,75.611 362.928,49.014 329.335,29.407 295.736,9.801 259.058,0 219.273,0 179.492,0 142.803,9.801 109.21,29.407 75.615,49.011 49.018,75.608 29.41,109.203 9.801,142.8 0,179.489 0,219.267 c 0,39.78 9.804,76.463 29.407,110.062 19.607,33.592 46.204,60.189 79.799,79.798 33.597,19.605 70.283,29.407 110.063,29.407 39.78,0 76.47,-9.802 110.065,-29.407 33.593,-19.602 60.189,-46.206 79.795,-79.798 19.603,-33.596 29.403,-70.284 29.403,-110.062 0.001,-39.782 -9.8,-76.472 -29.399,-110.064 z M 182.727,54.813 c 0,-2.666 0.855,-4.853 2.57,-6.565 1.712,-1.711 3.903,-2.57 6.567,-2.57 h 54.82 c 2.662,0 4.853,0.859 6.561,2.57 1.711,1.712 2.573,3.899 2.573,6.565 v 45.682 c 0,2.664 -0.862,4.854 -2.573,6.564 -1.708,1.712 -3.898,2.568 -6.561,2.568 h -54.82 c -2.664,0 -4.854,-0.856 -6.567,-2.568 -1.715,-1.709 -2.57,-3.9 -2.57,-6.564 z m 109.632,301.496 c 0,2.662 -0.863,4.853 -2.57,6.561 -1.704,1.714 -3.895,2.57 -6.563,2.57 H 155.317 c -2.667,0 -4.854,-0.856 -6.567,-2.57 -1.712,-1.708 -2.568,-3.898 -2.568,-6.564 v -45.682 c 0,-2.67 0.856,-4.853 2.568,-6.567 1.713,-1.708 3.903,-2.57 6.567,-2.57 h 27.41 v -91.358 h -27.41 c -2.667,0 -4.853,-0.855 -6.567,-2.568 -1.712,-1.711 -2.568,-3.901 -2.568,-6.567 v -45.679 c 0,-2.666 0.856,-4.853 2.568,-6.567 1.715,-1.713 3.905,-2.568 6.567,-2.568 h 91.367 c 2.662,0 4.853,0.855 6.561,2.568 1.711,1.714 2.573,3.901 2.573,6.567 v 146.179 h 27.401 c 2.669,0 4.859,0.855 6.57,2.566 1.704,1.712 2.566,3.901 2.566,6.567 v 45.683 h 0.004 z" />
|
||||
</g><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path88"
|
||||
d="m 16.36476,36.447391 v -3.208779 h 1.871787 1.871787 V 27.890649 22.542686 H 18.236547 16.36476 V 19.333908 16.12513 h 5.615361 5.615362 v 8.556741 8.556741 h 2.139185 2.139186 v 3.208779 3.208778 H 24.119307 16.36476 Z"
|
||||
style="fill:#ffffff;stroke-width:0.53479636" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path90"
|
||||
d="M 20.571824,11.490228 C 20.375732,11.294136 20.215294,9.8501861 20.215294,8.2814501 V 5.429203 h 3.743574 3.743574 v 3.208778 3.208778 h -3.387043 c -1.862874,0 -3.547483,-0.160439 -3.743575,-0.356531 z"
|
||||
style="fill:#ffffff;stroke-width:0.53479636" /></g></svg>
|
||||
|
After Width: | Height: | Size: 5.6 KiB |
@@ -1,12 +1,8 @@
|
||||
manage_window.title=Flatpak Application Manager
|
||||
manage_window.columns.name=Name
|
||||
manage_window.columns.version=Version
|
||||
manage_window.columns.latest_version=Latest Version
|
||||
manage_window.columns.branch=Branch
|
||||
manage_window.columns.arch=Arch
|
||||
manage_window.columns.ref=Ref
|
||||
manage_window.columns.origin=Origin
|
||||
manage_window.columns.update=Upgrade ?
|
||||
manage_window.apps_table.row.actions.info=Information
|
||||
manage_window.apps_table.row.actions.history=History
|
||||
manage_window.apps_table.row.actions.uninstall=Uninstall
|
||||
manage_window.apps_table.row.actions.uninstall.popup.title=Uninstall
|
||||
manage_window.apps_table.row.actions.uninstall.popup.body=Remove {} ?
|
||||
@@ -18,6 +14,8 @@ manage_window.status.refreshing=Refreshing
|
||||
manage_window.status.upgrading=Upgrading
|
||||
manage_window.status.uninstalling=Uninstalling
|
||||
manage_window.status.downgrading=Downgrading
|
||||
manage_window.status.info=Retrieving information
|
||||
manage_window.status.history=Retrieving history
|
||||
manage_window.bt.refresh.tooltip=Reload the data about installed applications
|
||||
manage_window.bt.upgrade.tooltip=Upgrade all selected applications
|
||||
popup.flatpak_not_installed.title=Error
|
||||
@@ -28,9 +26,29 @@ popup.root.bad_password.title=Error
|
||||
popup.root.bad_password.body=Wrong password
|
||||
popup.downgrade.impossible.title=Impossible to downgrade
|
||||
popup.downgrade.impossible.body=The app is in its first version
|
||||
popup.history.title=History
|
||||
popup.history.selected.tooltip=Current version
|
||||
popup.button.yes=Yes
|
||||
popup.button.no=No
|
||||
popup.button.cancel=Cancel
|
||||
tray.action.manage=Manage applications
|
||||
tray.action.exit=Exit
|
||||
notification.new_updates=Updates found
|
||||
notification.new_updates=Updates found
|
||||
flatpak.info.arch=arch
|
||||
flatpak.info.branch=branch
|
||||
flatpak.info.collection=collection
|
||||
flatpak.info.commit=commit
|
||||
flatpak.info.date=date
|
||||
flatpak.info.id=id
|
||||
flatpak.info.installation=installation
|
||||
flatpak.info.installed=installed
|
||||
flatpak.info.license=license
|
||||
flatpak.info.name=name
|
||||
flatpak.info.origin=origin
|
||||
flatpak.info.parent=parent
|
||||
flatpak.info.ref=ref
|
||||
flatpak.info.runtime=runtime
|
||||
flatpak.info.sdk=sdk
|
||||
flatpak.info.subject=subject
|
||||
flatpak.info.type=type
|
||||
flatpak.info.version=version
|
||||
@@ -1,23 +1,21 @@
|
||||
manage_window.title=Administrador de Aplicativos Flatpak
|
||||
manage_window.columns.name=Nombre
|
||||
manage_window.columns.version=Versión
|
||||
manage_window.columns.latest_version=Ultima Versión
|
||||
manage_window.columns.branch=Rama
|
||||
manage_window.columns.arch=Arch
|
||||
manage_window.columns.ref=Ref
|
||||
manage_window.columns.origin=Origen
|
||||
manage_window.columns.update=¿Actualizar?
|
||||
manage_window.columns.update=Actualizar ?
|
||||
manage_window.apps_table.row.actions.info=Información
|
||||
manage_window.apps_table.row.actions.history=Historia
|
||||
manage_window.apps_table.row.actions.uninstall=Desinstalar
|
||||
manage_window.apps_table.row.actions.uninstall.popup.title=Desinstalación
|
||||
manage_window.apps_table.row.actions.uninstall.popup.body=¿Eliminar {}?
|
||||
manage_window.apps_table.row.actions.downgrade=Revertir versión
|
||||
manage_window.apps_table.row.actions.downgrade.popup.body=¿Realmente quieres revertir la versión actual de {}?
|
||||
manage_window.checkbox.only_apps=Apps
|
||||
manage_window.checkbox.only_apps=Aplicativos
|
||||
manage_window.label.updates=Actualizaciones
|
||||
manage_window.status.refreshing=Recargando
|
||||
manage_window.status.upgrading=Actualizando
|
||||
manage_window.status.uninstalling=Desinstalando
|
||||
manage_window.status.downgrading=Revirtiendo
|
||||
manage_window.status.info=Obteniendo información
|
||||
manage_window.status.history=Obteniendo la historia
|
||||
manage_window.bt.refresh.tooltip=Recarga los datos sobre los aplicativos instalados
|
||||
manage_window.bt.upgrade.tooltip=Actualiza todos los aplicativos seleccionados
|
||||
popup.flatpak_not_installed.title=Error
|
||||
@@ -28,9 +26,29 @@ popup.root.bad_password.title=Error
|
||||
popup.root.bad_password.body=Contraseña incorrecta
|
||||
popup.downgrade.impossible.title=Imposible revertir la versión
|
||||
popup.downgrade.impossible.body=El aplicativo está en su primera versión
|
||||
popup.history.title=Historia
|
||||
popup.history.selected.tooltip=Versión actual
|
||||
popup.button.yes=Sí
|
||||
popup.button.no=No
|
||||
popup.button.cancel=Cancelar
|
||||
tray.action.manage=Administrar aplicativos
|
||||
tray.action.exit=Salir
|
||||
notification.new_updates=Actualizaciones encontradas
|
||||
notification.new_updates=Actualizaciones encontradas
|
||||
flatpak.info.arch=arquitectura
|
||||
flatpak.info.branch=rama
|
||||
flatpak.info.collection=colección
|
||||
flatpak.info.commit=commit
|
||||
flatpak.info.date=fecha
|
||||
flatpak.info.id=id
|
||||
flatpak.info.installation=instalación
|
||||
flatpak.info.installed=instalado
|
||||
flatpak.info.license=licencia
|
||||
flatpak.info.name=nombre
|
||||
flatpak.info.origin=origen
|
||||
flatpak.info.parent=padre
|
||||
flatpak.info.ref=ref
|
||||
flatpak.info.runtime=runtime
|
||||
flatpak.info.sdk=sdk
|
||||
flatpak.info.subject=tema
|
||||
flatpak.info.type=tipo
|
||||
flatpak.info.version=versión
|
||||
@@ -1,23 +1,21 @@
|
||||
manage_window.title=Gerenciador de Aplicativos Flatpak
|
||||
manage_window.columns.name=Nome
|
||||
manage_window.columns.version=Versão
|
||||
manage_window.columns.latest_version=Última Versão
|
||||
manage_window.columns.branch=Ramo
|
||||
manage_window.columns.arch=Arch
|
||||
manage_window.columns.ref=Ref
|
||||
manage_window.columns.origin=Origem
|
||||
manage_window.columns.update=Atualizar ?
|
||||
manage_window.apps_table.row.actions.info=Informação
|
||||
manage_window.apps_table.row.actions.history=Histórico
|
||||
manage_window.apps_table.row.actions.uninstall=Desinstalar
|
||||
manage_window.apps_table.row.actions.uninstall.popup.title=Desinstalação
|
||||
manage_window.apps_table.row.actions.uninstall.popup.body=Remover {}?
|
||||
manage_window.apps_table.row.actions.downgrade=Reverter versão
|
||||
manage_window.apps_table.row.actions.downgrade.popup.body=Você realmente quer reverter a versão atual de {} ?
|
||||
manage_window.checkbox.only_apps=Apps
|
||||
manage_window.checkbox.only_apps=Aplicativos
|
||||
manage_window.label.updates=Atualizações
|
||||
manage_window.status.refreshing=Recarregando
|
||||
manage_window.status.upgrading=Atualizando
|
||||
manage_window.status.uninstalling=Desinstalando
|
||||
manage_window.status.downgrading=Revertendo
|
||||
manage_window.status.info=Obtendo informação
|
||||
manage_window.status.history=Obtendo histórico
|
||||
manage_window.bt.refresh.tooltip=Recarrega os dados sobre os aplicativos instalados
|
||||
manage_window.bt.upgrade.tooltip=Atualiza todos os aplicativos selecionados
|
||||
popup.flatpak_not_installed.title=Erro
|
||||
@@ -28,9 +26,29 @@ popup.root.bad_password.title=Erro
|
||||
popup.root.bad_password.body=Senha incorreta
|
||||
popup.downgrade.impossible.title=Impossível reverter a versão
|
||||
popup.downgrade.impossible.body=O aplicativo está na sua primeira versão
|
||||
popup.history.title=Histórico
|
||||
popup.history.selected.tooltip=Versão atual
|
||||
popup.button.yes=Sim
|
||||
popup.button.no=Não
|
||||
popup.button.cancel=Cancelar
|
||||
tray.action.manage=Gerenciar aplicativos
|
||||
tray.action.exit=Sair
|
||||
notification.new_updates=Atualizações encontradas
|
||||
notification.new_updates=Atualizações encontradas
|
||||
flatpak.info.arch=arquitetura
|
||||
flatpak.info.branch=ramo
|
||||
flatpak.info.collection=coleção
|
||||
flatpak.info.commit=commit
|
||||
flatpak.info.date=data
|
||||
flatpak.info.id=id
|
||||
flatpak.info.installation=instalação
|
||||
flatpak.info.installed=instalado
|
||||
flatpak.info.license=licença
|
||||
flatpak.info.name=nome
|
||||
flatpak.info.origin=origem
|
||||
flatpak.info.parent=pai
|
||||
flatpak.info.ref=ref
|
||||
flatpak.info.runtime=runtime
|
||||
flatpak.info.sdk=sdk
|
||||
flatpak.info.subject=assunto
|
||||
flatpak.info.type=tipo
|
||||
flatpak.info.version=versão
|
||||
@@ -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()
|
||||
|
||||
52
fpakman/view/qt/history.py
Normal file
52
fpakman/view/qt/history.py
Normal 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
34
fpakman/view/qt/info.py
Normal 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()
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user