mirror of
https://github.com/spalencsar/bearhub.git
synced 2026-07-07 01:14: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
|
from bauh.api.abstract.view import MessageType, ViewComponent
|
||||||
|
|
||||||
@@ -65,3 +65,9 @@ class ProcessWatcher:
|
|||||||
"""
|
"""
|
||||||
:return: if the use requested to stop the process.
|
: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
|
import urllib3
|
||||||
from PyQt5.QtCore import Qt
|
from PyQt5.QtCore import Qt
|
||||||
from PyQt5.QtGui import QIcon
|
|
||||||
from PyQt5.QtWidgets import QApplication
|
from PyQt5.QtWidgets import QApplication
|
||||||
|
|
||||||
from bauh import __version__, __app_name__, app_args, ROOT_DIR
|
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.core.downloader import AdaptableFileDownloader
|
||||||
from bauh.view.qt.systray import TrayIcon
|
from bauh.view.qt.systray import TrayIcon
|
||||||
from bauh.view.qt.window import ManageWindow
|
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.cache import DefaultMemoryCacheFactory, CacheCleaner
|
||||||
from bauh.view.util.disk import DefaultDiskCacheLoaderFactory
|
from bauh.view.util.disk import DefaultDiskCacheLoaderFactory
|
||||||
from bauh.view.util.translation import I18n
|
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, \
|
from bauh.api.abstract.model import PackageHistory, PackageUpdate, SoftwarePackage, PackageSuggestion, \
|
||||||
SuggestionPriority
|
SuggestionPriority
|
||||||
from bauh.api.abstract.view import MessageType
|
from bauh.api.abstract.view import MessageType
|
||||||
|
from bauh.commons import user
|
||||||
from bauh.commons.html import strip_html, bold
|
from bauh.commons.html import strip_html, bold
|
||||||
from bauh.commons.system import SystemProcess, ProcessHandler, SimpleProcess
|
from bauh.commons.system import SystemProcess, ProcessHandler, SimpleProcess
|
||||||
from bauh.gems.flatpak import flatpak, SUGGESTIONS_FILE, CONFIG_FILE
|
from bauh.gems.flatpak import flatpak, SUGGESTIONS_FILE, CONFIG_FILE
|
||||||
@@ -67,7 +68,7 @@ class FlatpakManager(SoftwareManager):
|
|||||||
remote_level = 'user'
|
remote_level = 'user'
|
||||||
else:
|
else:
|
||||||
remote_level = 'user'
|
remote_level = 'user'
|
||||||
flatpak.set_default_remotes(remote_level)
|
ProcessHandler().handle_simple(flatpak.set_default_remotes(remote_level))
|
||||||
|
|
||||||
return remote_level
|
return remote_level
|
||||||
|
|
||||||
@@ -264,8 +265,28 @@ class FlatpakManager(SoftwareManager):
|
|||||||
deny_label=self.i18n['yes'].capitalize())
|
deny_label=self.i18n['yes'].capitalize())
|
||||||
pkg.installation = 'user' if user_level else 'system'
|
pkg.installation = 'user' if user_level else 'system'
|
||||||
|
|
||||||
|
remotes = flatpak.list_remotes()
|
||||||
|
|
||||||
handler = ProcessHandler(watcher)
|
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 pkg.installation == 'user':
|
||||||
if not handler.handle_simple(flatpak.register_flathub('user')):
|
if not handler.handle_simple(flatpak.register_flathub('user')):
|
||||||
return False
|
return False
|
||||||
@@ -318,7 +339,7 @@ class FlatpakManager(SoftwareManager):
|
|||||||
loader.join()
|
loader.join()
|
||||||
|
|
||||||
for app in to_update:
|
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',
|
pkg_type='flatpak',
|
||||||
version=app.version))
|
version=app.version))
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ from io import StringIO
|
|||||||
from typing import List, Dict, Set
|
from typing import List, Dict, Set
|
||||||
|
|
||||||
from bauh.api.exception import NoInternetException
|
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'
|
BASE_CMD = 'flatpak'
|
||||||
RE_SEVERAL_SPACES = re.compile(r'\s+')
|
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)])
|
return new_subprocess([BASE_CMD, 'install', origin, app_id, '-y', '--{}'.format(installation)])
|
||||||
|
|
||||||
|
|
||||||
def set_default_remotes(installation: str):
|
def set_default_remotes(installation: str, root_password: str = None) -> SimpleProcess:
|
||||||
run_cmd('{} remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo --{}'.format(BASE_CMD, installation))
|
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:
|
def has_remotes_set() -> bool:
|
||||||
|
|||||||
@@ -44,4 +44,5 @@ flatpak.info.translateurl=Traducció
|
|||||||
flatpak.info.developername=desenvolupador
|
flatpak.info.developername=desenvolupador
|
||||||
flatpak.install.install_level.title=Tipus d'instal·lació
|
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.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.history.commit=Commit
|
||||||
flatpak.install.install_level.title=Installationstyp
|
flatpak.install.install_level.title=Installationstyp
|
||||||
flatpak.install.install_level.body=Sollte {} für alle Gerätebenutzer installiert werden ( system ) ?
|
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.history.commit=commit
|
||||||
flatpak.install.install_level.title=Installation type
|
flatpak.install.install_level.title=Installation type
|
||||||
flatpak.install.install_level.body=Should {} be installed for all the device users ( system ) ?
|
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.info.developername=desarrollador
|
||||||
flatpak.install.install_level.title=Tipo de instalación
|
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.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.info.installation.system=sistema
|
||||||
flatpak.install.install_level.title=Tipo di installazione
|
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.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.info.developername=desenvolvedor
|
||||||
flatpak.install.install_level.title=Tipo de instalação
|
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.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 re
|
||||||
import time
|
import time
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from typing import List, Type, Set
|
from typing import List, Type, Set, Tuple
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
from PyQt5.QtCore import QThread, pyqtSignal
|
from PyQt5.QtCore import QThread, pyqtSignal
|
||||||
@@ -28,11 +28,13 @@ class AsyncAction(QThread, ProcessWatcher):
|
|||||||
signal_status = pyqtSignal(str) # changes the GUI status message
|
signal_status = pyqtSignal(str) # changes the GUI status message
|
||||||
signal_substatus = pyqtSignal(str) # changes the GUI substatus message
|
signal_substatus = pyqtSignal(str) # changes the GUI substatus message
|
||||||
signal_progress = pyqtSignal(int)
|
signal_progress = pyqtSignal(int)
|
||||||
|
signal_root_password = pyqtSignal()
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(AsyncAction, self).__init__()
|
super(AsyncAction, self).__init__()
|
||||||
self.wait_confirmation = False
|
self.wait_confirmation = False
|
||||||
self.confirmation_res = None
|
self.confirmation_res = None
|
||||||
|
self.root_password = None
|
||||||
self.stop = False
|
self.stop = False
|
||||||
|
|
||||||
def request_confirmation(self, title: str, body: str, components: List[InputViewComponent] = None, confirmation_label: str = None, deny_label: str = None) -> bool:
|
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()
|
self.wait_user()
|
||||||
return self.confirmation_res
|
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):
|
def confirm(self, res: bool):
|
||||||
self.confirmation_res = res
|
self.confirmation_res = res
|
||||||
self.wait_confirmation = False
|
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):
|
def wait_user(self):
|
||||||
while self.wait_confirmation:
|
while self.wait_confirmation:
|
||||||
time.sleep(0.01)
|
time.sleep(0.01)
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
import logging
|
import logging
|
||||||
import operator
|
|
||||||
import time
|
import time
|
||||||
from functools import reduce
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import List, Type, Set
|
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.model import SoftwarePackage, PackageAction
|
||||||
from bauh.api.abstract.view import MessageType
|
from bauh.api.abstract.view import MessageType
|
||||||
from bauh.api.http import HttpClient
|
from bauh.api.http import HttpClient
|
||||||
|
from bauh.commons import user
|
||||||
from bauh.commons.html import bold
|
from bauh.commons.html import bold
|
||||||
from bauh.view.core.controller import GenericSoftwareManager
|
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.about import AboutDialog
|
||||||
from bauh.view.qt.apps_table import AppsTable, UpdateToggleButton
|
from bauh.view.qt.apps_table import AppsTable, UpdateToggleButton
|
||||||
from bauh.view.qt.components import new_spacer, InputFilter, IconButton
|
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.gem_selector import GemSelectorPanel
|
||||||
from bauh.view.qt.history import HistoryDialog
|
from bauh.view.qt.history import HistoryDialog
|
||||||
from bauh.view.qt.info import InfoDialog
|
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.screenshots import ScreenshotsDialog
|
||||||
from bauh.view.qt.styles import StylesComboBox
|
from bauh.view.qt.styles import StylesComboBox
|
||||||
from bauh.view.qt.thread import UpdateSelectedApps, RefreshApps, UninstallApp, DowngradeApp, GetAppInfo, \
|
from bauh.view.qt.thread import UpdateSelectedApps, RefreshApps, UninstallApp, DowngradeApp, GetAppInfo, \
|
||||||
@@ -49,6 +48,7 @@ class ManageWindow(QWidget):
|
|||||||
__BASE_HEIGHT__ = 400
|
__BASE_HEIGHT__ = 400
|
||||||
|
|
||||||
signal_user_res = pyqtSignal(bool)
|
signal_user_res = pyqtSignal(bool)
|
||||||
|
signal_root_password = pyqtSignal(str, bool)
|
||||||
signal_table_update = pyqtSignal()
|
signal_table_update = pyqtSignal()
|
||||||
|
|
||||||
def __init__(self, i18n: I18n, icon_cache: MemoryCache, manager: SoftwareManager, screen_size, config: dict,
|
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_status.connect(self._change_label_status)
|
||||||
action.signal_substatus.connect(self._change_label_substatus)
|
action.signal_substatus.connect(self._change_label_substatus)
|
||||||
action.signal_progress.connect(self._update_process_progress)
|
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_user_res.connect(action.confirm)
|
||||||
|
self.signal_root_password.connect(action.set_root_password)
|
||||||
|
|
||||||
return action
|
return action
|
||||||
|
|
||||||
@@ -414,6 +416,12 @@ class ManageWindow(QWidget):
|
|||||||
self.thread_animate_progress.animate()
|
self.thread_animate_progress.animate()
|
||||||
self.signal_user_res.emit(res)
|
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):
|
def _show_message(self, msg: dict):
|
||||||
self.thread_animate_progress.pause()
|
self.thread_animate_progress.pause()
|
||||||
dialog.show_message(title=msg['title'], body=msg['body'], type_=msg['type'])
|
dialog.show_message(title=msg['title'], body=msg['body'], type_=msg['type'])
|
||||||
@@ -549,7 +557,7 @@ class ManageWindow(QWidget):
|
|||||||
pwd = None
|
pwd = None
|
||||||
requires_root = self.manager.requires_root('uninstall', app.model)
|
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)
|
pwd, ok = ask_root_password(self.i18n)
|
||||||
|
|
||||||
if not ok:
|
if not ok:
|
||||||
@@ -865,7 +873,7 @@ class ManageWindow(QWidget):
|
|||||||
widgets=[UpdateToggleButton(None, self, self.i18n, clickable=False)]):
|
widgets=[UpdateToggleButton(None, self, self.i18n, clickable=False)]):
|
||||||
pwd = None
|
pwd = None
|
||||||
|
|
||||||
if not is_root() and requires_root:
|
if not user.is_root() and requires_root:
|
||||||
pwd, ok = ask_root_password(self.i18n)
|
pwd, ok = ask_root_password(self.i18n)
|
||||||
|
|
||||||
if not ok:
|
if not ok:
|
||||||
@@ -983,7 +991,7 @@ class ManageWindow(QWidget):
|
|||||||
pwd = None
|
pwd = None
|
||||||
requires_root = self.manager.requires_root('downgrade', pkgv.model)
|
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)
|
pwd, ok = ask_root_password(self.i18n)
|
||||||
|
|
||||||
if not ok:
|
if not ok:
|
||||||
@@ -1076,7 +1084,7 @@ class ManageWindow(QWidget):
|
|||||||
pwd = None
|
pwd = None
|
||||||
requires_root = self.manager.requires_root('install', pkg.model)
|
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)
|
pwd, ok = ask_root_password(self.i18n)
|
||||||
|
|
||||||
if not ok:
|
if not ok:
|
||||||
@@ -1131,7 +1139,7 @@ class ManageWindow(QWidget):
|
|||||||
def execute_custom_action(self, pkg: PackageView, action: PackageAction):
|
def execute_custom_action(self, pkg: PackageView, action: PackageAction):
|
||||||
pwd = None
|
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)
|
pwd, ok = ask_root_password(self.i18n)
|
||||||
|
|
||||||
if not ok:
|
if not ok:
|
||||||
|
|||||||
Reference in New Issue
Block a user