mirror of
https://github.com/spalencsar/bearhub.git
synced 2026-07-07 10:34:15 +02:00
[snap] feature -> new custom action 'change channel'
This commit is contained in:
@@ -12,6 +12,7 @@ from bauh.api.abstract.model import SoftwarePackage, PackageHistory, PackageUpda
|
||||
SuggestionPriority, CustomSoftwareAction, PackageStatus
|
||||
from bauh.api.abstract.view import SingleSelectComponent, SelectViewType, InputOption, ViewComponent, PanelComponent, \
|
||||
FormComponent
|
||||
from bauh.api.exception import NoInternetException
|
||||
from bauh.commons import resource, internet
|
||||
from bauh.commons.category import CategoriesDownloader
|
||||
from bauh.commons.config import save_config
|
||||
@@ -47,7 +48,13 @@ class SnapManager(SoftwareManager):
|
||||
icon_path=resource.get_path('img/refresh.svg', context.get_view_path()),
|
||||
manager_method='refresh',
|
||||
requires_root=True,
|
||||
i18n_confirm_key='snap.action.refresh.confirm')
|
||||
i18n_confirm_key='snap.action.refresh.confirm'),
|
||||
CustomSoftwareAction(i18n_status_key='snap.action.channel.status',
|
||||
i18n_label_key='snap.action.channel.label',
|
||||
i18n_confirm_key='snap.action.channel.confirm',
|
||||
icon_path=resource.get_path('img/refresh.svg', context.get_view_path()),
|
||||
manager_method='change_channel',
|
||||
requires_root=True)
|
||||
]
|
||||
|
||||
def _fill_categories(self, app: SnapApplication):
|
||||
@@ -253,6 +260,28 @@ class SnapManager(SoftwareManager):
|
||||
def refresh(self, pkg: SnapApplication, root_password: str, watcher: ProcessWatcher) -> bool:
|
||||
return ProcessHandler(watcher).handle_simple(snap.refresh_and_stream(pkg.name, root_password))[0]
|
||||
|
||||
def change_channel(self, pkg: SnapApplication, root_password: str, watcher: ProcessWatcher) -> bool:
|
||||
if not internet.is_available():
|
||||
raise NoInternetException()
|
||||
|
||||
try:
|
||||
channel = self._request_channel_installation(pkg=pkg,
|
||||
snap_config=None,
|
||||
snapd_client=SnapdClient(self.logger),
|
||||
watcher=watcher,
|
||||
exclude_current=True)
|
||||
|
||||
if not channel:
|
||||
watcher.show_message(title=self.i18n['snap.action.channel.label'],
|
||||
body=self.i18n['snap.action.channel.error.no_channel'])
|
||||
return True
|
||||
|
||||
return ProcessHandler(watcher).handle_simple(snap.refresh_and_stream(app_name=pkg.name,
|
||||
root_password=root_password,
|
||||
channel=channel))[0]
|
||||
except:
|
||||
return True
|
||||
|
||||
def _start_category_task(self, task_man: TaskManager):
|
||||
if task_man:
|
||||
task_man.register_task('snap_cats', self.i18n['task.download_categories'].format('Snap'), get_icon_path())
|
||||
@@ -425,8 +454,8 @@ class SnapManager(SoftwareManager):
|
||||
except:
|
||||
return False, [traceback.format_exc()]
|
||||
|
||||
def _request_channel_installation(self, pkg: SnapApplication, snap_config: dict, snapd_client: SnapdClient, watcher: ProcessWatcher) -> Optional[str]:
|
||||
if snap_config['install_channel']:
|
||||
def _request_channel_installation(self, pkg: SnapApplication, snap_config: Optional[dict], snapd_client: SnapdClient, watcher: ProcessWatcher, exclude_current: bool = False) -> Optional[str]:
|
||||
if snap_config is None or snap_config['install_channel']:
|
||||
try:
|
||||
data = [r for r in snapd_client.find_by_name(pkg.name) if r['name'] == pkg.name]
|
||||
except:
|
||||
@@ -439,11 +468,31 @@ class SnapManager(SoftwareManager):
|
||||
if not data[0].get('channels'):
|
||||
self.logger.info("No channel available for '{}'. Skipping selection.".format(pkg.name))
|
||||
else:
|
||||
opts = [InputOption(label=c, value=c) for c in sorted(data[0]['channels'].keys())]
|
||||
def_opt = [o for o in opts if o.value == 'latest/{}'.format(data[0].get('channel', 'stable'))]
|
||||
if pkg.channel:
|
||||
current_channel = pkg.channel if '/' in pkg.channel else 'latest/{}'.format(pkg.channel)
|
||||
else:
|
||||
current_channel = 'latest/{}'.format(data[0].get('channel', 'stable'))
|
||||
|
||||
opts = []
|
||||
def_opt = None
|
||||
for channel in sorted(data[0]['channels'].keys()):
|
||||
if exclude_current:
|
||||
if channel != current_channel:
|
||||
opts.append(InputOption(label=channel, value=channel))
|
||||
else:
|
||||
op = InputOption(label=channel, value=channel)
|
||||
opts.append(op)
|
||||
|
||||
if not def_opt and channel == current_channel:
|
||||
def_opt = op
|
||||
|
||||
if not opts:
|
||||
self.logger.info("No different channel available for '{}'. Skipping selection.".format(pkg.name))
|
||||
return
|
||||
|
||||
select = SingleSelectComponent(label='',
|
||||
options=opts,
|
||||
default_option=def_opt[0] if def_opt else opts[0],
|
||||
default_option=def_opt if def_opt else opts[0],
|
||||
type_=SelectViewType.RADIO)
|
||||
|
||||
if not watcher.request_confirmation(title=self.i18n['snap.install.available_channels.title'],
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
gem.snap.info=Aplicacions publicades a https://snapcraft.io/store
|
||||
snap.action.channel.confirm=Change channel of {} ?
|
||||
snap.action.channel.error.no_channel=No available channel for {}
|
||||
snap.action.channel.label=Change channel
|
||||
snap.action.channel.status=Changing channel
|
||||
snap.action.refresh.confirm=Actualitza {} ?
|
||||
snap.action.refresh.label=Actualitza
|
||||
snap.action.refresh.status=S’està actualitzant
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
gem.snap.info=Anwendungen von https://snapcraft.io/store
|
||||
snap.action.channel.error.no_channel=No available channel for {}
|
||||
snap.action.channel.confirm=Change channel of {} ?
|
||||
snap.action.channel.label=Change channel
|
||||
snap.action.channel.status=Changing channel
|
||||
snap.action.refresh.confirm=Erneuern {} ?
|
||||
snap.action.refresh.label=Erneuern
|
||||
snap.action.refresh.status=Erneuern
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
gem.snap.info=Applications published at https://snapcraft.io/store
|
||||
snap.action.channel.confirm=Change channel of {} ?
|
||||
snap.action.channel.error.no_channel=No available channel for {}
|
||||
snap.action.channel.label=Change channel
|
||||
snap.action.channel.status=Changing channel
|
||||
snap.action.refresh.confirm=Refresh {} ?
|
||||
snap.action.refresh.label=Refresh
|
||||
snap.action.refresh.status=Refreshing
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
gem.snap.info=Aplicativos publicados en https://snapcraft.io/store
|
||||
snap.action.channel.confirm=Cambiar canal de {}?
|
||||
snap.action.channel.error.no_channel=No hay canal disponible para {}
|
||||
snap.action.channel.status=Cambiando canal
|
||||
snap.action.channel.label=Cambiar canal
|
||||
snap.action.refresh.confirm=Actualizar {} ?
|
||||
snap.action.refresh.label=Actualizar
|
||||
snap.action.refresh.status=Actualizando
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
gem.snap.info=Applicazioni pubblicate su https://snapcraft.io/store
|
||||
snap.action.channel.confirm=Change channel of {} ?
|
||||
snap.action.channel.error.no_channel=No available channel for {}
|
||||
snap.action.channel.label=Change channel
|
||||
snap.action.channel.status=Changing channel
|
||||
snap.action.refresh.confirm=Ripristina {} ?
|
||||
snap.action.refresh.label=Ripristina
|
||||
snap.action.refresh.status=Ripristinare
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
gem.snap.info=Aplicativos publicados em https://snapcraft.io/store
|
||||
snap.action.channel.confirm=Alterar canal de {} ?
|
||||
snap.action.channel.error.no_channel=Nenhum canal disponível para {}
|
||||
snap.action.channel.label=Alterar canal
|
||||
snap.action.channel.status=Alterando canal
|
||||
snap.action.refresh.confirm=Atualizar {} ?
|
||||
snap.action.refresh.label=Atualizar
|
||||
snap.action.refresh.status=Atualizando
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
gem.snap.info=Приложения, опубликованные на https://snapcraft.io/store
|
||||
snap.action.channel.confirm=Change channel of {} ?
|
||||
snap.action.channel.error.no_channel=No available channel for {}
|
||||
snap.action.channel.label=Change channel
|
||||
snap.action.channel.status=Changing channel
|
||||
snap.action.refresh.confirm=Обновить {} ?
|
||||
snap.action.refresh.label=Обновить
|
||||
snap.action.refresh.status=Обновляется
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
gem.snap.info=https://snapcraft.io/store adresinde yayınlanan uygulamalar
|
||||
snap.action.channel.confirm=Change channel of {} ?
|
||||
snap.action.channel.error.no_channel=No available channel for {}
|
||||
snap.action.channel.label=Change channel
|
||||
snap.action.channel.status=Changing channel
|
||||
snap.action.refresh.confirm=Yenile {} ?
|
||||
snap.action.refresh.label=Yenile
|
||||
snap.action.refresh.status=Yenileniyor
|
||||
|
||||
@@ -37,8 +37,13 @@ def downgrade_and_stream(app_name: str, root_password: str) -> SimpleProcess:
|
||||
shell=True)
|
||||
|
||||
|
||||
def refresh_and_stream(app_name: str, root_password: str) -> SimpleProcess:
|
||||
return SimpleProcess(cmd=[BASE_CMD, 'refresh', app_name],
|
||||
def refresh_and_stream(app_name: str, root_password: str, channel: Optional[str] = None) -> SimpleProcess:
|
||||
cmd = [BASE_CMD, 'refresh', app_name]
|
||||
|
||||
if channel:
|
||||
cmd.append('--channel={}'.format(channel))
|
||||
|
||||
return SimpleProcess(cmd=cmd,
|
||||
root_password=root_password,
|
||||
error_phrases={'no updates available'},
|
||||
shell=True)
|
||||
|
||||
@@ -11,7 +11,7 @@ from PyQt5.QtWidgets import QTableWidget, QTableView, QMenu, QAction, QTableWidg
|
||||
QHeaderView, QLabel, QHBoxLayout, QToolBar, QSizePolicy
|
||||
|
||||
from bauh.api.abstract.cache import MemoryCache
|
||||
from bauh.api.abstract.model import PackageStatus
|
||||
from bauh.api.abstract.model import PackageStatus, CustomSoftwareAction
|
||||
from bauh.commons.html import strip_html, bold
|
||||
from bauh.view.qt import dialog
|
||||
from bauh.view.qt.colors import GREEN, BROWN
|
||||
@@ -166,31 +166,34 @@ class AppsTable(QTableWidget):
|
||||
menu_row.addAction(action_ignore_updates)
|
||||
|
||||
if bool(pkg.model.get_custom_supported_actions()):
|
||||
for action in pkg.model.get_custom_supported_actions():
|
||||
item = QAction(self.i18n[action.i18n_label_key])
|
||||
|
||||
if action.icon_path:
|
||||
item.setIcon(QIcon(action.icon_path))
|
||||
|
||||
def custom_action():
|
||||
if action.i18n_confirm_key:
|
||||
body = self.i18n[action.i18n_confirm_key].format(bold(pkg.model.name))
|
||||
else:
|
||||
body = '{} ?'.format(self.i18n[action.i18n_label_key])
|
||||
|
||||
if dialog.ask_confirmation(
|
||||
title=self.i18n[action.i18n_label_key],
|
||||
body=self._parag(body),
|
||||
i18n=self.i18n):
|
||||
self.window.begin_execute_custom_action(pkg, action)
|
||||
|
||||
item.triggered.connect(custom_action)
|
||||
menu_row.addAction(item)
|
||||
actions = [self._map_custom_action(pkg, a) for a in pkg.model.get_custom_supported_actions()]
|
||||
menu_row.addActions(actions)
|
||||
|
||||
menu_row.adjustSize()
|
||||
menu_row.popup(QCursor.pos())
|
||||
menu_row.exec_()
|
||||
|
||||
def _map_custom_action(self, pkg: PackageView, action: CustomSoftwareAction) -> QAction:
|
||||
item = QAction(self.i18n[action.i18n_label_key])
|
||||
|
||||
if action.icon_path:
|
||||
item.setIcon(QIcon(action.icon_path))
|
||||
|
||||
def custom_action():
|
||||
if action.i18n_confirm_key:
|
||||
body = self.i18n[action.i18n_confirm_key].format(bold(pkg.model.name))
|
||||
else:
|
||||
body = '{} ?'.format(self.i18n[action.i18n_label_key])
|
||||
|
||||
if dialog.ask_confirmation(
|
||||
title=self.i18n[action.i18n_label_key],
|
||||
body=self._parag(body),
|
||||
i18n=self.i18n):
|
||||
self.window.begin_execute_custom_action(pkg, action)
|
||||
|
||||
item.triggered.connect(custom_action)
|
||||
return item
|
||||
|
||||
def refresh(self, pkg: PackageView):
|
||||
self._update_row(pkg, update_check_enabled=False, change_update_col=False)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user