mirror of
https://github.com/spalencsar/bearhub.git
synced 2026-07-07 02:24:16 +02:00
0.8.4
This commit is contained in:
20
CHANGELOG.md
20
CHANGELOG.md
@@ -3,6 +3,24 @@ 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/).
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
|
|
||||||
|
## [0.8.4] - 2020-02-21
|
||||||
|
### Improvements
|
||||||
|
- UI
|
||||||
|
- treating multiple lines on the application's description displayed on the table
|
||||||
|
- AUR
|
||||||
|
- generating the semantic search map on demand instead of storing it in memory
|
||||||
|
- Russian translations by:
|
||||||
|
- [leoneii](https://github.com/leoneii) - PRs: [#61](https://github.com/vinifmor/bauh/pull/61) [#63](https://github.com/vinifmor/bauh/pull/63)
|
||||||
|
- [mountain-biker85](https://github.com/mountain-biker85) - PRs: [#62](https://github.com/vinifmor/bauh/pull/62) [#64](https://github.com/vinifmor/bauh/pull/64)
|
||||||
|
### Fixes
|
||||||
|
- Snap
|
||||||
|
- not able to launch applications on some distros ( e.g: OpenSuse ) [#58](https://github.com/vinifmor/bauh/issues/58)
|
||||||
|
- AUR
|
||||||
|
- package name tooltip was displaying only the repository ( table row )
|
||||||
|
- UI
|
||||||
|
- not displaying some priority search results at the top of the table
|
||||||
|
|
||||||
|
|
||||||
## [0.8.3] - 2020-02-13
|
## [0.8.3] - 2020-02-13
|
||||||
### Improvements
|
### Improvements
|
||||||
@@ -15,7 +33,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||||||
- checking architecture dependencies (x86_64, i686)
|
- checking architecture dependencies (x86_64, i686)
|
||||||
- architecture dependencies are displayed on the info window as well
|
- architecture dependencies are displayed on the info window as well
|
||||||
- optimizations to speed up zst packages building
|
- optimizations to speed up zst packages building
|
||||||
- showing a warning messaging when trying to install / update / downgrade a package with the root user
|
- showing a warning message when trying to install / update / downgrade a package with the root user
|
||||||
- UI:
|
- UI:
|
||||||
- **Settings** available as a tray action as well
|
- **Settings** available as a tray action as well
|
||||||
- minor improvements
|
- minor improvements
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
__version__ = '0.8.3'
|
__version__ = '0.8.4'
|
||||||
__app_name__ = 'bauh'
|
__app_name__ = 'bauh'
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
|||||||
@@ -47,12 +47,6 @@ SOURCE_FIELDS = ('source', 'source_x86_64')
|
|||||||
RE_PRE_DOWNLOAD_WL_PROTOCOLS = re.compile(r'^(.+::)?(https?|ftp)://.+')
|
RE_PRE_DOWNLOAD_WL_PROTOCOLS = re.compile(r'^(.+::)?(https?|ftp)://.+')
|
||||||
RE_PRE_DOWNLOAD_BL_EXT = re.compile(r'.+\.(git|gpg)$')
|
RE_PRE_DOWNLOAD_BL_EXT = re.compile(r'.+\.(git|gpg)$')
|
||||||
|
|
||||||
SEARCH_OPTIMIZED_MAP = {
|
|
||||||
'google chrome': 'google-chrome',
|
|
||||||
'chrome google': 'google-chrome',
|
|
||||||
'googlechrome': 'google-chrome'
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class ArchManager(SoftwareManager):
|
class ArchManager(SoftwareManager):
|
||||||
|
|
||||||
@@ -75,6 +69,11 @@ class ArchManager(SoftwareManager):
|
|||||||
self.local_config = None
|
self.local_config = None
|
||||||
self.http_client = context.http_client
|
self.http_client = context.http_client
|
||||||
|
|
||||||
|
def get_semantic_search_map(self) -> Dict[str, str]:
|
||||||
|
return {'google chrome': 'google-chrome',
|
||||||
|
'chrome google': 'google-chrome',
|
||||||
|
'googlechrome': 'google-chrome'}
|
||||||
|
|
||||||
def _upgrade_search_result(self, apidata: dict, installed_pkgs: dict, downgrade_enabled: bool, res: SearchResult, disk_loader: DiskCacheLoader):
|
def _upgrade_search_result(self, apidata: dict, installed_pkgs: dict, downgrade_enabled: bool, res: SearchResult, disk_loader: DiskCacheLoader):
|
||||||
app = self.mapper.map_api_data(apidata, installed_pkgs['not_signed'], self.categories)
|
app = self.mapper.map_api_data(apidata, installed_pkgs['not_signed'], self.categories)
|
||||||
app.downgrade_enabled = downgrade_enabled
|
app.downgrade_enabled = downgrade_enabled
|
||||||
@@ -100,7 +99,7 @@ class ArchManager(SoftwareManager):
|
|||||||
read_installed = Thread(target=lambda: installed.update(pacman.list_and_map_installed()), daemon=True)
|
read_installed = Thread(target=lambda: installed.update(pacman.list_and_map_installed()), daemon=True)
|
||||||
read_installed.start()
|
read_installed.start()
|
||||||
|
|
||||||
mapped_words = SEARCH_OPTIMIZED_MAP.get(words)
|
mapped_words = self.get_semantic_search_map().get(words)
|
||||||
|
|
||||||
api_res = self.aur_client.search(mapped_words if mapped_words else words)
|
api_res = self.aur_client.search(mapped_words if mapped_words else words)
|
||||||
|
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ class ArchPackage(SoftwarePackage):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
def get_name_tooltip(self) -> str:
|
def get_name_tooltip(self) -> str:
|
||||||
return '{}: {}'.format(self.i18n['repository'], self.mirror)
|
return '{} ( {}: {} )'.format(self.name, self.i18n['repository'], self.mirror)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.__repr__()
|
return self.__repr__()
|
||||||
|
|||||||
@@ -36,6 +36,13 @@ class SnapManager(SoftwareManager):
|
|||||||
self.categories_downloader = CategoriesDownloader('snap', self.http_client, self.logger, self, context.disk_cache,
|
self.categories_downloader = CategoriesDownloader('snap', self.http_client, self.logger, self, context.disk_cache,
|
||||||
URL_CATEGORIES_FILE, SNAP_CACHE_PATH, CATEGORIES_FILE_PATH)
|
URL_CATEGORIES_FILE, SNAP_CACHE_PATH, CATEGORIES_FILE_PATH)
|
||||||
self.suggestions_cache = context.cache_factory.new()
|
self.suggestions_cache = context.cache_factory.new()
|
||||||
|
self.info_path = None
|
||||||
|
|
||||||
|
def get_info_path(self) -> str:
|
||||||
|
if self.info_path is None:
|
||||||
|
self.info_path = snap.get_app_info_path()
|
||||||
|
|
||||||
|
return self.info_path
|
||||||
|
|
||||||
def map_json(self, app_json: dict, installed: bool, disk_loader: DiskCacheLoader, internet: bool = True) -> SnapApplication:
|
def map_json(self, app_json: dict, installed: bool, disk_loader: DiskCacheLoader, internet: bool = True) -> SnapApplication:
|
||||||
app = SnapApplication(publisher=app_json.get('publisher'),
|
app = SnapApplication(publisher=app_json.get('publisher'),
|
||||||
@@ -112,9 +119,11 @@ class SnapManager(SoftwareManager):
|
|||||||
return SearchResult([], [], 0)
|
return SearchResult([], [], 0)
|
||||||
|
|
||||||
def read_installed(self, disk_loader: DiskCacheLoader, limit: int = -1, only_apps: bool = False, pkg_types: Set[Type[SoftwarePackage]] = None, internet_available: bool = None) -> SearchResult:
|
def read_installed(self, disk_loader: DiskCacheLoader, limit: int = -1, only_apps: bool = False, pkg_types: Set[Type[SoftwarePackage]] = None, internet_available: bool = None) -> SearchResult:
|
||||||
if snap.is_snapd_running():
|
info_path = self.get_info_path()
|
||||||
|
|
||||||
|
if snap.is_snapd_running() and info_path:
|
||||||
self.categories_downloader.join()
|
self.categories_downloader.join()
|
||||||
installed = [self.map_json(app_json, installed=True, disk_loader=disk_loader, internet=internet_available) for app_json in snap.read_installed(self.ubuntu_distro)]
|
installed = [self.map_json(app_json, installed=True, disk_loader=disk_loader, internet=internet_available) for app_json in snap.read_installed(info_path)]
|
||||||
return SearchResult(installed, None, len(installed))
|
return SearchResult(installed, None, len(installed))
|
||||||
else:
|
else:
|
||||||
return SearchResult([], None, 0)
|
return SearchResult([], None, 0)
|
||||||
@@ -159,6 +168,11 @@ class SnapManager(SoftwareManager):
|
|||||||
raise Exception("'get_history' is not supported by {}".format(pkg.__class__.__name__))
|
raise Exception("'get_history' is not supported by {}".format(pkg.__class__.__name__))
|
||||||
|
|
||||||
def install(self, pkg: SnapApplication, root_password: str, watcher: ProcessWatcher) -> bool:
|
def install(self, pkg: SnapApplication, root_password: str, watcher: ProcessWatcher) -> bool:
|
||||||
|
info_path = self.get_info_path()
|
||||||
|
|
||||||
|
if not info_path:
|
||||||
|
self.logger.warning('Information directory was not found. It will not be possible to determine if the installed application can be launched')
|
||||||
|
|
||||||
res, output = ProcessHandler(watcher).handle_simple(snap.install_and_stream(pkg.name, pkg.confinement, root_password))
|
res, output = ProcessHandler(watcher).handle_simple(snap.install_and_stream(pkg.name, pkg.confinement, root_password))
|
||||||
|
|
||||||
if 'error:' in output:
|
if 'error:' in output:
|
||||||
@@ -180,14 +194,15 @@ class SnapManager(SoftwareManager):
|
|||||||
self.logger.info("Installing '{}' with the custom command '{}'".format(pkg.name, channel_select.value))
|
self.logger.info("Installing '{}' with the custom command '{}'".format(pkg.name, channel_select.value))
|
||||||
res = ProcessHandler(watcher).handle(SystemProcess(new_root_subprocess(channel_select.value.value.split(' '), root_password=root_password)))
|
res = ProcessHandler(watcher).handle(SystemProcess(new_root_subprocess(channel_select.value.value.split(' '), root_password=root_password)))
|
||||||
|
|
||||||
if res:
|
if res and info_path:
|
||||||
pkg.has_apps_field = snap.has_apps_field(pkg.name, self.ubuntu_distro)
|
pkg.has_apps_field = snap.has_apps_field(pkg.name, info_path)
|
||||||
|
|
||||||
return res
|
return res
|
||||||
else:
|
else:
|
||||||
self.logger.error("Could not find available channels in the installation output: {}".format(output))
|
self.logger.error("Could not find available channels in the installation output: {}".format(output))
|
||||||
else:
|
else:
|
||||||
pkg.has_apps_field = snap.has_apps_field(pkg.name, self.ubuntu_distro)
|
if info_path:
|
||||||
|
pkg.has_apps_field = snap.has_apps_field(pkg.name, info_path)
|
||||||
|
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import logging
|
import logging
|
||||||
|
import os
|
||||||
import re
|
import re
|
||||||
import subprocess
|
import subprocess
|
||||||
from io import StringIO
|
from io import StringIO
|
||||||
@@ -85,7 +86,7 @@ def get_info(app_name: str, attrs: tuple = None):
|
|||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
def read_installed(ubuntu_distro: bool) -> List[dict]:
|
def read_installed(info_path: str) -> List[dict]:
|
||||||
res = run_cmd('{} list'.format(BASE_CMD), print_error=False)
|
res = run_cmd('{} list'.format(BASE_CMD), print_error=False)
|
||||||
|
|
||||||
apps = []
|
apps = []
|
||||||
@@ -98,8 +99,6 @@ def read_installed(ubuntu_distro: bool) -> List[dict]:
|
|||||||
if idx > 0 and app_str:
|
if idx > 0 and app_str:
|
||||||
apps.append(app_str_to_json(app_str))
|
apps.append(app_str_to_json(app_str))
|
||||||
|
|
||||||
info_path = _get_app_info_path(ubuntu_distro)
|
|
||||||
|
|
||||||
info_out = new_subprocess(['cat', *[info_path.format(a['name']) for a in apps]]).stdout
|
info_out = new_subprocess(['cat', *[info_path.format(a['name']) for a in apps]]).stdout
|
||||||
|
|
||||||
idx = -1
|
idx = -1
|
||||||
@@ -116,16 +115,16 @@ def read_installed(ubuntu_distro: bool) -> List[dict]:
|
|||||||
return apps
|
return apps
|
||||||
|
|
||||||
|
|
||||||
def _get_app_info_path(ubuntu_distro: bool) -> str:
|
def get_app_info_path() -> str:
|
||||||
if ubuntu_distro:
|
if os.path.exists('/snap'):
|
||||||
return '/snap/{}/current/meta/snap.yaml'
|
return '/snap/{}/current/meta/snap.yaml'
|
||||||
else:
|
elif os.path.exists('/var/lib/snapd/snap'):
|
||||||
return '/var/lib/snapd/snap/{}/current/meta/snap.yaml'
|
return '/var/lib/snapd/snap/{}/current/meta/snap.yaml'
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
def has_apps_field(name: str, ubuntu_distro: bool) -> bool:
|
def has_apps_field(name: str, info_path: str) -> bool:
|
||||||
info_path = _get_app_info_path(ubuntu_distro)
|
|
||||||
|
|
||||||
info_out = new_subprocess(['cat', info_path.format(name)]).stdout
|
info_out = new_subprocess(['cat', info_path.format(name)]).stdout
|
||||||
|
|
||||||
res = False
|
res = False
|
||||||
|
|||||||
@@ -381,7 +381,7 @@ class AppsTable(QTableWidget):
|
|||||||
item.setMinimumWidth(300)
|
item.setMinimumWidth(300)
|
||||||
|
|
||||||
if pkg.model.description is not None or not pkg.model.is_application() or pkg.model.status == PackageStatus.READY:
|
if pkg.model.description is not None or not pkg.model.is_application() or pkg.model.status == PackageStatus.READY:
|
||||||
desc = pkg.model.description
|
desc = pkg.model.description.split('\n')[0] if pkg.model.description else pkg.model.description
|
||||||
else:
|
else:
|
||||||
desc = '...'
|
desc = '...'
|
||||||
|
|
||||||
|
|||||||
@@ -694,7 +694,7 @@ class ManageWindow(QWidget):
|
|||||||
|
|
||||||
def _gen_filters(self, updates: int = 0, ignore_updates: bool = False) -> dict:
|
def _gen_filters(self, updates: int = 0, ignore_updates: bool = False) -> dict:
|
||||||
return {
|
return {
|
||||||
'only_apps': self.filter_only_apps,
|
'only_apps': False if self.search_performed else self.filter_only_apps,
|
||||||
'type': self.type_filter,
|
'type': self.type_filter,
|
||||||
'category': self.category_filter,
|
'category': self.category_filter,
|
||||||
'updates': False if ignore_updates else self.filter_updates,
|
'updates': False if ignore_updates else self.filter_updates,
|
||||||
|
|||||||
@@ -266,6 +266,7 @@ locale.pt=portuguès
|
|||||||
locale.ca=català
|
locale.ca=català
|
||||||
locale.de=alemany
|
locale.de=alemany
|
||||||
locale.it=italià
|
locale.it=italià
|
||||||
|
locale.ru=rus
|
||||||
interval=interval
|
interval=interval
|
||||||
installation=instal·lació
|
installation=instal·lació
|
||||||
download=download
|
download=download
|
||||||
|
|||||||
@@ -221,6 +221,7 @@ locale.pt=portugiesisch
|
|||||||
locale.ca=Katalanisch
|
locale.ca=Katalanisch
|
||||||
locale.de=deutsch
|
locale.de=deutsch
|
||||||
locale.it=italienisch
|
locale.it=italienisch
|
||||||
|
locale.ru=russisch
|
||||||
interval=intervall
|
interval=intervall
|
||||||
installation=Installation
|
installation=Installation
|
||||||
download=download
|
download=download
|
||||||
|
|||||||
@@ -228,6 +228,7 @@ locale.pt=portuguese
|
|||||||
locale.ca=catalan
|
locale.ca=catalan
|
||||||
locale.de=german
|
locale.de=german
|
||||||
locale.it=italian
|
locale.it=italian
|
||||||
|
locale.ru=russian
|
||||||
interval=interval
|
interval=interval
|
||||||
installation=installation
|
installation=installation
|
||||||
download=download
|
download=download
|
||||||
|
|||||||
@@ -269,6 +269,7 @@ locale.pt=portugués
|
|||||||
locale.ca=catalán
|
locale.ca=catalán
|
||||||
locale.de=alemán
|
locale.de=alemán
|
||||||
locale.it=italiano
|
locale.it=italiano
|
||||||
|
locale.ru=ruso
|
||||||
interval=intervalo
|
interval=intervalo
|
||||||
installation=instalación
|
installation=instalación
|
||||||
download=descarga
|
download=descarga
|
||||||
|
|||||||
@@ -221,6 +221,7 @@ locale.pt=portoghese
|
|||||||
locale.ca=catalan
|
locale.ca=catalan
|
||||||
locale.de=tedesco
|
locale.de=tedesco
|
||||||
locale.it=italiano
|
locale.it=italiano
|
||||||
|
locale.ru=russo
|
||||||
interval=intervallo
|
interval=intervallo
|
||||||
installation=installazione
|
installation=installazione
|
||||||
download=download
|
download=download
|
||||||
|
|||||||
@@ -272,6 +272,7 @@ locale.pt=português
|
|||||||
locale.ca=catalão
|
locale.ca=catalão
|
||||||
locale.de=alemão
|
locale.de=alemão
|
||||||
locale.it=italiano
|
locale.it=italiano
|
||||||
|
locale.ru=russo
|
||||||
interval=intervalo
|
interval=intervalo
|
||||||
installation=instalação
|
installation=instalação
|
||||||
download=download
|
download=download
|
||||||
|
|||||||
@@ -75,7 +75,10 @@ def get_locale_keys(key: str = None, locale_dir: str = resource.get_path('locale
|
|||||||
for line in locale_keys:
|
for line in locale_keys:
|
||||||
line_strip = line.strip()
|
line_strip = line.strip()
|
||||||
if line_strip:
|
if line_strip:
|
||||||
keyval = line_strip.split('=')
|
try:
|
||||||
locale_obj[keyval[0].strip()] = keyval[1].strip()
|
keyval = line_strip.split('=')
|
||||||
|
locale_obj[keyval[0].strip()] = keyval[1].strip()
|
||||||
|
except:
|
||||||
|
print("Error decoding i18n line '{}'".format(line))
|
||||||
|
|
||||||
return locale_path.split('/')[-1], locale_obj
|
return locale_path.split('/')[-1], locale_obj
|
||||||
|
|||||||
Reference in New Issue
Block a user