mirror of
https://github.com/spalencsar/bearhub.git
synced 2026-07-07 22:04:15 +02:00
[feature][flatpak] registering Flathub at system level
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
from typing import List
|
||||
from typing import List, Tuple
|
||||
|
||||
from bauh.api.abstract.view import MessageType, ViewComponent
|
||||
|
||||
@@ -65,3 +65,9 @@ class ProcessWatcher:
|
||||
"""
|
||||
:return: if the use requested to stop the process.
|
||||
"""
|
||||
|
||||
def request_root_password(self) -> Tuple[str, bool]:
|
||||
"""
|
||||
asks the root password for the user
|
||||
:return: a tuple with the typed password and if it is valid
|
||||
"""
|
||||
@@ -4,7 +4,6 @@ from threading import Thread
|
||||
|
||||
import urllib3
|
||||
from PyQt5.QtCore import Qt
|
||||
from PyQt5.QtGui import QIcon
|
||||
from PyQt5.QtWidgets import QApplication
|
||||
|
||||
from bauh import __version__, __app_name__, app_args, ROOT_DIR
|
||||
@@ -15,7 +14,7 @@ from bauh.view.core.controller import GenericSoftwareManager
|
||||
from bauh.view.core.downloader import AdaptableFileDownloader
|
||||
from bauh.view.qt.systray import TrayIcon
|
||||
from bauh.view.qt.window import ManageWindow
|
||||
from bauh.view.util import util, logs, resource, translation
|
||||
from bauh.view.util import util, logs, translation
|
||||
from bauh.view.util.cache import DefaultMemoryCacheFactory, CacheCleaner
|
||||
from bauh.view.util.disk import DefaultDiskCacheLoaderFactory
|
||||
from bauh.view.util.translation import I18n
|
||||
|
||||
5
bauh/commons/user.py
Normal file
5
bauh/commons/user.py
Normal file
@@ -0,0 +1,5 @@
|
||||
import os
|
||||
|
||||
|
||||
def is_root():
|
||||
return os.getuid() == 0
|
||||
@@ -9,6 +9,7 @@ from bauh.api.abstract.handler import ProcessWatcher
|
||||
from bauh.api.abstract.model import PackageHistory, PackageUpdate, SoftwarePackage, PackageSuggestion, \
|
||||
SuggestionPriority
|
||||
from bauh.api.abstract.view import MessageType
|
||||
from bauh.commons import user
|
||||
from bauh.commons.html import strip_html, bold
|
||||
from bauh.commons.system import SystemProcess, ProcessHandler, SimpleProcess
|
||||
from bauh.gems.flatpak import flatpak, SUGGESTIONS_FILE, CONFIG_FILE
|
||||
@@ -67,7 +68,7 @@ class FlatpakManager(SoftwareManager):
|
||||
remote_level = 'user'
|
||||
else:
|
||||
remote_level = 'user'
|
||||
flatpak.set_default_remotes(remote_level)
|
||||
ProcessHandler().handle_simple(flatpak.set_default_remotes(remote_level))
|
||||
|
||||
return remote_level
|
||||
|
||||
@@ -264,8 +265,28 @@ class FlatpakManager(SoftwareManager):
|
||||
deny_label=self.i18n['yes'].capitalize())
|
||||
pkg.installation = 'user' if user_level else 'system'
|
||||
|
||||
remotes = flatpak.list_remotes()
|
||||
|
||||
handler = ProcessHandler(watcher)
|
||||
|
||||
if pkg.installation == 'user' and not remotes['user']:
|
||||
handler.handle_simple(flatpak.set_default_remotes('user'))
|
||||
elif pkg.installation == 'system' and not remotes['system']:
|
||||
if user.is_root():
|
||||
handler.handle_simple(flatpak.set_default_remotes('system'))
|
||||
else:
|
||||
user_password, valid = watcher.request_root_password()
|
||||
if not valid:
|
||||
watcher.print('Operation aborted')
|
||||
return False
|
||||
else:
|
||||
if not handler.handle_simple(flatpak.set_default_remotes('system', user_password)):
|
||||
watcher.show_message(title=self.i18n['error'].capitalize(),
|
||||
body=self.i18n['flatpak.remotes.system_flathub.error'],
|
||||
type_=MessageType.ERROR)
|
||||
watcher.print("Operation cancelled")
|
||||
return False
|
||||
|
||||
if pkg.installation == 'user':
|
||||
if not handler.handle_simple(flatpak.register_flathub('user')):
|
||||
return False
|
||||
@@ -318,7 +339,7 @@ class FlatpakManager(SoftwareManager):
|
||||
loader.join()
|
||||
|
||||
for app in to_update:
|
||||
updates.append(PackageUpdate(pkg_id='{}:{}'.format(app.id, app.branch),
|
||||
updates.append(PackageUpdate(pkg_id='{}:{}:{}'.format(app.id, app.branch, app.installation),
|
||||
pkg_type='flatpak',
|
||||
version=app.version))
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ from io import StringIO
|
||||
from typing import List, Dict, Set
|
||||
|
||||
from bauh.api.exception import NoInternetException
|
||||
from bauh.commons.system import new_subprocess, run_cmd, new_root_subprocess, SimpleProcess
|
||||
from bauh.commons.system import new_subprocess, run_cmd, new_root_subprocess, SimpleProcess, SystemProcess
|
||||
|
||||
BASE_CMD = 'flatpak'
|
||||
RE_SEVERAL_SPACES = re.compile(r'\s+')
|
||||
@@ -343,8 +343,9 @@ def install(app_id: str, origin: str, installation: str):
|
||||
return new_subprocess([BASE_CMD, 'install', origin, app_id, '-y', '--{}'.format(installation)])
|
||||
|
||||
|
||||
def set_default_remotes(installation: str):
|
||||
run_cmd('{} remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo --{}'.format(BASE_CMD, installation))
|
||||
def set_default_remotes(installation: str, root_password: str = None) -> SimpleProcess:
|
||||
cmd = [BASE_CMD, 'remote-add', '--if-not-exists', 'flathub', 'https://flathub.org/repo/flathub.flatpakrepo', '--{}'.format(installation)]
|
||||
return SimpleProcess(cmd, root_password=root_password)
|
||||
|
||||
|
||||
def has_remotes_set() -> bool:
|
||||
|
||||
@@ -44,4 +44,5 @@ flatpak.info.translateurl=Traducció
|
||||
flatpak.info.developername=desenvolupador
|
||||
flatpak.install.install_level.title=Tipus d'instal·lació
|
||||
flatpak.install.install_level.body=S'ha d'instal·lar {} per a tots els usuaris del dispositiu ( sistema ) ?
|
||||
flatpak.install.bad_install_level.body=Valor invàlid per a {field} al fitxer de configuració {file}
|
||||
flatpak.install.bad_install_level.body=Valor invàlid per a {field} al fitxer de configuració {file}
|
||||
flatpak.remotes.system_flathub.error=No s'ha pogut afegir Flathub com a dipòsit del sistema ( remote )
|
||||
@@ -43,4 +43,5 @@ flatpak.history.date=Datum
|
||||
flatpak.history.commit=Commit
|
||||
flatpak.install.install_level.title=Installationstyp
|
||||
flatpak.install.install_level.body=Sollte {} für alle Gerätebenutzer installiert werden ( system ) ?
|
||||
flatpak.install.bad_install_level.body=Ungültiger Wert für {field} in der Konfigurationsdatei {file}
|
||||
flatpak.install.bad_install_level.body=Ungültiger Wert für {field} in der Konfigurationsdatei {file}
|
||||
flatpak.remotes.system_flathub.error=Flathub konnte nicht als System-Repository ( remote ) hinzugefügt werden
|
||||
@@ -43,4 +43,5 @@ flatpak.history.date=date
|
||||
flatpak.history.commit=commit
|
||||
flatpak.install.install_level.title=Installation type
|
||||
flatpak.install.install_level.body=Should {} be installed for all the device users ( system ) ?
|
||||
flatpak.install.bad_install_level.body=Invalid value for {field} in the configuration file {file}
|
||||
flatpak.install.bad_install_level.body=Invalid value for {field} in the configuration file {file}
|
||||
flatpak.remotes.system_flathub.error=It was not possible to add Flathub as a system repository ( remote )
|
||||
@@ -44,4 +44,5 @@ flatpak.info.translateurl=Traducción
|
||||
flatpak.info.developername=desarrollador
|
||||
flatpak.install.install_level.title=Tipo de instalación
|
||||
flatpak.install.install_level.body=¿Debería {} estar instalado para todos los usuarios del dispositivo ( sistema )?
|
||||
flatpak.install.bad_install_level.body=Valor inválido para {field} en el archivo de configuración {file}
|
||||
flatpak.install.bad_install_level.body=Valor inválido para {field} en el archivo de configuración {file}
|
||||
flatpak.remotes.system_flathub.error=No fue posible agregar Flathub como repositorio del sistema ( remote )
|
||||
@@ -23,4 +23,5 @@ flatpak.info.installation.user=utente
|
||||
flatpak.info.installation.system=sistema
|
||||
flatpak.install.install_level.title=Tipo di installazione
|
||||
flatpak.install.install_level.body={} deve essere installato per tutti gli utenti del dispositivo ( sistema ) ?
|
||||
flatpak.install.bad_install_level.body=Valore non valido per {field} nel file di configurazione {file}
|
||||
flatpak.install.bad_install_level.body=Valore non valido per {field} nel file di configurazione {file}
|
||||
flatpak.remotes.system_flathub.error=Non è stato possibile aggiungere Flathub come repository di sistema ( remote )
|
||||
@@ -44,4 +44,5 @@ flatpak.info.translateurl=tradução
|
||||
flatpak.info.developername=desenvolvedor
|
||||
flatpak.install.install_level.title=Tipo de instalação
|
||||
flatpak.install.install_level.body={} deve ser instalado para todos os usuários desse dispositivo ( sistema ) ?
|
||||
flatpak.install.bad_install_level.body=Valor inválido para {field} no arquivo de configuração {file}
|
||||
flatpak.install.bad_install_level.body=Valor inválido para {field} no arquivo de configuração {file}
|
||||
flatpak.remotes.system_flathub.error=Não foi possível adicionar o Flathub como um repositório do sistema ( remote )
|
||||
@@ -1,7 +1,7 @@
|
||||
import re
|
||||
import time
|
||||
from datetime import datetime, timedelta
|
||||
from typing import List, Type, Set
|
||||
from typing import List, Type, Set, Tuple
|
||||
|
||||
import requests
|
||||
from PyQt5.QtCore import QThread, pyqtSignal
|
||||
@@ -28,11 +28,13 @@ class AsyncAction(QThread, ProcessWatcher):
|
||||
signal_status = pyqtSignal(str) # changes the GUI status message
|
||||
signal_substatus = pyqtSignal(str) # changes the GUI substatus message
|
||||
signal_progress = pyqtSignal(int)
|
||||
signal_root_password = pyqtSignal()
|
||||
|
||||
def __init__(self):
|
||||
super(AsyncAction, self).__init__()
|
||||
self.wait_confirmation = False
|
||||
self.confirmation_res = None
|
||||
self.root_password = None
|
||||
self.stop = False
|
||||
|
||||
def request_confirmation(self, title: str, body: str, components: List[InputViewComponent] = None, confirmation_label: str = None, deny_label: str = None) -> bool:
|
||||
@@ -41,10 +43,22 @@ class AsyncAction(QThread, ProcessWatcher):
|
||||
self.wait_user()
|
||||
return self.confirmation_res
|
||||
|
||||
def request_root_password(self) -> Tuple[str, bool]:
|
||||
self.wait_confirmation = True
|
||||
self.signal_root_password.emit()
|
||||
self.wait_user()
|
||||
res = self.root_password
|
||||
self.root_password = None
|
||||
return res
|
||||
|
||||
def confirm(self, res: bool):
|
||||
self.confirmation_res = res
|
||||
self.wait_confirmation = False
|
||||
|
||||
def set_root_password(self, password: str, valid: bool):
|
||||
self.root_password = (password, valid)
|
||||
self.wait_confirmation = False
|
||||
|
||||
def wait_user(self):
|
||||
while self.wait_confirmation:
|
||||
time.sleep(0.01)
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import logging
|
||||
import operator
|
||||
import time
|
||||
from functools import reduce
|
||||
from pathlib import Path
|
||||
from typing import List, Type, Set
|
||||
|
||||
@@ -17,9 +15,10 @@ from bauh.api.abstract.controller import SoftwareManager
|
||||
from bauh.api.abstract.model import SoftwarePackage, PackageAction
|
||||
from bauh.api.abstract.view import MessageType
|
||||
from bauh.api.http import HttpClient
|
||||
from bauh.commons import user
|
||||
from bauh.commons.html import bold
|
||||
from bauh.view.core.controller import GenericSoftwareManager
|
||||
from bauh.view.qt import dialog, commons, qt_utils
|
||||
from bauh.view.qt import dialog, commons, qt_utils, root
|
||||
from bauh.view.qt.about import AboutDialog
|
||||
from bauh.view.qt.apps_table import AppsTable, UpdateToggleButton
|
||||
from bauh.view.qt.components import new_spacer, InputFilter, IconButton
|
||||
@@ -27,7 +26,7 @@ from bauh.view.qt.confirmation import ConfirmationDialog
|
||||
from bauh.view.qt.gem_selector import GemSelectorPanel
|
||||
from bauh.view.qt.history import HistoryDialog
|
||||
from bauh.view.qt.info import InfoDialog
|
||||
from bauh.view.qt.root import is_root, ask_root_password
|
||||
from bauh.view.qt.root import ask_root_password
|
||||
from bauh.view.qt.screenshots import ScreenshotsDialog
|
||||
from bauh.view.qt.styles import StylesComboBox
|
||||
from bauh.view.qt.thread import UpdateSelectedApps, RefreshApps, UninstallApp, DowngradeApp, GetAppInfo, \
|
||||
@@ -49,6 +48,7 @@ class ManageWindow(QWidget):
|
||||
__BASE_HEIGHT__ = 400
|
||||
|
||||
signal_user_res = pyqtSignal(bool)
|
||||
signal_root_password = pyqtSignal(str, bool)
|
||||
signal_table_update = pyqtSignal()
|
||||
|
||||
def __init__(self, i18n: I18n, icon_cache: MemoryCache, manager: SoftwareManager, screen_size, config: dict,
|
||||
@@ -396,8 +396,10 @@ class ManageWindow(QWidget):
|
||||
action.signal_status.connect(self._change_label_status)
|
||||
action.signal_substatus.connect(self._change_label_substatus)
|
||||
action.signal_progress.connect(self._update_process_progress)
|
||||
action.signal_root_password.connect(self._ask_root_password)
|
||||
|
||||
self.signal_user_res.connect(action.confirm)
|
||||
self.signal_root_password.connect(action.set_root_password)
|
||||
|
||||
return action
|
||||
|
||||
@@ -414,6 +416,12 @@ class ManageWindow(QWidget):
|
||||
self.thread_animate_progress.animate()
|
||||
self.signal_user_res.emit(res)
|
||||
|
||||
def _ask_root_password(self):
|
||||
self.thread_animate_progress.pause()
|
||||
password, valid = root.ask_root_password(self.i18n)
|
||||
self.thread_animate_progress.animate()
|
||||
self.signal_root_password.emit(password, valid)
|
||||
|
||||
def _show_message(self, msg: dict):
|
||||
self.thread_animate_progress.pause()
|
||||
dialog.show_message(title=msg['title'], body=msg['body'], type_=msg['type'])
|
||||
@@ -549,7 +557,7 @@ class ManageWindow(QWidget):
|
||||
pwd = None
|
||||
requires_root = self.manager.requires_root('uninstall', app.model)
|
||||
|
||||
if not is_root() and requires_root:
|
||||
if not user.is_root() and requires_root:
|
||||
pwd, ok = ask_root_password(self.i18n)
|
||||
|
||||
if not ok:
|
||||
@@ -865,7 +873,7 @@ class ManageWindow(QWidget):
|
||||
widgets=[UpdateToggleButton(None, self, self.i18n, clickable=False)]):
|
||||
pwd = None
|
||||
|
||||
if not is_root() and requires_root:
|
||||
if not user.is_root() and requires_root:
|
||||
pwd, ok = ask_root_password(self.i18n)
|
||||
|
||||
if not ok:
|
||||
@@ -983,7 +991,7 @@ class ManageWindow(QWidget):
|
||||
pwd = None
|
||||
requires_root = self.manager.requires_root('downgrade', pkgv.model)
|
||||
|
||||
if not is_root() and requires_root:
|
||||
if not user.is_root() and requires_root:
|
||||
pwd, ok = ask_root_password(self.i18n)
|
||||
|
||||
if not ok:
|
||||
@@ -1076,7 +1084,7 @@ class ManageWindow(QWidget):
|
||||
pwd = None
|
||||
requires_root = self.manager.requires_root('install', pkg.model)
|
||||
|
||||
if not is_root() and requires_root:
|
||||
if not user.is_root() and requires_root:
|
||||
pwd, ok = ask_root_password(self.i18n)
|
||||
|
||||
if not ok:
|
||||
@@ -1131,7 +1139,7 @@ class ManageWindow(QWidget):
|
||||
def execute_custom_action(self, pkg: PackageView, action: PackageAction):
|
||||
pwd = None
|
||||
|
||||
if not is_root() and action.requires_root:
|
||||
if not user.is_root() and action.requires_root:
|
||||
pwd, ok = ask_root_password(self.i18n)
|
||||
|
||||
if not ok:
|
||||
|
||||
Reference in New Issue
Block a user