mirror of
https://github.com/spalencsar/bearhub.git
synced 2026-07-06 22:54:16 +02:00
0.5.1
This commit is contained in:
10
CHANGELOG.md
10
CHANGELOG.md
@@ -4,6 +4,16 @@ All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||
|
||||
## [0.5.1] - 2019-08-09
|
||||
### Improvements:
|
||||
- suggestions are now retrieved asynchronously taking 45% less time.
|
||||
- search response takes an average of 20% less time ( reaching 35% for several results )
|
||||
- app boot takes 98% less time when snapd is installed, but disabled
|
||||
- FPAKMAN_TRAY (--tray) is not enabled by default (0).
|
||||
### Fixes
|
||||
- not showing correctly the latest flatpak app versions when bringing the search results
|
||||
- [flatpak dependency](https://github.com/vinifmor/fpakman/issues/36)
|
||||
|
||||
## [0.5.0] - 2019-08-06
|
||||
### Improvements
|
||||
- search results sorting takes an average of 35% less time, reaching 60% in some scenarios
|
||||
|
||||
@@ -52,7 +52,7 @@ You can change some application settings via environment variables or arguments
|
||||
- **FPAKMAN_FLATPAK**: enables / disables flatpak usage. Use **0** (disable) or **1** (enabled, default)
|
||||
- **FPAKMAN_SNAP**: enables / disables snap usage. Use **0** (disable) or **1** (enabled, default)
|
||||
- **FPAKMAN_CHECK_PACKAGING_ONCE**: If the available supported packaging types should be checked ONLY once. It improves the application speed if enabled, but can generate errors if you uninstall any packaging technology while using it, and every time a supported packaging type is installed it will only be available after a restart. Use **0** (disable, default) or **1** (enable).
|
||||
- **FPAKMAN_TRAY**: If the tray icon and update-check daemon should be created. Use **0** (disable) or **1** (enable, default).
|
||||
- **FPAKMAN_TRAY**: If the tray icon and update-check daemon should be created. Use **0** (disable, default) or **1** (enable).
|
||||
- **FPAKMAN_SUGGESTIONS**: If application suggestions should be displayed if no app is installed (runtimes do not count as apps). Use **0** (disable) or **1** (enable, default).
|
||||
|
||||
### How to improve the application performance
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# Generates a .desktop file based on the current python version. Used for AUR installation
|
||||
import os
|
||||
import sys
|
||||
|
||||
desktop_file = """
|
||||
@@ -7,11 +8,15 @@ Type = Application
|
||||
Name = fpakman
|
||||
Categories = System;
|
||||
Comment = Manage your Flatpak / Snap applications
|
||||
Exec = /usr/bin/fpakman --tray=0
|
||||
Icon = /usr/lib/python{version}/site-packages/fpakman/resources/img/logo.svg
|
||||
Exec = {path}
|
||||
Icon = {lib_path}/python{version}/site-packages/fpakman/resources/img/logo.svg
|
||||
"""
|
||||
|
||||
py_version = "{}.{}".format(sys.version_info.major, sys.version_info.minor)
|
||||
|
||||
fpakman_cmd = os.getenv('FPAKMAN_PATH', '/usr/bin/fpakman')
|
||||
|
||||
with open('fpakman.desktop', 'w+') as f:
|
||||
f.write(desktop_file.format(version=py_version))
|
||||
f.write(desktop_file.format(lib_path=os.getenv('FPAKMAN_LIB_PATH', '/usr/lib'),
|
||||
version=py_version,
|
||||
path=fpakman_cmd))
|
||||
|
||||
@@ -1,17 +1,26 @@
|
||||
# Generates a .desktop file based on the current python version. Used for AUR installation
|
||||
import os
|
||||
import sys
|
||||
|
||||
desktop_file = """
|
||||
[Desktop Entry]
|
||||
Type = Application
|
||||
Name = fpakman ( tray )
|
||||
Name = fpakman (tray)
|
||||
Categories = System;
|
||||
Comment = Manage your Flatpak / Snap applications
|
||||
Exec = /usr/bin/fpakman
|
||||
Icon = /usr/lib/python{version}/site-packages/fpakman/resources/img/logo.svg
|
||||
Exec = {path}
|
||||
Icon = {lib_path}/python{version}/site-packages/fpakman/resources/img/logo.svg
|
||||
"""
|
||||
|
||||
py_version = "{}.{}".format(sys.version_info.major, sys.version_info.minor)
|
||||
|
||||
fpakman_cmd = os.getenv('FPAKMAN_PATH', '/usr/bin/fpakman') + ' --tray=1'
|
||||
|
||||
with open('fpakman_tray.desktop', 'w+') as f:
|
||||
f.write(desktop_file.format(version=py_version))
|
||||
f.write(desktop_file.format(lib_path=os.getenv('FPAKMAN_LIB_PATH', '/usr/lib'),
|
||||
version=py_version,
|
||||
path=fpakman_cmd))
|
||||
|
||||
|
||||
with open('fpakman-tray', 'w') as f:
|
||||
f.write(fpakman_cmd)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
__version__ = '0.5.0'
|
||||
__version__ = '0.5.1'
|
||||
__app_name__ = 'fpakman'
|
||||
|
||||
import os
|
||||
|
||||
@@ -21,7 +21,6 @@ from fpakman.core.snap.model import SnapApplication
|
||||
from fpakman.util import util
|
||||
from fpakman.util.cache import Cache
|
||||
from fpakman.util.memory import CacheCleaner
|
||||
from fpakman.view.qt import dialog
|
||||
from fpakman.view.qt.systray import TrayIcon
|
||||
from fpakman.view.qt.window import ManageWindow
|
||||
|
||||
@@ -46,7 +45,7 @@ parser.add_argument('-di', '--download-icons', action="store", choices=[0, 1], d
|
||||
parser.add_argument('--flatpak', action="store", default=os.getenv('FPAKMAN_FLATPAK', 1), choices=[0, 1], type=int, help='Enables / disables flatpak usage. Default: %(default)s')
|
||||
parser.add_argument('--snap', action="store", default=os.getenv('FPAKMAN_SNAP', 1), choices=[0, 1], type=int, help='Enables / disables snap usage. Default: %(default)s')
|
||||
parser.add_argument('-co', '--check-packaging-once', action="store", default=os.getenv('FPAKMAN_CHECK_PACKAGING_ONCE', 0), choices=[0, 1], type=int, help='If the available supported packaging types should be checked ONLY once. It improves the application speed if enabled, but can generate errors if you uninstall any packaging technology while using it, and every time a supported packaging type is installed it will only be available after a restart. Default: %(default)s')
|
||||
parser.add_argument('--tray', action="store", default=os.getenv('FPAKMAN_TRAY', 1), choices=[0, 1], type=int, help='If the tray icon and update-check daemon should be created. Default: %(default)s')
|
||||
parser.add_argument('--tray', action="store", default=os.getenv('FPAKMAN_TRAY', 0), choices=[0, 1], type=int, help='If the tray icon and update-check daemon should be created. Default: %(default)s')
|
||||
parser.add_argument('--sugs', action="store", default=os.getenv('FPAKMAN_SUGGESTIONS', 1), choices=[0, 1], type=int, help='If app suggestions should be displayed if no app is installed (runtimes do not count as apps). Default: %(default)s')
|
||||
args = parser.parse_args()
|
||||
|
||||
@@ -135,18 +134,11 @@ if args.tray:
|
||||
manage_window=manage_window,
|
||||
check_interval=args.check_interval,
|
||||
update_notification=bool(args.update_notification))
|
||||
|
||||
manage_window.tray_icon = trayIcon
|
||||
trayIcon.show()
|
||||
else:
|
||||
manage_window.refresh_apps()
|
||||
manage_window.show()
|
||||
|
||||
warnings = manager.list_warnings()
|
||||
|
||||
if warnings:
|
||||
for warning in warnings:
|
||||
dialog.show_warning(title=locale_keys['warning'].capitalize(), body=warning)
|
||||
|
||||
CacheCleaner(caches).start()
|
||||
sys.exit(app.exec_())
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import time
|
||||
from abc import ABC, abstractmethod
|
||||
from argparse import Namespace
|
||||
from threading import Thread
|
||||
from typing import List, Dict
|
||||
|
||||
from fpakman.core.disk import DiskCacheLoader, DiskCacheLoaderFactory
|
||||
@@ -103,6 +103,12 @@ class GenericApplicationManager(ApplicationManager):
|
||||
self.map = {m.get_app_type(): m for m in self.managers}
|
||||
self.disk_loader_factory = disk_loader_factory
|
||||
self._enabled_map = {} if app_args.check_packaging_once else None
|
||||
self.thread_prepare = None
|
||||
|
||||
def _wait_to_be_ready(self):
|
||||
if self.thread_prepare:
|
||||
self.thread_prepare.join()
|
||||
self.thread_prepare = None
|
||||
|
||||
def _sort(self, apps: List[Application], word: str) -> List[Application]:
|
||||
exact_name_matches, contains_name_matches, others = [], [], []
|
||||
@@ -125,7 +131,6 @@ class GenericApplicationManager(ApplicationManager):
|
||||
return res
|
||||
|
||||
def _is_enabled(self, man: ApplicationManager):
|
||||
|
||||
if self._enabled_map is not None:
|
||||
enabled = self._enabled_map.get(man.get_app_type())
|
||||
|
||||
@@ -137,21 +142,30 @@ class GenericApplicationManager(ApplicationManager):
|
||||
else:
|
||||
return man.is_enabled()
|
||||
|
||||
def _search(self, word: str, man: ApplicationManager, disk_loader, res: dict):
|
||||
if self._is_enabled(man):
|
||||
apps_found = man.search(word=word, disk_loader=disk_loader)
|
||||
res['installed'].extend(apps_found['installed'])
|
||||
res['new'].extend(apps_found['new'])
|
||||
|
||||
def search(self, word: str, disk_loader: DiskCacheLoader = None) -> Dict[str, List[Application]]:
|
||||
self._wait_to_be_ready()
|
||||
|
||||
res = {'installed': [], 'new': []}
|
||||
|
||||
norm_word = word.strip().lower()
|
||||
disk_loader = None
|
||||
disk_loader = self.disk_loader_factory.new()
|
||||
disk_loader.start()
|
||||
|
||||
threads = []
|
||||
|
||||
for man in self.managers:
|
||||
if self._is_enabled(man):
|
||||
if not disk_loader:
|
||||
disk_loader = self.disk_loader_factory.new()
|
||||
disk_loader.start()
|
||||
t = Thread(target=self._search, args=(norm_word, man, disk_loader, res))
|
||||
t.start()
|
||||
threads.append(t)
|
||||
|
||||
apps_found = man.search(word=norm_word, disk_loader=disk_loader)
|
||||
res['installed'].extend(apps_found['installed'])
|
||||
res['new'].extend(apps_found['new'])
|
||||
for t in threads:
|
||||
t.join()
|
||||
|
||||
if disk_loader:
|
||||
disk_loader.stop = True
|
||||
@@ -163,6 +177,8 @@ class GenericApplicationManager(ApplicationManager):
|
||||
return res
|
||||
|
||||
def read_installed(self, disk_loader: DiskCacheLoader = None) -> List[Application]:
|
||||
self._wait_to_be_ready()
|
||||
|
||||
installed = []
|
||||
|
||||
disk_loader = None
|
||||
@@ -254,18 +270,26 @@ class GenericApplicationManager(ApplicationManager):
|
||||
return man.requires_root(action, app)
|
||||
|
||||
def refresh(self, app: Application, root_password: str) -> FpakmanProcess:
|
||||
self._wait_to_be_ready()
|
||||
|
||||
man = self._get_manager_for(app)
|
||||
|
||||
if man:
|
||||
return man.refresh(app, root_password)
|
||||
|
||||
def prepare(self):
|
||||
def _prepare(self):
|
||||
if self.managers:
|
||||
for man in self.managers:
|
||||
if self._is_enabled(man):
|
||||
man.prepare()
|
||||
|
||||
def prepare(self):
|
||||
self.thread_prepare = Thread(target=self._prepare)
|
||||
self.thread_prepare.start()
|
||||
|
||||
def list_updates(self) -> List[ApplicationUpdate]:
|
||||
self._wait_to_be_ready()
|
||||
|
||||
updates = []
|
||||
|
||||
if self.managers:
|
||||
@@ -290,10 +314,22 @@ class GenericApplicationManager(ApplicationManager):
|
||||
|
||||
return warnings
|
||||
|
||||
def _fill_suggestions(self, suggestions: list, man: ApplicationManager, limit: int):
|
||||
if self._is_enabled(man):
|
||||
man_sugs = man.list_suggestions(limit)
|
||||
|
||||
if man_sugs:
|
||||
suggestions.extend(man_sugs)
|
||||
|
||||
def list_suggestions(self, limit: int) -> List[Application]:
|
||||
if self.managers:
|
||||
suggestions = []
|
||||
suggestions, threads = [], []
|
||||
for man in self.managers:
|
||||
if self._is_enabled(man):
|
||||
suggestions.extend(man.list_suggestions(6))
|
||||
t = Thread(target=self._fill_suggestions, args=(suggestions, man, 6))
|
||||
t.start()
|
||||
threads.append(t)
|
||||
|
||||
for t in threads:
|
||||
t.join()
|
||||
|
||||
return suggestions
|
||||
|
||||
@@ -181,8 +181,9 @@ class FlatpakManager(ApplicationManager):
|
||||
return updates
|
||||
|
||||
def list_warnings(self) -> List[str]:
|
||||
if not flatpak.has_remotes_set():
|
||||
return [self.locale_keys['flatpak.notification.no_remotes']]
|
||||
if flatpak.is_installed():
|
||||
if not flatpak.has_remotes_set():
|
||||
return [self.locale_keys['flatpak.notification.no_remotes']]
|
||||
|
||||
def list_suggestions(self, limit: int) -> List[FlatpakApplication]:
|
||||
|
||||
|
||||
@@ -48,6 +48,9 @@ class FlatpakAsyncDataLoader(AsyncDataLoader):
|
||||
if not self.app.base_data.version and self.app.base_data.latest_version:
|
||||
self.app.base_data.version = self.app.base_data.latest_version
|
||||
|
||||
if not self.app.installed and self.app.base_data.latest_version:
|
||||
self.app.base_data.version = self.app.base_data.latest_version
|
||||
|
||||
if self.app.base_data.icon_url and self.app.base_data.icon_url.startswith('/'):
|
||||
self.app.base_data.icon_url = FLATHUB_URL + self.app.base_data.icon_url
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ from threading import Thread
|
||||
from typing import List
|
||||
|
||||
from fpakman.util.cache import Cache
|
||||
import gc
|
||||
|
||||
|
||||
class CacheCleaner(Thread):
|
||||
@@ -20,6 +19,5 @@ class CacheCleaner(Thread):
|
||||
for cache in self.caches:
|
||||
cache.clean_expired()
|
||||
|
||||
gc.collect()
|
||||
time.sleep(self.check_interval)
|
||||
|
||||
|
||||
@@ -315,7 +315,7 @@ class AppsTable(QTableWidget):
|
||||
label_version.setStyleSheet("color: #4EC306; font-weight: bold")
|
||||
tooltip = self.window.locale_keys['version.installed_outdated']
|
||||
|
||||
if app_v.model.base_data.version and app_v.model.base_data.latest_version and app_v.model.base_data.version < app_v.model.base_data.latest_version:
|
||||
if app_v.model.installed and app_v.model.base_data.version and app_v.model.base_data.latest_version and app_v.model.base_data.version < app_v.model.base_data.latest_version:
|
||||
tooltip = '{}. {}: {}'.format(tooltip, self.window.locale_keys['version.latest'], app_v.model.base_data.latest_version)
|
||||
label_version.setText(label_version.text() + ' > {}'.format(app_v.model.base_data.latest_version))
|
||||
|
||||
|
||||
@@ -347,4 +347,18 @@ class FindSuggestions(AsyncAction):
|
||||
|
||||
def run(self):
|
||||
self.signal_finished.emit(self.man.list_suggestions(limit=-1))
|
||||
|
||||
|
||||
|
||||
class ListWarnings(QThread):
|
||||
|
||||
signal_warnings = pyqtSignal(list)
|
||||
|
||||
def __init__(self, man: ApplicationManager, locale_keys: dict):
|
||||
super(QThread, self).__init__()
|
||||
self.locale_keys = locale_keys
|
||||
self.man = man
|
||||
|
||||
def run(self):
|
||||
warnings = self.man.list_warnings()
|
||||
if warnings:
|
||||
self.signal_warnings.emit(warnings)
|
||||
|
||||
@@ -18,7 +18,7 @@ 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
|
||||
from fpakman.view.qt.thread import UpdateSelectedApps, RefreshApps, UninstallApp, DowngradeApp, GetAppInfo, \
|
||||
GetAppHistory, SearchApps, InstallApp, AnimateProgress, VerifyModels, RefreshApp, FindSuggestions
|
||||
GetAppHistory, SearchApps, InstallApp, AnimateProgress, VerifyModels, RefreshApp, FindSuggestions, ListWarnings
|
||||
from fpakman.view.qt.view_model import ApplicationView
|
||||
|
||||
DARK_ORANGE = '#FF4500'
|
||||
@@ -213,6 +213,19 @@ class ManageWindow(QWidget):
|
||||
self.dialog_about = None
|
||||
self.first_refresh = suggestions
|
||||
|
||||
self.thread_warnings = ListWarnings(man=manager, locale_keys=locale_keys)
|
||||
self.thread_warnings.signal_warnings.connect(self._show_warnings)
|
||||
|
||||
def _show_warnings(self, warnings: List[str]):
|
||||
if warnings:
|
||||
for warning in warnings:
|
||||
dialog.show_warning(title=self.locale_keys['warning'].capitalize(), body=warning)
|
||||
|
||||
def show(self):
|
||||
super(ManageWindow, self).show()
|
||||
if not self.thread_warnings.isFinished():
|
||||
self.thread_warnings.start()
|
||||
|
||||
def _show_about(self):
|
||||
if self.dialog_about is None:
|
||||
self.dialog_about = AboutDialog(self.locale_keys)
|
||||
|
||||
Reference in New Issue
Block a user