This commit is contained in:
Vinícius Moreira
2019-11-01 11:43:39 -03:00
committed by GitHub
18 changed files with 135 additions and 29 deletions

View File

@@ -4,6 +4,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.7.2] 2019-11-01
### Improvements
- Snap
- not showing **License** in the info window if it defined as **unset**
- Flatpak:
- "Remotes not set" warning informing to the user that Flatpak support can be disabled
- showing suggestions if the user changes the application types available and there are no applications installed
- i18n: spanish contributions by [fitojb](https://github.com/fitojb)
- minor labels improvements
### UI
- Displaying a **verified** green icon next to a verified publisher's name
### Fixes
- Snap
- The application crashes due to Snap API checking when snap is not installed ( introduced in **0.7.1** )
## [0.7.1] 2019-10-25 ## [0.7.1] 2019-10-25
### Features ### Features
- Snap: - Snap:

View File

@@ -1,4 +1,4 @@
__version__ = '0.7.1' __version__ = '0.7.2'
__app_name__ = 'bauh' __app_name__ = 'bauh'
import os import os

View File

@@ -9,7 +9,7 @@ from bauh.api.abstract.disk import DiskCacheLoader
from bauh.api.abstract.handler import ProcessWatcher from bauh.api.abstract.handler import ProcessWatcher
from bauh.api.abstract.model import PackageHistory, PackageUpdate, SoftwarePackage, PackageSuggestion from bauh.api.abstract.model import PackageHistory, PackageUpdate, SoftwarePackage, PackageSuggestion
from bauh.api.abstract.view import MessageType from bauh.api.abstract.view import MessageType
from bauh.commons.html import strip_html from bauh.commons.html import strip_html, bold
from bauh.commons.system import SystemProcess, ProcessHandler from bauh.commons.system import SystemProcess, ProcessHandler
from bauh.gems.flatpak import flatpak, suggestions from bauh.gems.flatpak import flatpak, suggestions
from bauh.gems.flatpak.constants import FLATHUB_API_URL from bauh.gems.flatpak.constants import FLATHUB_API_URL
@@ -253,7 +253,8 @@ class FlatpakManager(SoftwareManager):
def list_warnings(self, internet_available: bool) -> List[str]: def list_warnings(self, internet_available: bool) -> List[str]:
if flatpak.is_installed(): if flatpak.is_installed():
if not flatpak.has_remotes_set(): if not flatpak.has_remotes_set():
return [self.i18n['flatpak.notification.no_remotes']] return [self.i18n['flatpak.notification.no_remotes'],
self.i18n['flatpak.notification.disable'].format(bold('Flatpak'), bold(self.i18n['manage_window.settings.gems']))]
def list_suggestions(self, limit: int) -> List[PackageSuggestion]: def list_suggestions(self, limit: int) -> List[PackageSuggestion]:
cli_version = flatpak.get_version() cli_version = flatpak.get_version()

View File

@@ -1,5 +1,6 @@
gem.flatpak.info=Applications available in the repositories configured on your system gem.flatpak.info=Applications available in the repositories configured on your system
flatpak.notification.no_remotes=No Flatpak remotes set. It will not be possible to search for Flatpak apps. flatpak.notification.no_remotes=No Flatpak remotes set. It will not be possible to search for Flatpak apps.
flatpak.notification.disable=If you do not want to use Flatpak applications, uncheck {} in {}
flatpak.downgrade.impossible.title=Error flatpak.downgrade.impossible.title=Error
flatpak.downgrade.impossible.body=Impossible to downgrade: the app is in its first version flatpak.downgrade.impossible.body=Impossible to downgrade: the app is in its first version
flatpak.downgrade.commits=Reading package commits flatpak.downgrade.commits=Reading package commits

View File

@@ -19,6 +19,7 @@ flatpak.info.subject=tema
flatpak.info.type=tipo flatpak.info.type=tipo
flatpak.info.version=versión flatpak.info.version=versión
flatpak.notification.no_remotes=No hay repositorios (remotes) Flatpak configurados. No será posible buscar aplicativos Flatpak. flatpak.notification.no_remotes=No hay repositorios (remotes) Flatpak configurados. No será posible buscar aplicativos Flatpak.
flatpak.notification.disable=Si no desea usar aplicativos Flatpak, desmarque {} en {}
flatpak.downgrade.impossible.title=Error flatpak.downgrade.impossible.title=Error
flatpak.downgrade.impossible.body=Imposible revertir la versión: el aplicativo está en su primera versión flatpak.downgrade.impossible.body=Imposible revertir la versión: el aplicativo está en su primera versión
flatpak.history.date=fecha flatpak.history.date=fecha

View File

@@ -19,6 +19,7 @@ flatpak.info.subject=assunto
flatpak.info.type=tipo flatpak.info.type=tipo
flatpak.info.version=versão flatpak.info.version=versão
flatpak.notification.no_remotes=Não há repositórios (remotes) Flatpak configurados. Não será possível buscar aplicativos Flatpak. flatpak.notification.no_remotes=Não há repositórios (remotes) Flatpak configurados. Não será possível buscar aplicativos Flatpak.
flatpak.notification.disable=Se não deseja usar aplicativos Flatpak, desmarque {} em {}
flatpak.downgrade.impossible.title=Erro flatpak.downgrade.impossible.title=Erro
flatpak.downgrade.impossible.body=Impossível reverter a versão: o aplicativo está na sua primeira versão flatpak.downgrade.impossible.body=Impossível reverter a versão: o aplicativo está na sua primeira versão
flatpak.history.date=data flatpak.history.date=data

View File

@@ -45,7 +45,8 @@ class SnapManager(SoftwareManager):
name=app_json.get('name'), name=app_json.get('name'),
version=app_json.get('version'), version=app_json.get('version'),
latest_version=app_json.get('version'), latest_version=app_json.get('version'),
description=app_json.get('description', app_json.get('summary'))) description=app_json.get('description', app_json.get('summary')),
verified_publisher=app_json.get('developer_validation', '') == 'verified')
if app.publisher and app.publisher.endswith('*'): if app.publisher and app.publisher.endswith('*'):
app.verified_publisher = True app.verified_publisher = True
@@ -140,6 +141,9 @@ class SnapManager(SoftwareManager):
if info.get('commands'): if info.get('commands'):
info['commands'] = ' '.join(info['commands']) info['commands'] = ' '.join(info['commands'])
if info.get('license') and info['license'] == 'unset':
del info['license']
return info return info
def get_history(self, pkg: SnapApplication) -> PackageHistory: def get_history(self, pkg: SnapApplication) -> PackageHistory:
@@ -197,17 +201,18 @@ class SnapManager(SoftwareManager):
pass pass
def list_warnings(self, internet_available: bool) -> List[str]: def list_warnings(self, internet_available: bool) -> List[str]:
if snap.is_installed() and not snap.is_snapd_running(): if snap.is_installed():
snap_bold = bold('Snap') if not snap.is_snapd_running():
return [self.i18n['snap.notification.snapd_unavailable'].format(bold('snapd'), snap_bold), snap_bold = bold('Snap')
self.i18n['snap.notification.snap.disable'].format(snap_bold, bold(self.i18n['manage_window.settings.gems']))] return [self.i18n['snap.notification.snapd_unavailable'].format(bold('snapd'), snap_bold),
self.i18n['snap.notification.snap.disable'].format(snap_bold, bold(self.i18n['manage_window.settings.gems']))]
if internet_available: elif internet_available:
available, output = snap.is_api_available() available, output = snap.is_api_available()
if not available: if not available:
self.logger.warning('It seems Snap API is not available. Search output: {}'.format(output)) self.logger.warning('It seems Snap API is not available. Search output: {}'.format(output))
return [self.i18n['snap.notifications.api.unavailable'].format(bold('Snaps'), bold('Snap'))] return [self.i18n['snap.notifications.api.unavailable'].format(bold('Snaps'), bold('Snap'))]
def _fill_suggestion(self, pkg_name: str, priority: SuggestionPriority, out: List[PackageSuggestion]): def _fill_suggestion(self, pkg_name: str, priority: SuggestionPriority, out: List[PackageSuggestion]):
res = self.http_client.get_json(SNAP_API_URL + '/search?q=package_name:{}'.format(pkg_name)) res = self.http_client.get_json(SNAP_API_URL + '/search?q=package_name:{}'.format(pkg_name))

View File

@@ -56,6 +56,9 @@ class SnapApplication(SoftwarePackage):
def get_disk_cache_path(self): def get_disk_cache_path(self):
return super(SnapApplication, self).get_disk_cache_path() + '/installed/' + self.name return super(SnapApplication, self).get_disk_cache_path() + '/installed/' + self.name
def is_trustable(self) -> bool:
return self.verified_publisher
def get_data_to_cache(self): def get_data_to_cache(self):
return { return {
"icon_url": self.icon_url, "icon_url": self.icon_url,

View File

@@ -1,5 +1,5 @@
gem.snap.info=Applications published at https://snapcraft.io/store gem.snap.info=Applications published at https://snapcraft.io/store
snap.notification.snapd_unavailable={} seems not to be installed or enabled. {} packages will not be available. snap.notification.snapd_unavailable={} seems not to be started or enabled. {} packages will not be available.
snap.notification.snap.disable=If you do not want to use Snap applications, uncheck {} in {} snap.notification.snap.disable=If you do not want to use Snap applications, uncheck {} in {}
snap.notifications.api.unavailable=It seems the {} API is unavailable at the moment. It will not be possible to search for new {} applications. snap.notifications.api.unavailable=It seems the {} API is unavailable at the moment. It will not be possible to search for new {} applications.
snap.action.refresh.status=Refreshing snap.action.refresh.status=Refreshing

View File

@@ -3,14 +3,13 @@ snap.info.commands=comandos
snap.info.contact=contacto snap.info.contact=contacto
snap.info.description=descripción snap.info.description=descripción
snap.info.license=licencia snap.info.license=licencia
snap.info.license.unset=no está definida
snap.info.revision=revisión snap.info.revision=revisión
snap.info.tracking=tracking snap.info.tracking=tracking
snap.info.installed=instalado snap.info.installed=instalado
snap.info.publisher=publicador snap.info.publisher=publicador
snap.info.version=versión snap.info.version=versión
snap.info.size=tamaño snap.info.size=tamaño
snap.notification.snapd_unavailable={} no parece estar instalado o habilitado. Los paquetes {} estarán indisponibles. snap.notification.snapd_unavailable={} parece no estar inicializado o habilitado. Los paquetes {} estarán indisponibles.
snap.notification.snap.disable=Si no desea usar aplicativos Snap, desmarque {} en {} snap.notification.snap.disable=Si no desea usar aplicativos Snap, desmarque {} en {}
snap.notifications.api.unavailable=Parece que la API de {} no está disponible en este momento. No será posible buscar nuevos aplicativos {}. snap.notifications.api.unavailable=Parece que la API de {} no está disponible en este momento. No será posible buscar nuevos aplicativos {}.
snap.action.refresh.status=Actualizando snap.action.refresh.status=Actualizando

View File

@@ -3,14 +3,13 @@ snap.info.commands=comandos
snap.info.contact=contato snap.info.contact=contato
snap.info.description=descrição snap.info.description=descrição
snap.info.license=licença snap.info.license=licença
snap.info.license.unset=não definida
snap.info.revision=revisão snap.info.revision=revisão
snap.info.tracking=tracking snap.info.tracking=tracking
snap.info.installed=instalado snap.info.installed=instalado
snap.info.publisher=publicador snap.info.publisher=publicador
snap.info.version=versão snap.info.version=versão
snap.info.size=tamanho snap.info.size=tamanho
snap.notification.snapd_unavailable={} não parece estar instalado ou habilitado. Os pacotes {} estarão indisponíveis. snap.notification.snapd_unavailable={} parece não estar inicializado ou habilitado. Os pacotes {} estarão indisponíveis.
snap.notification.snap.disable=Se não deseja usar aplicativos Snap, desmarque {} em {} snap.notification.snap.disable=Se não deseja usar aplicativos Snap, desmarque {} em {}
snap.notifications.api.unavailable=Parece que a API de {} está indisponível no momento. Não será possível buscar novos aplicativos {}. snap.notifications.api.unavailable=Parece que a API de {} está indisponível no momento. Não será possível buscar novos aplicativos {}.
snap.action.refresh.status=Atualizando snap.action.refresh.status=Atualizando

View File

@@ -11,10 +11,10 @@ from PyQt5.QtWidgets import QTableWidget, QTableView, QMenu, QAction, QTableWidg
from bauh.api.abstract.cache import MemoryCache from bauh.api.abstract.cache import MemoryCache
from bauh.api.abstract.model import PackageStatus from bauh.api.abstract.model import PackageStatus
from bauh.commons.html import strip_html from bauh.commons.html import strip_html
from bauh.view.util import resource
from bauh.view.qt import dialog from bauh.view.qt import dialog
from bauh.view.qt.components import IconButton from bauh.view.qt.components import IconButton
from bauh.view.qt.view_model import PackageView, PackageViewStatus from bauh.view.qt.view_model import PackageView, PackageViewStatus
from bauh.view.util import resource
INSTALL_BT_STYLE = 'background: {back}; color: white; font-size: 10px; font-weight: bold' INSTALL_BT_STYLE = 'background: {back}; color: white; font-size: 10px; font-weight: bold'
@@ -76,6 +76,7 @@ class AppsTable(QTableWidget):
self.setHorizontalHeaderLabels(['' for _ in range(self.columnCount())]) self.setHorizontalHeaderLabels(['' for _ in range(self.columnCount())])
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.icon_logo = QIcon(resource.get_path('img/logo.svg')) self.icon_logo = QIcon(resource.get_path('img/logo.svg'))
self.pixmap_verified = QPixmap(resource.get_path('img/verified.svg'))
self.network_man = QNetworkAccessManager() self.network_man = QNetworkAccessManager()
self.network_man.finished.connect(self._load_icon_and_cache) self.network_man.finished.connect(self._load_icon_and_cache)
@@ -372,7 +373,7 @@ class AppsTable(QTableWidget):
self.setItem(pkg.table_index, col, item) self.setItem(pkg.table_index, col, item)
def _set_col_publisher(self, col: int, pkg: PackageView): def _set_col_publisher(self, col: int, pkg: PackageView):
item = QLabel() item = QToolBar()
publisher = pkg.model.get_publisher() publisher = pkg.model.get_publisher()
full_publisher = None full_publisher = None
@@ -384,19 +385,25 @@ class AppsTable(QTableWidget):
if len(publisher) > PUBLISHER_MAX_SIZE: if len(publisher) > PUBLISHER_MAX_SIZE:
publisher = full_publisher[0: PUBLISHER_MAX_SIZE - 3] + '...' publisher = full_publisher[0: PUBLISHER_MAX_SIZE - 3] + '...'
if len(publisher) < PUBLISHER_MAX_SIZE:
publisher = publisher + ' ' * (PUBLISHER_MAX_SIZE - len(publisher))
if not publisher: if not publisher:
if not pkg.model.installed: if not pkg.model.installed:
item.setStyleSheet('QLabel { color: red; }') item.setStyleSheet('QLabel { color: red; }')
publisher = self.i18n['unknown'] publisher = self.i18n['unknown']
item.setText(' {} '.format(publisher)) lb_name = QLabel(' {}'.format(publisher))
item.addWidget(lb_name)
if publisher and full_publisher: if publisher and full_publisher:
item.setToolTip(self.i18n['publisher'].capitalize() + ((': ' + full_publisher) if full_publisher else '')) lb_name.setToolTip(self.i18n['publisher'].capitalize() + ((': ' + full_publisher) if full_publisher else ''))
if pkg.model.is_trustable():
lb_verified = QLabel()
lb_verified.setPixmap(self.pixmap_verified)
lb_verified.setToolTip(self.i18n['publisher.verified'].capitalize())
item.addWidget(lb_verified)
else:
lb_name.setText(lb_name.text() + " ")
self.setCellWidget(pkg.table_index, col, item) self.setCellWidget(pkg.table_index, col, item)

View File

@@ -32,7 +32,7 @@ class GemSelectorPanel(QWidget):
self.bt_proceed.setStyleSheet(css.OK_BUTTON) self.bt_proceed.setStyleSheet(css.OK_BUTTON)
self.bt_proceed.clicked.connect(self.save) self.bt_proceed.clicked.connect(self.save)
self.bt_exit = QPushButton(i18n['exit'].capitalize()) self.bt_exit = QPushButton(i18n['close'].capitalize())
self.bt_exit.clicked.connect(self.exit) self.bt_exit.clicked.connect(self.exit)
self.gem_map = {} self.gem_map = {}
@@ -91,6 +91,7 @@ class GemSelectorPanel(QWidget):
self.manager.reset_cache() self.manager.reset_cache()
self.manager.prepare() self.manager.prepare()
self.window.verify_warnings() self.window.verify_warnings()
self.window.types_changed = True
self.window.refresh_apps() self.window.refresh_apps()
self.close() self.close()

View File

@@ -284,6 +284,7 @@ class ManageWindow(QWidget):
self.progress_controll_enabled = True self.progress_controll_enabled = True
self.recent_installation = False self.recent_installation = False
self.recent_uninstall = False self.recent_uninstall = False
self.types_changed = False
self.dialog_about = None self.dialog_about = None
self.first_refresh = suggestions self.first_refresh = suggestions
@@ -474,6 +475,7 @@ class ManageWindow(QWidget):
self.update_pkgs(res['installed'], as_installed=as_installed, types=res['types'], keep_filters=self.recent_uninstall and res['types']) self.update_pkgs(res['installed'], as_installed=as_installed, types=res['types'], keep_filters=self.recent_uninstall and res['types'])
self.first_refresh = False self.first_refresh = False
self.recent_uninstall = False self.recent_uninstall = False
self.types_changed = False
self._hide_fields_after_recent_installation() self._hide_fields_after_recent_installation()
def uninstall_app(self, app: PackageView): def uninstall_app(self, app: PackageView):
@@ -640,7 +642,7 @@ class ManageWindow(QWidget):
commons.apply_filters(pkgv, filters, pkgs_info) commons.apply_filters(pkgv, filters, pkgs_info)
if pkgs_info['apps_count'] == 0: if pkgs_info['apps_count'] == 0:
if self.first_refresh: if self.first_refresh or self.types_changed:
self._begin_search('') self._begin_search('')
self.thread_suggestions.start() self.thread_suggestions.start()
return return

View File

@@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
viewBox="0 0 8.0000001 8"
enable-background="new 0 0 26 26"
id="svg817"
sodipodi:docname="verified.svg"
width="8"
height="8"
inkscape:version="0.92.4 5da689c313, 2019-01-14">
<metadata
id="metadata823">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs821" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1019"
id="namedview819"
showgrid="false"
showborder="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:zoom="1.1923077"
inkscape:cx="-358.68351"
inkscape:cy="156.16568"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg817" />
<path
d="M 0.09230771,4.4 C 0.03076924,4.32 0,4.2 0,4.12 0,4.04 0.03076924,3.92 0.09230771,3.84 l 0.4307693,-0.56 c 0.12307694,-0.16 0.30769231,-0.16 0.43076928,0 l 0.0307687,0.04 1.69230781,2.36 c 0.061539,0.08 0.1538463,0.08 0.2153848,0 L 7.0153863,0.12 h 0.030767 v 0 c 0.1230774,-0.16 0.3076932,-0.16 0.4307692,0 L 7.907692,0.68 c 0.1230773,0.16 0.1230773,0.4 0,0.56 v 0 L 2.9846157,7.88 C 2.9230775,7.96 2.8615389,8 2.7692313,8 2.6769233,8 2.6153851,7.96 2.5538465,7.88 L 0.15384617,4.52 Z"
id="path815"
inkscape:connector-curvature="0"
style="fill:#00aa00;stroke-width:0.35082322" />
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@@ -147,3 +147,5 @@ screenshots.download.no_content=No content to display
screenshots.download.no_response=Image not found screenshots.download.no_response=Image not found
continue=continue continue=continue
stable=stable stable=stable
close=close
publisher.verified=verified

View File

@@ -191,3 +191,5 @@ screenshots.download.no_content=No hay contenido para mostrar
screenshots.download.no_response=No se encontró la imagen screenshots.download.no_response=No se encontró la imagen
continue=continuar continue=continuar
stable=estable stable=estable
close=cerrar
publisher.verified=verificado

View File

@@ -194,3 +194,5 @@ screenshots.download.no_content=Sem conteúdo para exibir
screenshots.download.no_response=Imagem não encontrada screenshots.download.no_response=Imagem não encontrada
continue=continuar continue=continuar
stable=estável stable=estável
close=fechar
publisher.verified=verificado