Skip to content

Commit

Permalink
0.10.6
Browse files Browse the repository at this point in the history
  • Loading branch information
vinifmor authored Dec 23, 2023
2 parents a596400 + 2bcbaf8 commit 6f7e4db
Show file tree
Hide file tree
Showing 112 changed files with 2,075 additions and 534 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@ linux_dist/appimage/appimage-builder-cache
linux_dist/appimage/*.zsync
linux_dist/appimage/*.AppImage
linux_dist/appimage/*.gz
linux_dist/appimage/*.gz.*
linux_dist/appimage/bauh-*

47 changes: 47 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,53 @@ 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.10.6] 2023-12-23
### Features
- new **verified** filter for the management table

### Improvements
- AppImage
- supporting AppImages from GitLab repositories
- info window: displaying "unknown" when there is no mapped license
- Arch
- parallelized installed packages reading
- parallelized search
- adding the AUR's URL on the package information dialog [#339](https://github.com/vinifmor/bauh/issues/339)
- General
- new download implementation replaces `wget` (implemented in Python using the `requests` library)
- replaced the internet checking old host (`google.com`) by a more general one (`w3.org`) [#300](https://github.com/vinifmor/bauh/issues/300)
- faster exit (threaded calls won't be waited)
- adding a new project definition/setup (`pyproject.toml`) file to comply with the latest standards
- UI
- faster package icons download
- faster packages filtering (`type`, `category`, `name`, etc... up to **95% less time**)
- the "Skip" button on the initialization panel is now enabled after 10 seconds [#310](https://github.com/vinifmor/bauh/issues/310)
- displaying the download progress for screenshots
- on the package information dialog is now possible to open fields associated with URLs in the browser [#340](https://github.com/vinifmor/bauh/issues/340)
- displaying a text warning before installing an unverified package (unverified = not verified by the system maintainers or a trustable source)
- at the moment the following packaging formats are considered completely **unverified**: AppImage, AUR, Web
- Snap supports both verified and unverified software
- minor reduction in the table loading time
- improvements to help with random widget centralisation issues
- more translations

### Fixes
- AppImage
- upgrade fails when the package was initially imported, but later available on bauh's database [#321](https://github.com/vinifmor/bauh/issues/321)
- General
- random segmentation fault errors associated with threads and caching
- Web
- search not working for some typed addresses (e.g: those returning 403)

### Contributions
- German translations by [Mape6](https://github.com/Mape6)
- Russian translations by [KoromeloDev](https://github.com/KoromeloDev)
- Fix [#329](https://github.com/vinifmor/bauh/issues/329) by [w568w](https://github.com/w568w)

### Distribution
- bauh's AppImage is now based on Debian bullseye and had a small size reduction


## [0.10.5] 2022-12-17

### Fixes
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Copyright (c) 2019-2023 Vinícius Moreira
Copyright (c) 2019 Vinícius Moreira

zlib/libpng license

Expand Down
7 changes: 4 additions & 3 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
include LICENSE CHANGELOG.md README.md
include requirements.txt
include LICENSE CHANGELOG.md README.md requirements.txt
recursive-include bauh/desktop *
recursive-exclude bauh/desktop *.orig
recursive-include bauh/view/resources *
recursive-exclude bauh/view/resources *.orig
recursive-include bauh/gems/*/resources *
recursive-include tests *
recursive-exclude bauh/gems/*/resources *.orig
21 changes: 15 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,16 @@ Key features
- `qt5dxcb-plugin` (or equivalent): the package name may vary from distribution

##### Steps
- Download the .AppImage file attached with the latest release from https://github.com/vinifmor/bauh/releases.
- Run the following command through a terminal: `chmod a+x bauh-${version}-x86_64.AppImage` (replace `${version}` by the respective downloaded version)
- Launch it: `./bauh-${version}-x86_64.AppImage`
- Download the .AppImage file attached with the latest release from https://github.com/vinifmor/bauh/releases
- Generally desktop environment allow you to double-click the downloaded file to execute it. If that's not your case, follow the steps below from a console:
- `chmod a+x bauh-${version}-x86_64.AppImage` (replace `${version}` by the respective downloaded version)
- `./bauh-${version}-x86_64.AppImage`
- If you want to integrate bauh to your desktop: click on bauh's settings menu ("sandwich") and then `Install bauh`

<p align="center">
<img src="https://raw.githubusercontent.com/vinifmor/bauh-files/master/pictures/releases/0.10.0/appim_self.png">
</p>


#### <a name="inst_ubuntu">Ubuntu 20.04 based distros (Linux Mint, PopOS, ...)</a>

Expand All @@ -77,11 +84,12 @@ Key features
- `aria2`: multi-threaded downloads
- `axel`: multi-threaded downloads alternative
- `libappindicator3-1`: tray-mode
- `wget`, `sqlite3`, `fuse`: AppImage support
- `sqlite3`, `fuse`: AppImage support
- `flatpak`: Flatpaks support
- `snapd`: Snaps support
- `python3-lxml`, `python3-bs4`: Web apps support
- `python3-venv`: [isolated installation](#inst_iso)
- `xdg-utils`: to open URLs in the browsers (`xdg-open`)

##### Updating bauh

Expand Down Expand Up @@ -125,8 +133,9 @@ makepkg -si
- `aria2`: multi-threaded downloads
- `axel`: multi-threaded downloads alternative
- `libappindicator-gtk2`: tray-mode (GTK2 desktop environments)
- `libappindicator-gtk3`: tray-mode (GTK3 desktop environments)
- `wget`, `sqlite`, `fuse2`, `fuse3`: AppImage support
- `libappindicator-gtk3`: tray-mode (GTK3 desktop environments)
- `xdg-utils`: to open URLs in the browser (`xdg-open`)
- `sqlite`, `fuse2`, `fuse3`: AppImage support
- `flatpak`: Flatpak support
- `snapd`: Snap support
- `pacman`: ArchLinux package management support
Expand Down
2 changes: 1 addition & 1 deletion bauh/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__version__ = '0.10.5'
__version__ = '0.10.6'
__app_name__ = 'bauh'

import os
Expand Down
8 changes: 4 additions & 4 deletions bauh/api/abstract/download.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from abc import ABC, abstractmethod
from typing import Iterable, List, Optional
from typing import Iterable, List, Optional, Tuple

from bauh.api.abstract.handler import ProcessWatcher

Expand Down Expand Up @@ -31,17 +31,17 @@ def can_work(self) -> bool:
pass

@abstractmethod
def get_supported_multithreaded_clients(self) -> Iterable[str]:
def get_supported_multithreaded_clients(self) -> Tuple[str, ...]:
pass

@abstractmethod
def is_multithreaded_client_available(self, name: str) -> bool:
pass

@abstractmethod
def list_available_multithreaded_clients(self) -> List[str]:
def list_available_multithreaded_clients(self) -> Tuple[str, ...]:
pass

@abstractmethod
def get_supported_clients(self) -> tuple:
def get_supported_clients(self) -> Tuple[str, ...]:
pass
7 changes: 4 additions & 3 deletions bauh/api/http.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,15 @@ def __init__(self, logger: logging.Logger, max_attempts: int = 2, timeout: int =
self.sleep = sleep
self.logger = logger

def get(self, url: str, params: dict = None, headers: dict = None, allow_redirects: bool = True, ignore_ssl: bool = False, single_call: bool = False, session: bool = True) -> Optional[requests.Response]:
def get(self, url: str, params: dict = None, headers: dict = None, allow_redirects: bool = True, ignore_ssl: bool = False, single_call: bool = False,
session: bool = True, stream: bool = False) -> Optional[requests.Response]:
cur_attempts = 1

while cur_attempts <= self.max_attempts:
cur_attempts += 1

try:
args = {'timeout': self.timeout, 'allow_redirects': allow_redirects}
args = {'timeout': self.timeout, 'allow_redirects': allow_redirects, 'stream': stream}

if params:
args['params'] = params
Expand All @@ -42,7 +43,7 @@ def get(self, url: str, params: dict = None, headers: dict = None, allow_redirec
else:
res = requests.get(url, **args)

if res.status_code == 200:
if 200 <= res.status_code < 300:
return res

if single_call:
Expand Down
2 changes: 1 addition & 1 deletion bauh/commons/internet.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ def is_available(self) -> bool:
return False

try:
socket.gethostbyname('google.com')
socket.gethostbyname("w3.org")
return True
except Exception:
return False
3 changes: 3 additions & 0 deletions bauh/commons/regex.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import re

RE_URL = re.compile(r"^https?://.+$")
46 changes: 28 additions & 18 deletions bauh/gems/appimage/controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ def __init__(self, context: ApplicationContext):
self.configman = AppImageConfigManager()
self._custom_actions: Optional[Iterable[CustomSoftwareAction]] = None
self._action_self_install: Optional[CustomSoftwareAction] = None
self._app_github: Optional[str] = None
self._app_repository: Optional[str] = None
self._search_unfilled_attrs: Optional[Tuple[str, ...]] = None
self._suggestions_downloader: Optional[AppImageSuggestionsDownloader] = None

Expand Down Expand Up @@ -122,7 +122,7 @@ def install_file(self, root_password: Optional[str], watcher: ProcessWatcher) ->
else:
return False

appim = AppImage(i18n=self.i18n, imported=True)
appim = AppImage(i18n=self.i18n, imported=True, manual_update=True)
appim.name = input_name.get_value().strip()
appim.local_file_path = file_chooser.file_path
appim.version = input_version.get_value()
Expand Down Expand Up @@ -168,6 +168,7 @@ def update_file(self, pkg: AppImage, root_password: Optional[str], watcher: Proc

pkg.local_file_path = file_chooser.file_path
pkg.version = input_version.get_value()
pkg.manual_update = True

reqs = UpgradeRequirements(to_install=None, to_remove=None, to_upgrade=[UpgradeRequirement(pkg=pkg)], cannot_upgrade=None)
return self.upgrade(reqs, root_password=root_password, watcher=watcher)
Expand All @@ -183,7 +184,7 @@ def _get_db_connection(self, db_path: str) -> sqlite3.Connection:
self.logger.warning(f"Could not get a connection for database '{db_path}'")

def _gen_app_key(self, app: AppImage):
return f"{app.name.lower()}{app.github.lower() if app.github else ''}"
return f"{app.name.lower()}{app.repository.lower() if app.repository else ''}"

def search(self, words: str, disk_loader: DiskCacheLoader, limit: int = -1, is_url: bool = False) -> SearchResult:
if is_url:
Expand Down Expand Up @@ -275,7 +276,7 @@ def read_installed(self, disk_loader: Optional[DiskCacheLoader], limit: int = -1

for tup in cursor.fetchall():
for app in installed_apps:
if app.name.lower() == tup[0].lower() and (not app.github or app.github.lower() == tup[1].lower()):
if app.name.lower() == tup[0].lower() and (not app.repository or app.repository.lower() == tup[1].lower()):
continuous_version = app.version == 'continuous'
continuous_update = tup[2] == 'continuous'

Expand Down Expand Up @@ -368,6 +369,16 @@ def upgrade(self, requirements: UpgradeRequirements, root_password: Optional[str

download_data = None

# always changing the 'imported' field based on the 'manual_update' flag that means
# "the user is manually installing/updating the AppImage"
if not req.pkg.manual_update:
req.pkg.imported = False

if req.pkg.categories and "Imported" in req.pkg.categories:
# removing the imported category in case the file is not considered imported anymore
req.pkg.categories.remove("Imported")

# manual file updates do not required download it
if not req.pkg.imported:
download_data = self._download(req.pkg, watcher)

Expand Down Expand Up @@ -430,7 +441,7 @@ def uninstall(self, pkg: AppImage, root_password: Optional[str], watcher: Proces
return TransactionResult(success=True, installed=None, removed=[pkg])

def _add_self_latest_version(self, app: AppImage):
if app.name == self.context.app_name and app.github == self.app_github and not app.url_download_latest_version:
if app.name == self.context.app_name and app.repository == self.app_repository and not app.url_download_latest_version:
history = self.get_history(app)

if not history or not history.history:
Expand Down Expand Up @@ -469,6 +480,9 @@ def get_info(self, pkg: AppImage) -> dict:
if data.get('symlink') and not os.path.islink(data['symlink']):
del data['symlink']

if not data.get("license"):
data["license"] = self.i18n["unknown"].lower()

return data

def _sort_release(self, rel: tuple):
Expand All @@ -486,7 +500,7 @@ def get_history(self, pkg: AppImage) -> PackageHistory:
try:
cursor = app_con.cursor()

cursor.execute(query.FIND_APP_ID_BY_NAME_AND_GITHUB.format(pkg.name.lower(), pkg.github.lower() if pkg.github else ''))
cursor.execute(query.FIND_APP_ID_BY_REPO_AND_NAME.format(pkg.repository.lower() if pkg.repository else '', pkg.name.lower()))
app_tuple = cursor.fetchone()

if not app_tuple:
Expand Down Expand Up @@ -593,8 +607,8 @@ def _install(self, pkg: AppImage, watcher: ProcessWatcher, pre_downloaded_file:
Path(out_dir).mkdir(parents=True, exist_ok=True)
pkg.install_dir = out_dir

if pkg.imported:

# when the package is being imported/upgraded there is no need to download it
if pkg.manual_update:
downloaded, file_name = True, pkg.local_file_path.split('/')[-1]

install_file_path = out_dir + '/' + file_name
Expand Down Expand Up @@ -725,10 +739,6 @@ def can_work(self) -> Tuple[bool, Optional[str]]:
if not self._is_sqlite3_available():
return False, self.i18n['missing_dep'].format(dep=bold('sqlite3'))

if not self.file_downloader.can_work():
download_clients = ', '.join(self.file_downloader.get_supported_clients())
return False, self.i18n['appimage.missing_downloader'].format(clients=download_clients)

return True, None

def requires_root(self, action: SoftwareAction, pkg: AppImage) -> bool:
Expand Down Expand Up @@ -984,7 +994,7 @@ def update_database(self, root_password: Optional[str], watcher: ProcessWatcher)
@property
def search_unfilled_attrs(self) -> Tuple[str, ...]:
if self._search_unfilled_attrs is None:
self._search_unfilled_attrs = ('icon_url', 'url_download_latest_version', 'author', 'license', 'github',
self._search_unfilled_attrs = ('icon_url', 'url_download_latest_version', 'author', 'license', 'repository',
'source', 'url_screenshot')

return self._search_unfilled_attrs
Expand All @@ -999,7 +1009,7 @@ def self_install(self, root_password: Optional[str], watcher: ProcessWatcher) ->
return False

app = AppImage(name=self.context.app_name, version=self.context.app_version,
categories=['system'], author=self.context.app_name, github=self.app_github,
categories=['system'], author=self.context.app_name, repository=self.app_repository,
license='zlib/libpng')

res = self._install(pkg=app, watcher=watcher,
Expand Down Expand Up @@ -1080,11 +1090,11 @@ def action_self_install(self) -> CustomSoftwareAction:
return self._action_self_install

@property
def app_github(self) -> str:
if self._app_github is None:
self._app_github = f'vinifmor/{self.context.app_name}'
def app_repository(self) -> str:
if self._app_repository is None:
self._app_repository = f"https://github.com/vinifmor/{self.context.app_name}"

return self._app_github
return self._app_repository

@property
def suggestions_downloader(self) -> AppImageSuggestionsDownloader:
Expand Down
12 changes: 7 additions & 5 deletions bauh/gems/appimage/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ def actions_local_installation(cls) -> Tuple[CustomSoftwareAction, ...]:
def cached_attrs(cls) -> Tuple[str, ...]:
if cls.__cached_attrs is None:
cls.__cached_attrs = ('name', 'description', 'version', 'url_download', 'author', 'license', 'source',
'icon_path', 'github', 'categories', 'imported', 'install_dir', 'symlink')
'icon_path', 'repository', 'categories', 'imported', 'install_dir',
'symlink')

return cls.__cached_attrs

Expand All @@ -43,17 +44,17 @@ def re_many_spaces(cls) -> Pattern:

return cls.__re_many_spaces

def __init__(self, name: str = None, description: str = None, github: str = None, source: str = None, version: str = None,
def __init__(self, name: str = None, description: str = None, repository: str = None, source: str = None, version: str = None,
url_download: str = None, url_icon: str = None, url_screenshot: str = None, license: str = None, author: str = None,
categories=None, icon_path: str = None, installed: bool = False,
url_download_latest_version: str = None, local_file_path: str = None, imported: bool = False,
i18n: I18n = None, install_dir: str = None, updates_ignored: bool = False,
symlink: str = None, **kwargs):
symlink: str = None, manual_update: bool = False, github: str = None, **kwargs):
super(AppImage, self).__init__(id=name, name=name, version=version, latest_version=version,
icon_url=url_icon, license=license, description=description,
installed=installed)
self.source = source
self.github = github
self.repository = repository if repository else (github if github else repository)
self.categories = (categories.split(',') if isinstance(categories, str) else categories) if categories else None
self.url_download = url_download
self.icon_path = icon_path
Expand All @@ -66,9 +67,10 @@ def __init__(self, name: str = None, description: str = None, github: str = None
self.install_dir = install_dir
self.updates_ignored = updates_ignored
self.symlink = symlink
self.manual_update = manual_update # True when the user is manually installing/upgrading an AppImage file

def __repr__(self):
return "{} (name={}, github={})".format(self.__class__.__name__, self.name, self.github)
return f"{self.__class__.__name__} (name={self.name}, repository={self.repository})"

def can_be_installed(self):
return not self.installed and self.url_download
Expand Down
Loading

0 comments on commit 6f7e4db

Please sign in to comment.