mirror of
https://github.com/spalencsar/bearhub.git
synced 2026-07-07 18:34:16 +02:00
refactoring async work
This commit is contained in:
@@ -1,11 +1,9 @@
|
|||||||
import time
|
|
||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
from argparse import Namespace
|
from argparse import Namespace
|
||||||
from threading import Lock
|
|
||||||
from typing import List, Dict
|
from typing import List, Dict
|
||||||
|
|
||||||
from fpakman.core.disk import DiskCacheLoader, DiskCacheLoaderFactory
|
from fpakman.core.disk import DiskCacheLoader, DiskCacheLoaderFactory
|
||||||
from fpakman.core.model import Application
|
from fpakman.core.model import Application, ApplicationUpdate
|
||||||
from fpakman.core.system import FpakmanProcess
|
from fpakman.core.system import FpakmanProcess
|
||||||
|
|
||||||
|
|
||||||
@@ -82,6 +80,10 @@ class ApplicationManager(ABC):
|
|||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def list_updates(self) -> List[ApplicationUpdate]:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class GenericApplicationManager(ApplicationManager):
|
class GenericApplicationManager(ApplicationManager):
|
||||||
|
|
||||||
@@ -90,7 +92,6 @@ class GenericApplicationManager(ApplicationManager):
|
|||||||
self.managers = managers
|
self.managers = managers
|
||||||
self.map = {m.get_app_type(): m for m in self.managers}
|
self.map = {m.get_app_type(): m for m in self.managers}
|
||||||
self.disk_loader_factory = disk_loader_factory
|
self.disk_loader_factory = disk_loader_factory
|
||||||
self.lock_read = Lock()
|
|
||||||
self._enabled_map = {} if app_args.check_packaging_once else None
|
self._enabled_map = {} if app_args.check_packaging_once else None
|
||||||
self.prepare()
|
self.prepare()
|
||||||
|
|
||||||
@@ -131,57 +132,48 @@ class GenericApplicationManager(ApplicationManager):
|
|||||||
return man.is_enabled()
|
return man.is_enabled()
|
||||||
|
|
||||||
def search(self, word: str, disk_loader: DiskCacheLoader = None) -> Dict[str, List[Application]]:
|
def search(self, word: str, disk_loader: DiskCacheLoader = None) -> Dict[str, List[Application]]:
|
||||||
self.lock_read.acquire()
|
res = {'installed': [], 'new': []}
|
||||||
try:
|
|
||||||
res = {'installed': [], 'new': []}
|
|
||||||
|
|
||||||
norm_word = word.strip().lower()
|
norm_word = word.strip().lower()
|
||||||
disk_loader = None
|
disk_loader = None
|
||||||
|
|
||||||
for man in self.managers:
|
for man in self.managers:
|
||||||
if self._is_enabled(man):
|
if self._is_enabled(man):
|
||||||
if not disk_loader:
|
if not disk_loader:
|
||||||
disk_loader = self.disk_loader_factory.new()
|
disk_loader = self.disk_loader_factory.new()
|
||||||
disk_loader.start()
|
disk_loader.start()
|
||||||
|
|
||||||
apps_found = man.search(word=norm_word, disk_loader=disk_loader)
|
apps_found = man.search(word=norm_word, disk_loader=disk_loader)
|
||||||
res['installed'].extend(apps_found['installed'])
|
res['installed'].extend(apps_found['installed'])
|
||||||
res['new'].extend(apps_found['new'])
|
res['new'].extend(apps_found['new'])
|
||||||
|
|
||||||
disk_loader.stop = True
|
disk_loader.stop = True
|
||||||
disk_loader.join()
|
disk_loader.join()
|
||||||
|
|
||||||
for key in res:
|
for key in res:
|
||||||
res[key] = self._sort(res[key], norm_word)
|
res[key] = self._sort(res[key], norm_word)
|
||||||
|
|
||||||
return res
|
return res
|
||||||
finally:
|
|
||||||
self.lock_read.release()
|
|
||||||
|
|
||||||
def read_installed(self, disk_loader: DiskCacheLoader = None) -> List[Application]:
|
def read_installed(self, disk_loader: DiskCacheLoader = None) -> List[Application]:
|
||||||
self.lock_read.acquire()
|
installed = []
|
||||||
|
|
||||||
try:
|
disk_loader = None
|
||||||
installed = []
|
|
||||||
|
|
||||||
disk_loader = None
|
for man in self.managers:
|
||||||
|
if self._is_enabled(man):
|
||||||
|
if not disk_loader:
|
||||||
|
disk_loader = self.disk_loader_factory.new()
|
||||||
|
disk_loader.start()
|
||||||
|
|
||||||
for man in self.managers:
|
installed.extend(man.read_installed(disk_loader=disk_loader))
|
||||||
if self._is_enabled(man):
|
|
||||||
if not disk_loader:
|
|
||||||
disk_loader = self.disk_loader_factory.new()
|
|
||||||
disk_loader.start()
|
|
||||||
|
|
||||||
installed.extend(man.read_installed(disk_loader=disk_loader))
|
disk_loader.stop = True
|
||||||
|
disk_loader.join()
|
||||||
|
|
||||||
disk_loader.stop = True
|
installed.sort(key=lambda a: a.base_data.name.lower())
|
||||||
disk_loader.join()
|
|
||||||
|
|
||||||
installed.sort(key=lambda a: a.base_data.name.lower())
|
return installed
|
||||||
|
|
||||||
return installed
|
|
||||||
finally:
|
|
||||||
self.lock_read.release()
|
|
||||||
|
|
||||||
def can_downgrade(self):
|
def can_downgrade(self):
|
||||||
return True
|
return True
|
||||||
@@ -260,8 +252,17 @@ class GenericApplicationManager(ApplicationManager):
|
|||||||
return man.refresh(app, root_password)
|
return man.refresh(app, root_password)
|
||||||
|
|
||||||
def prepare(self):
|
def prepare(self):
|
||||||
|
|
||||||
if self.managers:
|
if self.managers:
|
||||||
for man in self.managers:
|
for man in self.managers:
|
||||||
if self._is_enabled(man):
|
if self._is_enabled(man):
|
||||||
man.prepare()
|
man.prepare()
|
||||||
|
|
||||||
|
def list_updates(self) -> List[ApplicationUpdate]:
|
||||||
|
updates = []
|
||||||
|
|
||||||
|
if self.managers:
|
||||||
|
for man in self.managers:
|
||||||
|
if self._is_enabled(man):
|
||||||
|
updates.extend(man.list_updates())
|
||||||
|
|
||||||
|
return updates
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ from fpakman.core.controller import ApplicationManager
|
|||||||
from fpakman.core.disk import DiskCacheLoader
|
from fpakman.core.disk import DiskCacheLoader
|
||||||
from fpakman.core.flatpak import flatpak
|
from fpakman.core.flatpak import flatpak
|
||||||
from fpakman.core.flatpak.model import FlatpakApplication
|
from fpakman.core.flatpak.model import FlatpakApplication
|
||||||
from fpakman.core.flatpak.worker import FlatpakAsyncDataLoader
|
from fpakman.core.flatpak.worker import FlatpakAsyncDataLoader, FlatpakUpdateLoader
|
||||||
from fpakman.core.model import ApplicationData
|
from fpakman.core.model import ApplicationData, ApplicationUpdate
|
||||||
from fpakman.core.system import FpakmanProcess
|
from fpakman.core.system import FpakmanProcess
|
||||||
from fpakman.util.cache import Cache
|
from fpakman.util.cache import Cache
|
||||||
|
|
||||||
@@ -148,3 +148,33 @@ class FlatpakManager(ApplicationManager):
|
|||||||
|
|
||||||
def prepare(self):
|
def prepare(self):
|
||||||
flatpak.set_default_remotes()
|
flatpak.set_default_remotes()
|
||||||
|
|
||||||
|
def list_updates(self) -> List[ApplicationUpdate]:
|
||||||
|
updates = []
|
||||||
|
installed = flatpak.list_installed(extra_fields=False)
|
||||||
|
|
||||||
|
if installed:
|
||||||
|
available_updates = flatpak.list_updates_as_str()
|
||||||
|
|
||||||
|
if available_updates:
|
||||||
|
loaders = None
|
||||||
|
|
||||||
|
for app_json in installed:
|
||||||
|
if app_json['id'] in available_updates:
|
||||||
|
loader = FlatpakUpdateLoader(app=app_json, http_session=self.http_session)
|
||||||
|
loader.start()
|
||||||
|
|
||||||
|
if loaders is None:
|
||||||
|
loaders = []
|
||||||
|
|
||||||
|
loaders.append(loader)
|
||||||
|
|
||||||
|
if loaders:
|
||||||
|
for loader in loaders:
|
||||||
|
loader.join()
|
||||||
|
app = loader.app
|
||||||
|
updates.append(ApplicationUpdate(app_id='{}:{}'.format(app['id'], app['branch']),
|
||||||
|
app_type='flatpak',
|
||||||
|
version=app.get('version')))
|
||||||
|
|
||||||
|
return updates
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import re
|
import re
|
||||||
import subprocess
|
import subprocess
|
||||||
from typing import List
|
from typing import List, Set
|
||||||
|
|
||||||
from fpakman.core import system
|
from fpakman.core import system
|
||||||
from fpakman.core.exception import NoInternetException
|
from fpakman.core.exception import NoInternetException
|
||||||
@@ -8,7 +8,7 @@ from fpakman.core.exception import NoInternetException
|
|||||||
BASE_CMD = 'flatpak'
|
BASE_CMD = 'flatpak'
|
||||||
|
|
||||||
|
|
||||||
def app_str_to_json(line: str, version: str) -> dict:
|
def app_str_to_json(line: str, version: str, extra_fields: bool = True) -> dict:
|
||||||
|
|
||||||
app_array = line.split('\t')
|
app_array = line.split('\t')
|
||||||
|
|
||||||
@@ -17,18 +17,21 @@ def app_str_to_json(line: str, version: str) -> dict:
|
|||||||
'id': app_array[1],
|
'id': app_array[1],
|
||||||
'version': app_array[2],
|
'version': app_array[2],
|
||||||
'branch': app_array[3]}
|
'branch': app_array[3]}
|
||||||
elif '1.0' <= version < '1.1':
|
|
||||||
app = {'ref': app_array[0], 'options': app_array[1]}
|
|
||||||
|
|
||||||
ref_data = app['ref'].split('/')
|
elif '1.0' <= version < '1.1':
|
||||||
app['id'] = ref_data[0]
|
|
||||||
app['arch'] = ref_data[1]
|
ref_data = app_array[0].split('/')
|
||||||
app['branch'] = ref_data[2]
|
|
||||||
app['name'] = ref_data[0].split('.')[-1]
|
app = {'id': ref_data[0],
|
||||||
app['version'] = None
|
'arch': ref_data[1],
|
||||||
|
'name': ref_data[0].split('.')[-1],
|
||||||
|
'ref': app_array[0],
|
||||||
|
'options': app_array[1],
|
||||||
|
'branch': ref_data[2],
|
||||||
|
'version': None}
|
||||||
elif '1.2' <= version < '1.3':
|
elif '1.2' <= version < '1.3':
|
||||||
app = {'name': app_array[1].strip().split('.')[-1],
|
app = {'id': app_array[1],
|
||||||
'id': app_array[1],
|
'name': app_array[1].strip().split('.')[-1],
|
||||||
'version': app_array[2],
|
'version': app_array[2],
|
||||||
'branch': app_array[3],
|
'branch': app_array[3],
|
||||||
'arch': app_array[4],
|
'arch': app_array[4],
|
||||||
@@ -36,8 +39,9 @@ def app_str_to_json(line: str, version: str) -> dict:
|
|||||||
else:
|
else:
|
||||||
raise Exception('Unsupported version')
|
raise Exception('Unsupported version')
|
||||||
|
|
||||||
extra_fields = get_app_info_fields(app['id'], app['branch'], ['origin', 'arch', 'ref', 'commit'], check_runtime=True)
|
if extra_fields:
|
||||||
app.update(extra_fields)
|
extra_fields = get_app_info_fields(app['id'], app['branch'], ['origin', 'arch', 'ref', 'commit'], check_runtime=True)
|
||||||
|
app.update(extra_fields)
|
||||||
|
|
||||||
return app
|
return app
|
||||||
|
|
||||||
@@ -81,13 +85,13 @@ def get_app_info(app_id: str, branch: str):
|
|||||||
return system.run_cmd('{} info {} {}'.format(BASE_CMD, app_id, branch))
|
return system.run_cmd('{} info {} {}'.format(BASE_CMD, app_id, branch))
|
||||||
|
|
||||||
|
|
||||||
def list_installed() -> List[dict]:
|
def list_installed(extra_fields: bool = True) -> List[dict]:
|
||||||
apps_str = system.run_cmd('{} list'.format(BASE_CMD))
|
apps_str = system.run_cmd('{} list'.format(BASE_CMD))
|
||||||
|
|
||||||
if apps_str:
|
if apps_str:
|
||||||
version = get_version()
|
version = get_version()
|
||||||
app_lines = apps_str.split('\n')
|
app_lines = apps_str.split('\n')
|
||||||
return [app_str_to_json(line, version) for line in app_lines if line]
|
return [app_str_to_json(line, version, extra_fields=extra_fields) for line in app_lines if line]
|
||||||
|
|
||||||
return []
|
return []
|
||||||
|
|
||||||
@@ -215,4 +219,3 @@ def install_and_stream(app_id: str, origin: str):
|
|||||||
|
|
||||||
def set_default_remotes():
|
def set_default_remotes():
|
||||||
system.run_cmd('flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo')
|
system.run_cmd('flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo')
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
import time
|
import time
|
||||||
import traceback
|
import traceback
|
||||||
|
from threading import Thread
|
||||||
|
|
||||||
from colorama import Fore
|
from colorama import Fore
|
||||||
|
|
||||||
from fpakman.core.controller import ApplicationManager
|
from fpakman.core.controller import ApplicationManager
|
||||||
|
from fpakman.core.flatpak import flatpak
|
||||||
from fpakman.core.flatpak.constants import FLATHUB_API_URL, FLATHUB_URL
|
from fpakman.core.flatpak.constants import FLATHUB_API_URL, FLATHUB_URL
|
||||||
from fpakman.core.flatpak.model import FlatpakApplication
|
from fpakman.core.flatpak.model import FlatpakApplication
|
||||||
from fpakman.core.model import ApplicationStatus
|
from fpakman.core.model import ApplicationStatus
|
||||||
@@ -82,3 +84,41 @@ class FlatpakAsyncDataLoader(AsyncDataLoader):
|
|||||||
http_session=self.http_session,
|
http_session=self.http_session,
|
||||||
timeout=self.timeout,
|
timeout=self.timeout,
|
||||||
app=self.app)
|
app=self.app)
|
||||||
|
|
||||||
|
|
||||||
|
class FlatpakUpdateLoader(Thread):
|
||||||
|
|
||||||
|
def __init__(self, app: dict, http_session, attempts: int = 2, timeout: int = 20):
|
||||||
|
super(FlatpakUpdateLoader, self).__init__(daemon=True)
|
||||||
|
self.app = app
|
||||||
|
self.http_session = http_session
|
||||||
|
self.attempts = attempts
|
||||||
|
self.timeout = timeout
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
|
||||||
|
if self.app.get('ref') is None:
|
||||||
|
self.app.update(flatpak.get_app_info_fields(self.app['id'], self.app['branch'], fields=['ref'], check_runtime=True))
|
||||||
|
else:
|
||||||
|
self.app['runtime'] = self.app['ref'].startswith('runtime/')
|
||||||
|
|
||||||
|
if not self.app['runtime']:
|
||||||
|
current_attempts = 0
|
||||||
|
|
||||||
|
while current_attempts < self.attempts:
|
||||||
|
|
||||||
|
current_attempts += 1
|
||||||
|
|
||||||
|
try:
|
||||||
|
res = self.http_session.get('{}/apps/{}'.format(FLATHUB_API_URL, self.app['id']), timeout=self.timeout)
|
||||||
|
|
||||||
|
if res.status_code == 200 and res.text:
|
||||||
|
data = res.json()
|
||||||
|
|
||||||
|
if data.get('currentReleaseVersion'):
|
||||||
|
self.app['version'] = data['currentReleaseVersion']
|
||||||
|
|
||||||
|
break
|
||||||
|
except:
|
||||||
|
traceback.print_exc()
|
||||||
|
time.sleep(0.5)
|
||||||
|
|||||||
@@ -86,3 +86,14 @@ class Application(ABC):
|
|||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return '{} (id={}, name={})'.format(self.__class__.__name__, self.base_data.id, self.base_data.name)
|
return '{} (id={}, name={})'.format(self.__class__.__name__, self.base_data.id, self.base_data.name)
|
||||||
|
|
||||||
|
|
||||||
|
class ApplicationUpdate:
|
||||||
|
|
||||||
|
def __init__(self, app_id: str, version: str, app_type: str):
|
||||||
|
self.id = app_id
|
||||||
|
self.version = version
|
||||||
|
self.type = app_type
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return '{} (id={}, type={}, new_version={})'.format(self.__class__.__name__, self.id, self.type, self.type)
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ from typing import Dict, List
|
|||||||
from fpakman.core import disk
|
from fpakman.core import disk
|
||||||
from fpakman.core.controller import ApplicationManager
|
from fpakman.core.controller import ApplicationManager
|
||||||
from fpakman.core.disk import DiskCacheLoader
|
from fpakman.core.disk import DiskCacheLoader
|
||||||
from fpakman.core.model import ApplicationData, Application
|
from fpakman.core.model import ApplicationData, Application, ApplicationUpdate
|
||||||
from fpakman.core.snap import snap
|
from fpakman.core.snap import snap
|
||||||
from fpakman.core.snap.model import SnapApplication
|
from fpakman.core.snap.model import SnapApplication
|
||||||
from fpakman.core.snap.worker import SnapAsyncDataLoader
|
from fpakman.core.snap.worker import SnapAsyncDataLoader
|
||||||
@@ -131,3 +131,6 @@ class SnapManager(ApplicationManager):
|
|||||||
|
|
||||||
def prepare(self):
|
def prepare(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def list_updates(self) -> List[ApplicationUpdate]:
|
||||||
|
return []
|
||||||
|
|||||||
@@ -119,9 +119,6 @@ class AppsTable(QTableWidget):
|
|||||||
menu_row.exec_()
|
menu_row.exec_()
|
||||||
|
|
||||||
def fill_async_data(self):
|
def fill_async_data(self):
|
||||||
|
|
||||||
self.lock_async_data.acquire()
|
|
||||||
|
|
||||||
if self.window.apps:
|
if self.window.apps:
|
||||||
|
|
||||||
for idx, app_v in enumerate(self.window.apps):
|
for idx, app_v in enumerate(self.window.apps):
|
||||||
@@ -142,8 +139,6 @@ class AppsTable(QTableWidget):
|
|||||||
|
|
||||||
self.window.resize_and_center()
|
self.window.resize_and_center()
|
||||||
|
|
||||||
self.lock_async_data.release()
|
|
||||||
|
|
||||||
def get_selected_app(self) -> ApplicationView:
|
def get_selected_app(self) -> ApplicationView:
|
||||||
return self.window.apps[self.currentRow()]
|
return self.window.apps[self.currentRow()]
|
||||||
|
|
||||||
@@ -202,9 +197,9 @@ class AppsTable(QTableWidget):
|
|||||||
if not icon_was_cached or not os.path.exists(app.model.get_disk_icon_path()):
|
if not icon_was_cached or not os.path.exists(app.model.get_disk_icon_path()):
|
||||||
self.window.manager.cache_to_disk(app=app.model, icon_bytes=icon_data['bytes'], only_icon=True)
|
self.window.manager.cache_to_disk(app=app.model, icon_bytes=icon_data['bytes'], only_icon=True)
|
||||||
|
|
||||||
def update_apps(self, app_views: List[ApplicationView]):
|
def update_apps(self, app_views: List[ApplicationView], update_check_enabled: bool = True):
|
||||||
self.setEnabled(True)
|
|
||||||
self.setRowCount(len(app_views) if app_views else 0)
|
self.setRowCount(len(app_views) if app_views else 0)
|
||||||
|
self.setEnabled(True)
|
||||||
|
|
||||||
if app_views:
|
if app_views:
|
||||||
for idx, app_v in enumerate(app_views):
|
for idx, app_v in enumerate(app_views):
|
||||||
@@ -214,7 +209,11 @@ class AppsTable(QTableWidget):
|
|||||||
self._set_col_type(idx, app_v)
|
self._set_col_type(idx, app_v)
|
||||||
self._set_col_installed(idx, app_v)
|
self._set_col_installed(idx, app_v)
|
||||||
|
|
||||||
col_update = UpdateToggleButton(app_v, self.window, self.window.locale_keys, app_v.model.update) if app_v.model.update else None
|
col_update = None
|
||||||
|
|
||||||
|
if update_check_enabled and app_v.model.update:
|
||||||
|
col_update = UpdateToggleButton(app_v, self.window, self.window.locale_keys, app_v.model.update)
|
||||||
|
|
||||||
self.setCellWidget(idx, 5, col_update)
|
self.setCellWidget(idx, 5, col_update)
|
||||||
|
|
||||||
def _set_col_installed(self, idx: int, app_v: ApplicationView):
|
def _set_col_installed(self, idx: int, app_v: ApplicationView):
|
||||||
|
|||||||
@@ -6,9 +6,10 @@ from PyQt5.QtCore import QThread, pyqtSignal, QCoreApplication, Qt, QSize
|
|||||||
from PyQt5.QtGui import QIcon
|
from PyQt5.QtGui import QIcon
|
||||||
from PyQt5.QtWidgets import QSystemTrayIcon, QMenu
|
from PyQt5.QtWidgets import QSystemTrayIcon, QMenu
|
||||||
|
|
||||||
|
from fpakman import __app_name__
|
||||||
from fpakman.core import resource, system
|
from fpakman.core import resource, system
|
||||||
from fpakman.core.controller import ApplicationManager
|
from fpakman.core.controller import ApplicationManager
|
||||||
from fpakman.core.model import Application
|
from fpakman.core.model import ApplicationUpdate
|
||||||
from fpakman.util.cache import Cache
|
from fpakman.util.cache import Cache
|
||||||
from fpakman.view.qt.about import AboutDialog
|
from fpakman.view.qt.about import AboutDialog
|
||||||
from fpakman.view.qt.window import ManageWindow
|
from fpakman.view.qt.window import ManageWindow
|
||||||
@@ -27,9 +28,7 @@ class UpdateCheck(QThread):
|
|||||||
|
|
||||||
while True:
|
while True:
|
||||||
|
|
||||||
apps = self.manager.read_installed()
|
updates = self.manager.list_updates()
|
||||||
|
|
||||||
updates = [app for app in apps if app.update]
|
|
||||||
|
|
||||||
if updates:
|
if updates:
|
||||||
self.signal.emit(updates)
|
self.signal.emit(updates)
|
||||||
@@ -66,30 +65,32 @@ class TrayIcon(QSystemTrayIcon):
|
|||||||
self.setContextMenu(self.menu)
|
self.setContextMenu(self.menu)
|
||||||
|
|
||||||
self.manage_window = None
|
self.manage_window = None
|
||||||
|
self.dialog_about = None
|
||||||
self.check_thread = UpdateCheck(check_interval=check_interval, manager=self.manager)
|
self.check_thread = UpdateCheck(check_interval=check_interval, manager=self.manager)
|
||||||
self.check_thread.signal.connect(self.notify_updates)
|
self.check_thread.signal.connect(self.notify_updates)
|
||||||
self.check_thread.start()
|
self.check_thread.start()
|
||||||
|
|
||||||
self.dialog_about = None
|
|
||||||
|
|
||||||
self.last_updates = set()
|
self.last_updates = set()
|
||||||
self.update_notification = update_notification
|
self.update_notification = update_notification
|
||||||
self.lock_notify = Lock()
|
self.lock_notify = Lock()
|
||||||
|
|
||||||
self.activated.connect(self.handle_click)
|
self.activated.connect(self.handle_click)
|
||||||
|
self.set_default_tooltip()
|
||||||
|
|
||||||
|
def set_default_tooltip(self):
|
||||||
|
self.setToolTip('{} ({})'.format(self.locale_keys['manage_window.title'], __app_name__))
|
||||||
|
|
||||||
def handle_click(self, reason):
|
def handle_click(self, reason):
|
||||||
if reason == self.Trigger:
|
if reason == self.Trigger:
|
||||||
self.show_manage_window()
|
self.show_manage_window()
|
||||||
|
|
||||||
def notify_updates(self, updates: List[Application]):
|
def notify_updates(self, updates: List[ApplicationUpdate]):
|
||||||
|
|
||||||
self.lock_notify.acquire()
|
self.lock_notify.acquire()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if len(updates) > 0:
|
if len(updates) > 0:
|
||||||
|
update_keys = {'{}:{}:{}'.format(up.type, up.id, up.version) for up in updates}
|
||||||
update_keys = {'{}:{}'.format(app.base_data.id, app.base_data.version) for app in updates}
|
|
||||||
|
|
||||||
new_icon = self.icon_update
|
new_icon = self.icon_update
|
||||||
|
|
||||||
@@ -103,7 +104,7 @@ class TrayIcon(QSystemTrayIcon):
|
|||||||
|
|
||||||
else:
|
else:
|
||||||
new_icon = self.icon_default
|
new_icon = self.icon_default
|
||||||
self.setToolTip(None)
|
self.set_default_tooltip()
|
||||||
|
|
||||||
if self.icon().cacheKey() != new_icon.cacheKey(): # changes the icon if needed
|
if self.icon().cacheKey() != new_icon.cacheKey(): # changes the icon if needed
|
||||||
self.setIcon(new_icon)
|
self.setIcon(new_icon)
|
||||||
|
|||||||
@@ -302,6 +302,8 @@ class VerifyModels(QThread):
|
|||||||
if stop_at <= datetime.utcnow():
|
if stop_at <= datetime.utcnow():
|
||||||
break
|
break
|
||||||
|
|
||||||
|
time.sleep(0.1)
|
||||||
|
|
||||||
self.apps = None
|
self.apps = None
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import operator
|
import operator
|
||||||
from functools import reduce
|
from functools import reduce
|
||||||
from threading import Lock
|
|
||||||
from typing import List, Set
|
from typing import List, Set
|
||||||
|
|
||||||
from PyQt5.QtCore import QEvent, Qt
|
from PyQt5.QtCore import QEvent, Qt
|
||||||
@@ -31,7 +30,6 @@ class ManageWindow(QWidget):
|
|||||||
self.locale_keys = locale_keys
|
self.locale_keys = locale_keys
|
||||||
self.manager = manager
|
self.manager = manager
|
||||||
self.tray_icon = tray_icon
|
self.tray_icon = tray_icon
|
||||||
self.thread_lock = Lock()
|
|
||||||
self.working = False # restrict the number of threaded actions
|
self.working = False # restrict the number of threaded actions
|
||||||
self.apps = []
|
self.apps = []
|
||||||
self.label_flatpak = None
|
self.label_flatpak = None
|
||||||
@@ -42,7 +40,6 @@ class ManageWindow(QWidget):
|
|||||||
|
|
||||||
self.icon_flathub = QIcon(resource.get_path('img/logo.svg'))
|
self.icon_flathub = QIcon(resource.get_path('img/logo.svg'))
|
||||||
self.resize(ManageWindow.__BASE_HEIGHT__, ManageWindow.__BASE_HEIGHT__)
|
self.resize(ManageWindow.__BASE_HEIGHT__, ManageWindow.__BASE_HEIGHT__)
|
||||||
self.setWindowTitle(locale_keys['manage_window.title'])
|
|
||||||
self.setWindowIcon(self.icon_flathub)
|
self.setWindowIcon(self.icon_flathub)
|
||||||
|
|
||||||
self.layout = QVBoxLayout()
|
self.layout = QVBoxLayout()
|
||||||
@@ -111,7 +108,7 @@ class ManageWindow(QWidget):
|
|||||||
self.bt_upgrade.setIcon(QIcon(resource.get_path('img/update_green.svg')))
|
self.bt_upgrade.setIcon(QIcon(resource.get_path('img/update_green.svg')))
|
||||||
self.bt_upgrade.setEnabled(False)
|
self.bt_upgrade.setEnabled(False)
|
||||||
self.bt_upgrade.clicked.connect(self.update_selected)
|
self.bt_upgrade.clicked.connect(self.update_selected)
|
||||||
toolbar.addWidget(self.bt_upgrade)
|
self.ref_bt_upgrade = toolbar.addWidget(self.bt_upgrade)
|
||||||
|
|
||||||
self.layout.addWidget(toolbar)
|
self.layout.addWidget(toolbar)
|
||||||
|
|
||||||
@@ -235,25 +232,6 @@ class ManageWindow(QWidget):
|
|||||||
self.hide()
|
self.hide()
|
||||||
self._handle_console_option(False)
|
self._handle_console_option(False)
|
||||||
|
|
||||||
def _acquire_lock(self):
|
|
||||||
|
|
||||||
self.thread_lock.acquire()
|
|
||||||
|
|
||||||
if not self.working:
|
|
||||||
self.working = True
|
|
||||||
|
|
||||||
self.thread_lock.release()
|
|
||||||
return self.working
|
|
||||||
|
|
||||||
def _release_lock(self):
|
|
||||||
|
|
||||||
self.thread_lock.acquire()
|
|
||||||
|
|
||||||
if self.working:
|
|
||||||
self.working = False
|
|
||||||
|
|
||||||
self.thread_lock.release()
|
|
||||||
|
|
||||||
def _handle_console(self, checked: bool):
|
def _handle_console(self, checked: bool):
|
||||||
|
|
||||||
if checked:
|
if checked:
|
||||||
@@ -271,69 +249,59 @@ class ManageWindow(QWidget):
|
|||||||
self.textarea_output.hide()
|
self.textarea_output.hide()
|
||||||
|
|
||||||
def refresh_apps(self, keep_console: bool = True):
|
def refresh_apps(self, keep_console: bool = True):
|
||||||
|
self.filter_types.clear()
|
||||||
|
self.input_search.clear()
|
||||||
|
|
||||||
if self._acquire_lock():
|
if not keep_console:
|
||||||
self.filter_types.clear()
|
self._handle_console_option(False)
|
||||||
self.input_search.clear()
|
|
||||||
|
|
||||||
if not keep_console:
|
self.ref_checkbox_updates.setVisible(False)
|
||||||
self._handle_console_option(False)
|
self.ref_checkbox_only_apps.setVisible(False)
|
||||||
|
self._begin_action(self.locale_keys['manage_window.status.refreshing'], clear_filters=True)
|
||||||
self.ref_checkbox_updates.setVisible(False)
|
self.thread_refresh.start()
|
||||||
self.ref_checkbox_only_apps.setVisible(False)
|
|
||||||
self._begin_action(self.locale_keys['manage_window.status.refreshing'], clear_filters=True)
|
|
||||||
|
|
||||||
self.thread_refresh.start()
|
|
||||||
|
|
||||||
def _finish_refresh_apps(self, apps: List[Application]):
|
def _finish_refresh_apps(self, apps: List[Application]):
|
||||||
self.update_apps(apps)
|
self.update_apps(apps)
|
||||||
self.finish_action()
|
self.finish_action()
|
||||||
self.ref_checkbox_only_apps.setVisible(True)
|
self.ref_checkbox_only_apps.setVisible(True)
|
||||||
self._release_lock()
|
self.ref_bt_upgrade.setVisible(True)
|
||||||
|
|
||||||
def uninstall_app(self, app: ApplicationView):
|
def uninstall_app(self, app: ApplicationView):
|
||||||
if self._acquire_lock():
|
pwd = None
|
||||||
|
requires_root = self.manager.requires_root('uninstall', self.table_apps.get_selected_app().model)
|
||||||
|
|
||||||
pwd = None
|
if not is_root() and requires_root:
|
||||||
requires_root = self.manager.requires_root('uninstall', self.table_apps.get_selected_app().model)
|
pwd, ok = ask_root_password(self.locale_keys)
|
||||||
|
|
||||||
if not is_root() and requires_root:
|
if not ok:
|
||||||
pwd, ok = ask_root_password(self.locale_keys)
|
return
|
||||||
|
|
||||||
if not ok:
|
self._handle_console_option(True)
|
||||||
self._release_lock()
|
self._begin_action('{} {}'.format(self.locale_keys['manage_window.status.uninstalling'], app.model.base_data.name))
|
||||||
return
|
|
||||||
|
|
||||||
self._handle_console_option(True)
|
self.thread_uninstall.app = app
|
||||||
self._begin_action('{} {}'.format(self.locale_keys['manage_window.status.uninstalling'], app.model.base_data.name))
|
self.thread_uninstall.root_password = pwd
|
||||||
|
self.thread_uninstall.start()
|
||||||
self.thread_uninstall.app = app
|
|
||||||
self.thread_uninstall.root_password = pwd
|
|
||||||
self.thread_uninstall.start()
|
|
||||||
|
|
||||||
def refresh(self, app: ApplicationView):
|
def refresh(self, app: ApplicationView):
|
||||||
if self._acquire_lock():
|
pwd = None
|
||||||
|
requires_root = self.manager.requires_root('refresh', self.table_apps.get_selected_app().model)
|
||||||
|
|
||||||
pwd = None
|
if not is_root() and requires_root:
|
||||||
requires_root = self.manager.requires_root('refresh', self.table_apps.get_selected_app().model)
|
pwd, ok = ask_root_password(self.locale_keys)
|
||||||
|
|
||||||
if not is_root() and requires_root:
|
if not ok:
|
||||||
pwd, ok = ask_root_password(self.locale_keys)
|
return
|
||||||
|
|
||||||
if not ok:
|
self._handle_console_option(True)
|
||||||
self._release_lock()
|
self._begin_action('{} {}'.format(self.locale_keys['manage_window.status.refreshing'], app.model.base_data.name))
|
||||||
return
|
|
||||||
|
|
||||||
self._handle_console_option(True)
|
self.thread_refresh_app.app = app
|
||||||
self._begin_action('{} {}'.format(self.locale_keys['manage_window.status.refreshing'], app.model.base_data.name))
|
self.thread_refresh_app.root_password = pwd
|
||||||
|
self.thread_refresh_app.start()
|
||||||
self.thread_refresh_app.app = app
|
|
||||||
self.thread_refresh_app.root_password = pwd
|
|
||||||
self.thread_refresh_app.start()
|
|
||||||
|
|
||||||
def _finish_uninstall(self, success: bool):
|
def _finish_uninstall(self, success: bool):
|
||||||
self.finish_action()
|
self.finish_action()
|
||||||
self._release_lock()
|
|
||||||
|
|
||||||
if success:
|
if success:
|
||||||
if self._can_notify_user():
|
if self._can_notify_user():
|
||||||
@@ -353,7 +321,6 @@ class ManageWindow(QWidget):
|
|||||||
|
|
||||||
def _finish_downgrade(self, success: bool):
|
def _finish_downgrade(self, success: bool):
|
||||||
self.finish_action()
|
self.finish_action()
|
||||||
self._release_lock()
|
|
||||||
|
|
||||||
if success:
|
if success:
|
||||||
if self._can_notify_user():
|
if self._can_notify_user():
|
||||||
@@ -365,17 +332,16 @@ class ManageWindow(QWidget):
|
|||||||
if self._can_notify_user():
|
if self._can_notify_user():
|
||||||
system.notify_user(self.locale_keys['notification.downgrade.failed'])
|
system.notify_user(self.locale_keys['notification.downgrade.failed'])
|
||||||
|
|
||||||
self.change_update_state(notify_tray=False)
|
self.change_update_state()
|
||||||
self.checkbox_console.setChecked(True)
|
self.checkbox_console.setChecked(True)
|
||||||
|
|
||||||
def _finish_refresh(self, success: bool):
|
def _finish_refresh(self, success: bool):
|
||||||
self.finish_action()
|
self.finish_action()
|
||||||
self._release_lock()
|
|
||||||
|
|
||||||
if success:
|
if success:
|
||||||
self.refresh_apps()
|
self.refresh_apps()
|
||||||
else:
|
else:
|
||||||
self.change_update_state(notify_tray=False)
|
self.change_update_state()
|
||||||
self.checkbox_console.setChecked(True)
|
self.checkbox_console.setChecked(True)
|
||||||
|
|
||||||
def apply_filters(self):
|
def apply_filters(self):
|
||||||
@@ -399,11 +365,9 @@ class ManageWindow(QWidget):
|
|||||||
self.table_apps.change_headers_policy()
|
self.table_apps.change_headers_policy()
|
||||||
self.resize_and_center(accept_lower_width=visible_apps > 0)
|
self.resize_and_center(accept_lower_width=visible_apps > 0)
|
||||||
|
|
||||||
def change_update_state(self, notify_tray: bool = True, change_filters: bool = True):
|
def change_update_state(self, change_filters: bool = True):
|
||||||
|
|
||||||
enable_bt_update = False
|
enable_bt_update = False
|
||||||
|
app_updates, library_updates, not_installed = 0, 0, 0
|
||||||
app_updates, library_updates = 0, 0
|
|
||||||
|
|
||||||
for app_v in self.apps:
|
for app_v in self.apps:
|
||||||
if app_v.model.update:
|
if app_v.model.update:
|
||||||
@@ -412,28 +376,33 @@ class ManageWindow(QWidget):
|
|||||||
else:
|
else:
|
||||||
app_updates += 1
|
app_updates += 1
|
||||||
|
|
||||||
|
if not app_v.model.installed:
|
||||||
|
not_installed += 1
|
||||||
|
|
||||||
for app_v in self.apps:
|
for app_v in self.apps:
|
||||||
if app_v.visible and app_v.update_checked:
|
if not_installed == 0 and app_v.visible and app_v.update_checked:
|
||||||
enable_bt_update = True
|
enable_bt_update = True
|
||||||
break
|
break
|
||||||
|
|
||||||
self.bt_upgrade.setEnabled(enable_bt_update)
|
self.bt_upgrade.setEnabled(enable_bt_update)
|
||||||
|
|
||||||
total_updates = app_updates + library_updates
|
total_updates = app_updates + library_updates
|
||||||
|
|
||||||
if total_updates > 0:
|
if total_updates > 0:
|
||||||
self.label_updates.setPixmap(QPixmap(resource.get_path('img/exclamation.svg')).scaled(16, 16, Qt.KeepAspectRatio, Qt.SmoothTransformation))
|
self.label_updates.setPixmap(QPixmap(resource.get_path('img/exclamation.svg')).scaled(16, 16, Qt.KeepAspectRatio, Qt.SmoothTransformation))
|
||||||
self.label_updates.setToolTip('{}: {} ( {} {} | {} {} )'.format(self.locale_keys['manage_window.label.updates'],
|
self.label_updates.setToolTip('{}: {} ( {} {} | {} {} )'.format(self.locale_keys['manage_window.label.updates'],
|
||||||
total_updates,
|
total_updates,
|
||||||
app_updates,
|
app_updates,
|
||||||
self.locale_keys['manage_window.checkbox.only_apps'].lower(),
|
self.locale_keys['manage_window.checkbox.only_apps'].lower(),
|
||||||
library_updates,
|
library_updates,
|
||||||
self.locale_keys['others'].lower()))
|
self.locale_keys['others'].lower()))
|
||||||
|
|
||||||
if not self.ref_checkbox_updates.isVisible():
|
if not_installed == 0:
|
||||||
self.ref_checkbox_updates.setVisible(True)
|
if not self.ref_checkbox_updates.isVisible():
|
||||||
|
self.ref_checkbox_updates.setVisible(True)
|
||||||
|
|
||||||
if change_filters and not self.checkbox_updates.isChecked():
|
if change_filters and not self.checkbox_updates.isChecked():
|
||||||
self.checkbox_updates.setChecked(True)
|
self.checkbox_updates.setChecked(True)
|
||||||
|
|
||||||
if change_filters and library_updates > 0 and self.checkbox_only_apps.isChecked():
|
if change_filters and library_updates > 0 and self.checkbox_only_apps.isChecked():
|
||||||
self.checkbox_only_apps.setChecked(False)
|
self.checkbox_only_apps.setChecked(False)
|
||||||
@@ -442,9 +411,6 @@ class ManageWindow(QWidget):
|
|||||||
self.ref_checkbox_updates.setVisible(False)
|
self.ref_checkbox_updates.setVisible(False)
|
||||||
self.label_updates.setPixmap(QPixmap())
|
self.label_updates.setPixmap(QPixmap())
|
||||||
|
|
||||||
if notify_tray:
|
|
||||||
self.tray_icon.notify_updates([app.model for app in self.apps if app.model.update])
|
|
||||||
|
|
||||||
def centralize(self):
|
def centralize(self):
|
||||||
geo = self.frameGeometry()
|
geo = self.frameGeometry()
|
||||||
screen = QApplication.desktop().screenNumber(QApplication.desktop().cursor().pos())
|
screen = QApplication.desktop().screenNumber(QApplication.desktop().cursor().pos())
|
||||||
@@ -452,7 +418,7 @@ class ManageWindow(QWidget):
|
|||||||
geo.moveCenter(center_point)
|
geo.moveCenter(center_point)
|
||||||
self.move(geo.topLeft())
|
self.move(geo.topLeft())
|
||||||
|
|
||||||
def update_apps(self, apps: List[Application]):
|
def update_apps(self, apps: List[Application], update_check_enabled: bool = True):
|
||||||
self.apps = []
|
self.apps = []
|
||||||
|
|
||||||
napps = 0 # number of apps (not libraries)
|
napps = 0 # number of apps (not libraries)
|
||||||
@@ -473,7 +439,7 @@ class ManageWindow(QWidget):
|
|||||||
self.checkbox_only_apps.setChecked(True)
|
self.checkbox_only_apps.setChecked(True)
|
||||||
|
|
||||||
self._update_type_filters(available_types)
|
self._update_type_filters(available_types)
|
||||||
self.table_apps.update_apps(self.apps)
|
self.table_apps.update_apps(self.apps, update_check_enabled=update_check_enabled)
|
||||||
self.apply_filters()
|
self.apply_filters()
|
||||||
self.change_update_state()
|
self.change_update_state()
|
||||||
self.resize_and_center()
|
self.resize_and_center()
|
||||||
@@ -510,22 +476,19 @@ class ManageWindow(QWidget):
|
|||||||
self.centralize()
|
self.centralize()
|
||||||
|
|
||||||
def update_selected(self):
|
def update_selected(self):
|
||||||
|
if self.apps:
|
||||||
|
|
||||||
if self._acquire_lock():
|
to_update = [app_v for app_v in self.apps if app_v.visible and app_v.update_checked]
|
||||||
if self.apps:
|
|
||||||
|
|
||||||
to_update = [app_v for app_v in self.apps if app_v.visible and app_v.update_checked]
|
if to_update:
|
||||||
|
self._handle_console_option(True)
|
||||||
|
|
||||||
if to_update:
|
self._begin_action(self.locale_keys['manage_window.status.upgrading'])
|
||||||
self._handle_console_option(True)
|
self.thread_update.apps_to_update = to_update
|
||||||
|
self.thread_update.start()
|
||||||
self._begin_action(self.locale_keys['manage_window.status.upgrading'])
|
|
||||||
self.thread_update.apps_to_update = to_update
|
|
||||||
self.thread_update.start()
|
|
||||||
|
|
||||||
def _finish_update_selected(self, success: bool, updated: int):
|
def _finish_update_selected(self, success: bool, updated: int):
|
||||||
self.finish_action()
|
self.finish_action()
|
||||||
self._release_lock()
|
|
||||||
|
|
||||||
if success:
|
if success:
|
||||||
if self._can_notify_user():
|
if self._can_notify_user():
|
||||||
@@ -581,51 +544,43 @@ class ManageWindow(QWidget):
|
|||||||
self.checkbox_updates.setEnabled(True)
|
self.checkbox_updates.setEnabled(True)
|
||||||
|
|
||||||
def downgrade_app(self, app: ApplicationView):
|
def downgrade_app(self, app: ApplicationView):
|
||||||
if self._acquire_lock():
|
pwd = None
|
||||||
|
requires_root = self.manager.requires_root('downgrade', self.table_apps.get_selected_app().model)
|
||||||
|
|
||||||
pwd = None
|
if not is_root() and requires_root:
|
||||||
requires_root = self.manager.requires_root('downgrade', self.table_apps.get_selected_app().model)
|
pwd, ok = ask_root_password(self.locale_keys)
|
||||||
|
|
||||||
if not is_root() and requires_root:
|
if not ok:
|
||||||
pwd, ok = ask_root_password(self.locale_keys)
|
return
|
||||||
|
|
||||||
if not ok:
|
self._handle_console_option(True)
|
||||||
self._release_lock()
|
self._begin_action('{} {}'.format(self.locale_keys['manage_window.status.downgrading'], app.model.base_data.name))
|
||||||
return
|
|
||||||
|
|
||||||
self._handle_console_option(True)
|
self.thread_downgrade.app = app
|
||||||
self._begin_action('{} {}'.format(self.locale_keys['manage_window.status.downgrading'], app.model.base_data.name))
|
self.thread_downgrade.root_password = pwd
|
||||||
|
self.thread_downgrade.start()
|
||||||
self.thread_downgrade.app = app
|
|
||||||
self.thread_downgrade.root_password = pwd
|
|
||||||
self.thread_downgrade.start()
|
|
||||||
|
|
||||||
def get_app_info(self, app: dict):
|
def get_app_info(self, app: dict):
|
||||||
|
self._handle_console_option(False)
|
||||||
|
self._begin_action(self.locale_keys['manage_window.status.info'])
|
||||||
|
|
||||||
if self._acquire_lock():
|
self.thread_get_info.app = app
|
||||||
self._handle_console_option(False)
|
self.thread_get_info.start()
|
||||||
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):
|
def get_app_history(self, app: dict):
|
||||||
if self._acquire_lock():
|
self._handle_console_option(False)
|
||||||
self._handle_console_option(False)
|
self._begin_action(self.locale_keys['manage_window.status.history'])
|
||||||
self._begin_action(self.locale_keys['manage_window.status.history'])
|
|
||||||
|
|
||||||
self.thread_get_history.app = app
|
self.thread_get_history.app = app
|
||||||
self.thread_get_history.start()
|
self.thread_get_history.start()
|
||||||
|
|
||||||
def _finish_get_info(self, app_info: dict):
|
def _finish_get_info(self, app_info: dict):
|
||||||
self._release_lock()
|
|
||||||
self.finish_action()
|
self.finish_action()
|
||||||
self.change_update_state()
|
self.change_update_state()
|
||||||
dialog_info = InfoDialog(app_info, self.table_apps.get_selected_app_icon(), self.locale_keys, self.table_apps.get_selected_app().model.get_type(), self.screen_size)
|
dialog_info = InfoDialog(app_info, self.table_apps.get_selected_app_icon(), self.locale_keys, self.table_apps.get_selected_app().model.get_type(), self.screen_size)
|
||||||
dialog_info.exec_()
|
dialog_info.exec_()
|
||||||
|
|
||||||
def _finish_get_history(self, app: dict):
|
def _finish_get_history(self, app: dict):
|
||||||
self._release_lock()
|
|
||||||
self.finish_action()
|
self.finish_action()
|
||||||
self.change_update_state()
|
self.change_update_state()
|
||||||
|
|
||||||
@@ -641,7 +596,7 @@ class ManageWindow(QWidget):
|
|||||||
|
|
||||||
word = self.input_search.text().strip()
|
word = self.input_search.text().strip()
|
||||||
|
|
||||||
if word and self._acquire_lock():
|
if word:
|
||||||
self._handle_console_option(False)
|
self._handle_console_option(False)
|
||||||
self.ref_checkbox_only_apps.setVisible(False)
|
self.ref_checkbox_only_apps.setVisible(False)
|
||||||
self.ref_checkbox_updates.setVisible(False)
|
self.ref_checkbox_updates.setVisible(False)
|
||||||
@@ -651,34 +606,30 @@ class ManageWindow(QWidget):
|
|||||||
self.thread_search.start()
|
self.thread_search.start()
|
||||||
|
|
||||||
def _finish_search(self, apps_found: List[Application]):
|
def _finish_search(self, apps_found: List[Application]):
|
||||||
self._release_lock()
|
|
||||||
self.finish_action()
|
self.finish_action()
|
||||||
self.update_apps(apps_found)
|
self.ref_bt_upgrade.setVisible(False)
|
||||||
|
self.update_apps(apps_found, update_check_enabled=False)
|
||||||
|
|
||||||
def install_app(self, app: ApplicationView):
|
def install_app(self, app: ApplicationView):
|
||||||
if self._acquire_lock():
|
pwd = None
|
||||||
|
requires_root = self.manager.requires_root('install', self.table_apps.get_selected_app().model)
|
||||||
|
|
||||||
pwd = None
|
if not is_root() and requires_root:
|
||||||
requires_root = self.manager.requires_root('install', self.table_apps.get_selected_app().model)
|
pwd, ok = ask_root_password(self.locale_keys)
|
||||||
|
|
||||||
if not is_root() and requires_root:
|
if not ok:
|
||||||
pwd, ok = ask_root_password(self.locale_keys)
|
return
|
||||||
|
|
||||||
if not ok:
|
self._handle_console_option(True)
|
||||||
self._release_lock()
|
self._begin_action('{} {}'.format(self.locale_keys['manage_window.status.installing'], app.model.base_data.name))
|
||||||
return
|
|
||||||
|
|
||||||
self._handle_console_option(True)
|
self.thread_install.app = app
|
||||||
self._begin_action('{} {}'.format(self.locale_keys['manage_window.status.installing'], app.model.base_data.name))
|
self.thread_install.root_password = pwd
|
||||||
|
self.thread_install.start()
|
||||||
self.thread_install.app = app
|
|
||||||
self.thread_install.root_password = pwd
|
|
||||||
self.thread_install.start()
|
|
||||||
|
|
||||||
def _finish_install(self, success: bool):
|
def _finish_install(self, success: bool):
|
||||||
self.input_search.setText('')
|
self.input_search.setText('')
|
||||||
self.finish_action()
|
self.finish_action()
|
||||||
self._release_lock()
|
|
||||||
|
|
||||||
if success:
|
if success:
|
||||||
if self._can_notify_user():
|
if self._can_notify_user():
|
||||||
|
|||||||
Reference in New Issue
Block a user