mirror of
https://github.com/spalencsar/bearhub.git
synced 2026-07-09 09:54:14 +02:00
0.9.19
This commit is contained in:
17
CHANGELOG.md
17
CHANGELOG.md
@@ -4,6 +4,23 @@ 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.9.19] 2021-08-23
|
||||||
|
### Improvements
|
||||||
|
- AppImage
|
||||||
|
- manual installation: adding generic file filter extension (.*) since some desktop environments filters are case sensitive [#185](https://github.com/vinifmor/bauh/issues/185)
|
||||||
|
- installation: generating a default **.desktop** file for AppImages that provide empty desktop entries [#186](https://github.com/vinifmor/bauh/issues/186)
|
||||||
|
- hiding the app's launching output
|
||||||
|
- Arch
|
||||||
|
- AUR: **rebuild-detector** integration disabled by default since it has a great impact on the overall refresh time (it can be enabled through the settings panel -> "Check reinstallation need")
|
||||||
|
- UI
|
||||||
|
- not using native dialogs for file/directory choosing to prevent unexpected behaviors and wrong theming
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
- AppImage
|
||||||
|
- search: not matching manually installed applications
|
||||||
|
- info button remains "clickable" after an imported Appimage is uninstalled
|
||||||
|
|
||||||
|
|
||||||
## [0.9.18] 2021-06-18
|
## [0.9.18] 2021-06-18
|
||||||
### Fixes
|
### Fixes
|
||||||
- Arch
|
- Arch
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
__version__ = '0.9.18'
|
__version__ = '0.9.19'
|
||||||
__app_name__ = 'bauh'
|
__app_name__ = 'bauh'
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ class AppImageManager(SoftwareManager):
|
|||||||
|
|
||||||
def install_file(self, root_password: str, watcher: ProcessWatcher) -> bool:
|
def install_file(self, root_password: str, watcher: ProcessWatcher) -> bool:
|
||||||
file_chooser = FileChooserComponent(label=self.i18n['file'].capitalize(),
|
file_chooser = FileChooserComponent(label=self.i18n['file'].capitalize(),
|
||||||
allowed_extensions={'AppImage'},
|
allowed_extensions={'AppImage', '*'},
|
||||||
search_path=get_default_manual_installation_file_dir())
|
search_path=get_default_manual_installation_file_dir())
|
||||||
input_name = TextInputComponent(label=self.i18n['name'].capitalize())
|
input_name = TextInputComponent(label=self.i18n['name'].capitalize())
|
||||||
input_version = TextInputComponent(label=self.i18n['version'].capitalize())
|
input_version = TextInputComponent(label=self.i18n['version'].capitalize())
|
||||||
@@ -118,7 +118,7 @@ class AppImageManager(SoftwareManager):
|
|||||||
components=[form],
|
components=[form],
|
||||||
confirmation_label=self.i18n['proceed'].capitalize(),
|
confirmation_label=self.i18n['proceed'].capitalize(),
|
||||||
deny_label=self.i18n['cancel'].capitalize()):
|
deny_label=self.i18n['cancel'].capitalize()):
|
||||||
if not file_chooser.file_path or not os.path.isfile(file_chooser.file_path):
|
if not file_chooser.file_path or not os.path.isfile(file_chooser.file_path) or not file_chooser.file_path.lower().strip().endswith('.appimage'):
|
||||||
watcher.request_confirmation(title=self.i18n['error'].capitalize(),
|
watcher.request_confirmation(title=self.i18n['error'].capitalize(),
|
||||||
body=self.i18n['appimage.custom_action.install_file.invalid_file'],
|
body=self.i18n['appimage.custom_action.install_file.invalid_file'],
|
||||||
deny_button=False)
|
deny_button=False)
|
||||||
@@ -214,27 +214,30 @@ class AppImageManager(SoftwareManager):
|
|||||||
except:
|
except:
|
||||||
self.logger.error("An exception happened while querying the 'apps' database")
|
self.logger.error("An exception happened while querying the 'apps' database")
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
apps_conn.close()
|
|
||||||
return SearchResult.empty()
|
try:
|
||||||
|
installed = self.read_installed(connection=apps_conn, disk_loader=disk_loader, limit=limit, only_apps=False, pkg_types=None, internet_available=True).installed
|
||||||
|
except:
|
||||||
|
installed = None
|
||||||
|
|
||||||
installed_found = []
|
installed_found = []
|
||||||
|
|
||||||
if not_installed:
|
if installed:
|
||||||
installed = self.read_installed(disk_loader=disk_loader, limit=limit,
|
lower_words = words.lower()
|
||||||
only_apps=False,
|
for appim in installed:
|
||||||
pkg_types=None,
|
found = False
|
||||||
connection=apps_conn,
|
|
||||||
internet_available=True).installed
|
|
||||||
if installed:
|
|
||||||
for appim in installed:
|
|
||||||
key = self._gen_app_key(appim)
|
|
||||||
|
|
||||||
|
if not_installed and found_map:
|
||||||
|
key = self._gen_app_key(appim)
|
||||||
new_found = found_map.get(key)
|
new_found = found_map.get(key)
|
||||||
|
|
||||||
if new_found:
|
if new_found:
|
||||||
del not_installed[new_found['idx']]
|
del not_installed[new_found['idx']]
|
||||||
installed_found.append(appim)
|
installed_found.append(appim)
|
||||||
|
found = True
|
||||||
|
|
||||||
|
if not found and lower_words in appim.name.lower() or (appim.description and lower_words in appim.description.lower()):
|
||||||
|
installed_found.append(appim)
|
||||||
try:
|
try:
|
||||||
apps_conn.close()
|
apps_conn.close()
|
||||||
except:
|
except:
|
||||||
@@ -561,18 +564,24 @@ class AppImageManager(SoftwareManager):
|
|||||||
with open('{}/{}'.format(extracted_folder, desktop_entry)) as f:
|
with open('{}/{}'.format(extracted_folder, desktop_entry)) as f:
|
||||||
de_content = f.read()
|
de_content = f.read()
|
||||||
|
|
||||||
de_content = replace_desktop_entry_exec_command(desktop_entry=de_content,
|
if de_content:
|
||||||
appname=pkg.name,
|
de_content = replace_desktop_entry_exec_command(desktop_entry=de_content,
|
||||||
file_path=file_path)
|
appname=pkg.name,
|
||||||
|
file_path=file_path)
|
||||||
extracted_icon = self._find_icon_file(extracted_folder)
|
extracted_icon = self._find_icon_file(extracted_folder)
|
||||||
|
|
||||||
if extracted_icon:
|
if extracted_icon:
|
||||||
icon_path = out_dir + '/logo.' + extracted_icon.split('/')[-1].split('.')[-1]
|
icon_path = out_dir + '/logo.' + extracted_icon.split('/')[-1].split('.')[-1]
|
||||||
shutil.copy(extracted_icon, icon_path)
|
shutil.copy(extracted_icon, icon_path)
|
||||||
de_content = RE_DESKTOP_ICON.sub('Icon={}\n'.format(icon_path), de_content)
|
|
||||||
|
if de_content:
|
||||||
|
de_content = RE_DESKTOP_ICON.sub('Icon={}\n'.format(icon_path), de_content)
|
||||||
|
|
||||||
pkg.icon_path = icon_path
|
pkg.icon_path = icon_path
|
||||||
|
|
||||||
|
if not de_content:
|
||||||
|
de_content = pkg.to_desktop_entry()
|
||||||
|
|
||||||
Path(DESKTOP_ENTRIES_PATH).mkdir(parents=True, exist_ok=True)
|
Path(DESKTOP_ENTRIES_PATH).mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
with open(self._gen_desktop_entry_path(pkg), 'w+') as f:
|
with open(self._gen_desktop_entry_path(pkg), 'w+') as f:
|
||||||
@@ -706,7 +715,8 @@ class AppImageManager(SoftwareManager):
|
|||||||
appimag_path = util.find_appimage_file(installation_dir)
|
appimag_path = util.find_appimage_file(installation_dir)
|
||||||
|
|
||||||
if appimag_path:
|
if appimag_path:
|
||||||
subprocess.Popen(args=[appimag_path], shell=True, env={**os.environ})
|
subprocess.Popen(args=[appimag_path], shell=True, env={**os.environ},
|
||||||
|
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, stdin=subprocess.DEVNULL)
|
||||||
else:
|
else:
|
||||||
self.logger.error("Could not find the AppImage file of '{}' in '{}'".format(pkg.name, installation_dir))
|
self.logger.error("Could not find the AppImage file of '{}' in '{}'".format(pkg.name, installation_dir))
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import re
|
import re
|
||||||
|
from io import StringIO
|
||||||
from typing import List, Optional
|
from typing import List, Optional
|
||||||
|
|
||||||
from bauh.api.abstract.model import SoftwarePackage, CustomSoftwareAction
|
from bauh.api.abstract.model import SoftwarePackage, CustomSoftwareAction
|
||||||
@@ -49,7 +50,7 @@ class AppImage(SoftwarePackage):
|
|||||||
return self.installed and not self.imported
|
return self.installed and not self.imported
|
||||||
|
|
||||||
def has_info(self):
|
def has_info(self):
|
||||||
return True
|
return self.installed if self.imported else True
|
||||||
|
|
||||||
def can_be_downgraded(self):
|
def can_be_downgraded(self):
|
||||||
return self.installed and not self.imported
|
return self.installed and not self.imported
|
||||||
@@ -127,3 +128,23 @@ class AppImage(SoftwarePackage):
|
|||||||
def get_clean_name(self) -> Optional[str]:
|
def get_clean_name(self) -> Optional[str]:
|
||||||
if self.name:
|
if self.name:
|
||||||
return RE_MANY_SPACES.sub('-', self.name.lower().strip())
|
return RE_MANY_SPACES.sub('-', self.name.lower().strip())
|
||||||
|
|
||||||
|
def to_desktop_entry(self) -> str:
|
||||||
|
de = StringIO()
|
||||||
|
de.write("[Desktop Entry]\nType=Application\nName={}\n".format(self.name))
|
||||||
|
|
||||||
|
if self.description:
|
||||||
|
de.write("Comment={}\n".format(self.description.replace('\n', ' ')))
|
||||||
|
|
||||||
|
if self.install_dir and self.local_file_path:
|
||||||
|
de.write('Exec="{}/{}"\n'.format(self.install_dir, self.local_file_path.split('/')[-1]))
|
||||||
|
|
||||||
|
if self.icon_path:
|
||||||
|
de.write('Icon={}\n'.format(self.icon_path))
|
||||||
|
|
||||||
|
if self.categories:
|
||||||
|
de.write('Categories={};\n'.format(';'.join((c for c in self.categories if c.lower() != 'imported'))))
|
||||||
|
|
||||||
|
de.write('Terminal=false')
|
||||||
|
de.seek(0)
|
||||||
|
return de.read()
|
||||||
|
|||||||
@@ -39,5 +39,5 @@ class ArchConfigManager(YAMLConfigManager):
|
|||||||
'suggest_optdep_uninstall': False,
|
'suggest_optdep_uninstall': False,
|
||||||
'aur_idx_exp': 1,
|
'aur_idx_exp': 1,
|
||||||
'categories_exp': 24,
|
'categories_exp': 24,
|
||||||
'aur_rebuild_detector': True,
|
'aur_rebuild_detector': False,
|
||||||
"aur_rebuild_detector_no_bin": True}
|
"aur_rebuild_detector_no_bin": True}
|
||||||
|
|||||||
@@ -870,9 +870,11 @@ class FormQt(QGroupBox):
|
|||||||
cur_path = str(Path.home())
|
cur_path = str(Path.home())
|
||||||
|
|
||||||
if c.directory:
|
if c.directory:
|
||||||
file_path = QFileDialog.getExistingDirectory(self, self.i18n['file_chooser.title'], cur_path, options=QFileDialog.Options())
|
opts = QFileDialog.DontUseNativeDialog
|
||||||
|
opts |= QFileDialog.ShowDirsOnly
|
||||||
|
file_path = QFileDialog.getExistingDirectory(self, self.i18n['file_chooser.title'], cur_path, options=opts)
|
||||||
else:
|
else:
|
||||||
file_path, _ = QFileDialog.getOpenFileName(self, self.i18n['file_chooser.title'], cur_path, exts, options=QFileDialog.Options())
|
file_path, _ = QFileDialog.getOpenFileName(self, self.i18n['file_chooser.title'], cur_path, exts, options=QFileDialog.DontUseNativeDialog)
|
||||||
|
|
||||||
if file_path:
|
if file_path:
|
||||||
c.set_file_path(file_path)
|
c.set_file_path(file_path)
|
||||||
|
|||||||
Reference in New Issue
Block a user