[snap] feature -> allowing to select an available channel during the installation process

This commit is contained in:
Vinicius Moreira
2020-09-06 01:10:13 -03:00
parent bf6361a6d1
commit 26fa25cebb
20 changed files with 135 additions and 14 deletions

View File

@@ -24,6 +24,15 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
<p align="center"> <p align="center">
<img src="https://raw.githubusercontent.com/vinifmor/bauh-files/master/pictures/releases/0.9.7/unmark_pkgbuild.png"> <img src="https://raw.githubusercontent.com/vinifmor/bauh-files/master/pictures/releases/0.9.7/unmark_pkgbuild.png">
</p> </p>
- Snap
- new settings property **install_channel**: it allows to select an available channel during the application installation. Default: false.
<p align="center">
<img src="https://raw.githubusercontent.com/vinifmor/bauh-files/master/pictures/releases/0.9.7/snap_config.png">
</p>
<p align="center">
<img src="https://raw.githubusercontent.com/vinifmor/bauh-files/master/pictures/releases/0.9.7/snap_channels.png">
</p>
### Improvements ### Improvements
- AppImage - AppImage

View File

@@ -120,6 +120,10 @@ installation_level: null # defines a default installation level: user or system.
- Supported actions: search, install, uninstall, launch, downgrade - Supported actions: search, install, uninstall, launch, downgrade
- Custom actions: refresh - Custom actions: refresh
- The configuration file is located at **~/.config/bauh/snap.yml** and it allows the following customizations:
```
install_channel: false # it allows to select an available channel during the application installation. Default: false
```
- Required dependencies: - Required dependencies:
- Any distro: **snapd** ( it must be enabled after its installation. Details at https://snapcraft.io/docs/installing-snapd ) - Any distro: **snapd** ( it must be enabled after its installation. Details at https://snapcraft.io/docs/installing-snapd )

View File

@@ -350,7 +350,7 @@ class SoftwareManager(ABC):
""" """
pass pass
def save_settings(self, component: ViewComponent) -> Tuple[bool, List[str]]: def save_settings(self, component: ViewComponent) -> Tuple[bool, Optional[List[str]]]:
""" """
:return: a tuple with a bool informing if the settings were saved and a list of error messages :return: a tuple with a bool informing if the settings were saved and a list of error messages
""" """

View File

@@ -723,7 +723,7 @@ class AppImageManager(SoftwareManager):
return PanelComponent([FormComponent(updater_opts, self.i18n['appimage.config.db_updates'])]) return PanelComponent([FormComponent(updater_opts, self.i18n['appimage.config.db_updates'])])
def save_settings(self, component: PanelComponent) -> Tuple[bool, List[str]]: def save_settings(self, component: PanelComponent) -> Tuple[bool, Optional[List[str]]]:
config = read_config() config = read_config()
panel = component.components[0] panel = component.components[0]

View File

@@ -2682,7 +2682,7 @@ class ArchManager(SoftwareManager):
return PanelComponent([FormComponent(fields, spaces=False)]) return PanelComponent([FormComponent(fields, spaces=False)])
def save_settings(self, component: PanelComponent) -> Tuple[bool, List[str]]: def save_settings(self, component: PanelComponent) -> Tuple[bool, Optional[List[str]]]:
config = read_config() config = read_config()
form_install = component.components[0] form_install = component.components[0]

View File

@@ -5,7 +5,7 @@ from datetime import datetime
from math import floor from math import floor
from pathlib import Path from pathlib import Path
from threading import Thread from threading import Thread
from typing import List, Set, Type, Tuple from typing import List, Set, Type, Tuple, Optional
from bauh.api.abstract.controller import SearchResult, SoftwareManager, ApplicationContext, UpgradeRequirements, \ from bauh.api.abstract.controller import SearchResult, SoftwareManager, ApplicationContext, UpgradeRequirements, \
UpgradeRequirement, TransactionResult UpgradeRequirement, TransactionResult
@@ -570,7 +570,7 @@ class FlatpakManager(SoftwareManager):
return PanelComponent([FormComponent(fields, self.i18n['installation'].capitalize())]) return PanelComponent([FormComponent(fields, self.i18n['installation'].capitalize())])
def save_settings(self, component: PanelComponent) -> Tuple[bool, List[str]]: def save_settings(self, component: PanelComponent) -> Tuple[bool, Optional[List[str]]]:
config = read_config() config = read_config()
config['installation_level'] = component.components[0].components[0].get_selected() config['installation_level'] = component.components[0].components[0].get_selected()

View File

@@ -1,10 +1,11 @@
import os import os
from bauh.api.constants import CACHE_PATH from bauh.api.constants import CACHE_PATH, CONFIG_PATH
from bauh.commons import resource from bauh.commons import resource
ROOT_DIR = os.path.dirname(os.path.abspath(__file__)) ROOT_DIR = os.path.dirname(os.path.abspath(__file__))
SNAP_CACHE_PATH = CACHE_PATH + '/snap' SNAP_CACHE_PATH = CACHE_PATH + '/snap'
CONFIG_FILE = '{}/snap.yml'.format(CONFIG_PATH)
CATEGORIES_FILE_PATH = SNAP_CACHE_PATH + '/categories.txt' CATEGORIES_FILE_PATH = SNAP_CACHE_PATH + '/categories.txt'
URL_CATEGORIES_FILE = 'https://raw.githubusercontent.com/vinifmor/bauh-files/master/snap/categories.txt' URL_CATEGORIES_FILE = 'https://raw.githubusercontent.com/vinifmor/bauh-files/master/snap/categories.txt'
SUGGESTIONS_FILE = 'https://raw.githubusercontent.com/vinifmor/bauh-files/master/snap/suggestions.txt' SUGGESTIONS_FILE = 'https://raw.githubusercontent.com/vinifmor/bauh-files/master/snap/suggestions.txt'

7
bauh/gems/snap/config.py Normal file
View File

@@ -0,0 +1,7 @@
from bauh.commons.config import read_config as read
from bauh.gems.snap import CONFIG_FILE
def read_config(update_file: bool = False) -> dict:
template = {'install_channel': False}
return read(CONFIG_FILE, template, update_file=update_file)

View File

@@ -2,7 +2,7 @@ import re
import time import time
import traceback import traceback
from threading import Thread from threading import Thread
from typing import List, Set, Type, Optional from typing import List, Set, Type, Optional, Tuple
from bauh.api.abstract.controller import SoftwareManager, SearchResult, ApplicationContext, UpgradeRequirements, \ from bauh.api.abstract.controller import SoftwareManager, SearchResult, ApplicationContext, UpgradeRequirements, \
TransactionResult TransactionResult
@@ -10,13 +10,17 @@ from bauh.api.abstract.disk import DiskCacheLoader
from bauh.api.abstract.handler import ProcessWatcher, TaskManager from bauh.api.abstract.handler import ProcessWatcher, TaskManager
from bauh.api.abstract.model import SoftwarePackage, PackageHistory, PackageUpdate, PackageSuggestion, \ from bauh.api.abstract.model import SoftwarePackage, PackageHistory, PackageUpdate, PackageSuggestion, \
SuggestionPriority, CustomSoftwareAction, PackageStatus SuggestionPriority, CustomSoftwareAction, PackageStatus
from bauh.api.abstract.view import SingleSelectComponent, SelectViewType, InputOption from bauh.api.abstract.view import SingleSelectComponent, SelectViewType, InputOption, ViewComponent, PanelComponent, \
FormComponent
from bauh.commons import resource, internet from bauh.commons import resource, internet
from bauh.commons.category import CategoriesDownloader from bauh.commons.category import CategoriesDownloader
from bauh.commons.config import save_config
from bauh.commons.html import bold from bauh.commons.html import bold
from bauh.commons.system import SystemProcess, ProcessHandler, new_root_subprocess, get_human_size_str from bauh.commons.system import SystemProcess, ProcessHandler, new_root_subprocess, get_human_size_str
from bauh.commons.view_utils import new_select
from bauh.gems.snap import snap, URL_CATEGORIES_FILE, SNAP_CACHE_PATH, CATEGORIES_FILE_PATH, SUGGESTIONS_FILE, \ from bauh.gems.snap import snap, URL_CATEGORIES_FILE, SNAP_CACHE_PATH, CATEGORIES_FILE_PATH, SUGGESTIONS_FILE, \
get_icon_path, snapd get_icon_path, snapd, CONFIG_FILE
from bauh.gems.snap.config import read_config
from bauh.gems.snap.model import SnapApplication from bauh.gems.snap.model import SnapApplication
from bauh.gems.snap.snapd import SnapdClient from bauh.gems.snap.snapd import SnapdClient
@@ -175,7 +179,20 @@ class SnapManager(SoftwareManager):
installed_names = {s['name'] for s in SnapdClient(self.logger).list_all_snaps()} installed_names = {s['name'] for s in SnapdClient(self.logger).list_all_snaps()}
res, output = ProcessHandler(watcher).handle_simple(snap.install_and_stream(pkg.name, pkg.confinement, root_password)) client = SnapdClient(self.logger)
snap_config = read_config()
try:
channel = self._request_channel_installation(pkg=pkg, snap_config=snap_config, snapd_client=client, watcher=watcher)
pkg.channel = channel
except:
watcher.print('Aborted by user')
return TransactionResult.fail()
res, output = ProcessHandler(watcher).handle_simple(snap.install_and_stream(app_name=pkg.name,
confinement=pkg.confinement,
root_password=root_password,
channel=channel))
if 'error:' in output: if 'error:' in output:
res = False res = False
@@ -247,6 +264,8 @@ class SnapManager(SoftwareManager):
task_man.finish_task('snap_cats') task_man.finish_task('snap_cats')
def prepare(self, task_manager: TaskManager, root_password: str, internet_available: bool): def prepare(self, task_manager: TaskManager, root_password: str, internet_available: bool):
Thread(target=read_config, args=(True,), daemon=True).start()
CategoriesDownloader(id_='snap', manager=self, http_client=self.http_client, logger=self.logger, CategoriesDownloader(id_='snap', manager=self, http_client=self.http_client, logger=self.logger,
url_categories_file=URL_CATEGORIES_FILE, disk_cache_dir=SNAP_CACHE_PATH, url_categories_file=URL_CATEGORIES_FILE, disk_cache_dir=SNAP_CACHE_PATH,
categories_path=CATEGORIES_FILE_PATH, categories_path=CATEGORIES_FILE_PATH,
@@ -382,3 +401,56 @@ class SnapManager(SoftwareManager):
def get_screenshots(self, pkg: SnapApplication) -> List[str]: def get_screenshots(self, pkg: SnapApplication) -> List[str]:
return pkg.screenshots if pkg.has_screenshots() else [] return pkg.screenshots if pkg.has_screenshots() else []
def get_settings(self, screen_width: int, screen_height: int) -> ViewComponent:
snap_config = read_config()
install_channel = new_select(label=self.i18n['snap.config.install_channel'],
opts=[(self.i18n['yes'].capitalize(), True, None),
(self.i18n['no'].capitalize(), False, None)],
value=bool(snap_config['install_channel']),
id_='install_channel',
max_width=200,
tip=self.i18n['snap.config.install_channel.tip'])
return PanelComponent([FormComponent([install_channel], self.i18n['installation'].capitalize())])
def save_settings(self, component: ViewComponent) -> Tuple[bool, Optional[List[str]]]:
config = read_config()
config['install_channel'] = component.components[0].components[0].get_selected()
try:
save_config(config, CONFIG_FILE)
return True, None
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']:
try:
data = [r for r in snapd_client.find_by_name(pkg.name) if r['name'] == pkg.name]
except:
self.logger.warning("snapd client could not retrieve channels for '{}'".format(pkg.name))
return
if not data:
self.logger.warning("snapd client could find a match for name '{}' when retrieving its channels".format(pkg.name))
else:
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'))]
select = SingleSelectComponent(label='',
options=opts,
default_option=def_opt[0] if def_opt else opts[0],
type_=SelectViewType.RADIO)
if not watcher.request_confirmation(title=self.i18n['snap.install.available_channels.title'],
body=self.i18n['snap.install.channel.body'] + ':',
components=[select],
confirmation_label=self.i18n['proceed'].capitalize(),
deny_label=self.i18n['cancel'].capitalize()):
raise Exception('aborted')
else:
return select.get_selected()

View File

@@ -2,6 +2,8 @@ gem.snap.info=Aplicacions publicades a https://snapcraft.io/store
snap.action.refresh.confirm=Actualitza {} ? snap.action.refresh.confirm=Actualitza {} ?
snap.action.refresh.label=Actualitza snap.action.refresh.label=Actualitza
snap.action.refresh.status=Sestà actualitzant snap.action.refresh.status=Sestà actualitzant
snap.config.install_channel=Display channels
snap.config.install_channel.tip=It allows to select one of the available channels for the given application to be installed
snap.info.channel=channel snap.info.channel=channel
snap.info.commands=ordres snap.info.commands=ordres
snap.info.contact=contacte snap.info.contact=contacte
@@ -18,6 +20,7 @@ snap.info.version=versió
snap.install.available_channels.help=Seleccioneu-ne un si voleu continuar snap.install.available_channels.help=Seleccioneu-ne un si voleu continuar
snap.install.available_channels.message=No hi ha un canal {} (stable) disponible per a {}. Però més avall nhi ha els següents snap.install.available_channels.message=No hi ha un canal {} (stable) disponible per a {}. Però més avall nhi ha els següents
snap.install.available_channels.title=Canals disponibles snap.install.available_channels.title=Canals disponibles
snap.install.channel.body=Select a channel to proceed
snap.notification.snap.disable=Si no voleu utilitzar aplicacions snap, desmarqueu {} a {} snap.notification.snap.disable=Si no voleu utilitzar aplicacions snap, desmarqueu {} a {}
snap.notification.snapd_unavailable=Sembla que no sha iniciat o activat {}. Els paquets {} no estaran disponibles. snap.notification.snapd_unavailable=Sembla que no sha iniciat o activat {}. Els paquets {} no estaran disponibles.
snap.notifications.api.unavailable=Sembla que lAPI de {} no està disponible en aquests moments. No podreu cercar aplicacions {} noves. snap.notifications.api.unavailable=Sembla que lAPI de {} no està disponible en aquests moments. No podreu cercar aplicacions {} noves.

View File

@@ -2,6 +2,8 @@ gem.snap.info=Anwendungen von https://snapcraft.io/store
snap.action.refresh.confirm=Erneuern {} ? snap.action.refresh.confirm=Erneuern {} ?
snap.action.refresh.label=Erneuern snap.action.refresh.label=Erneuern
snap.action.refresh.status=Erneuern snap.action.refresh.status=Erneuern
snap.config.install_channel=Display channels
snap.config.install_channel.tip=It allows to select one of the available channels for the given application to be installed
snap.info.channel=channel snap.info.channel=channel
snap.info.commands=Kommandos snap.info.commands=Kommandos
snap.info.contact=Kontakt snap.info.contact=Kontakt
@@ -18,6 +20,7 @@ snap.info.version=Version
snap.install.available_channels.help=Wähle einen aus um fortzufahren snap.install.available_channels.help=Wähle einen aus um fortzufahren
snap.install.available_channels.message=Es ist kein {} Channel verfügbar für {}. Es gibt jedoch folgende snap.install.available_channels.message=Es ist kein {} Channel verfügbar für {}. Es gibt jedoch folgende
snap.install.available_channels.title=Verfügbare Channels snap.install.available_channels.title=Verfügbare Channels
snap.install.channel.body=Select a channel to proceed
snap.notification.snap.disable=Um keine Snap Anwerndungen zu nutzen deaktivieren {} unter {} snap.notification.snap.disable=Um keine Snap Anwerndungen zu nutzen deaktivieren {} unter {}
snap.notification.snapd_unavailable={} wurde nicht gestartet oder ist deaktiviert. {} Pakete werden nicht verfügbar sein. snap.notification.snapd_unavailable={} wurde nicht gestartet oder ist deaktiviert. {} Pakete werden nicht verfügbar sein.
snap.notifications.api.unavailable=Es scheint als ob die {} API aktuell nicht verfügbar ist. Die Suche nach neuen {} Anwendungen ist nicht möglich. snap.notifications.api.unavailable=Es scheint als ob die {} API aktuell nicht verfügbar ist. Die Suche nach neuen {} Anwendungen ist nicht möglich.

View File

@@ -2,6 +2,8 @@ gem.snap.info=Applications published at https://snapcraft.io/store
snap.action.refresh.confirm=Refresh {} ? snap.action.refresh.confirm=Refresh {} ?
snap.action.refresh.label=Refresh snap.action.refresh.label=Refresh
snap.action.refresh.status=Refreshing snap.action.refresh.status=Refreshing
snap.config.install_channel=Display channels
snap.config.install_channel.tip=It allows to select one of the available channels for the given application to be installed
snap.info.channel=channel snap.info.channel=channel
snap.info.commands=commands snap.info.commands=commands
snap.info.contact=contact snap.info.contact=contact
@@ -18,6 +20,7 @@ snap.info.version=version
snap.install.available_channels.help=Select one if you want to continue snap.install.available_channels.help=Select one if you want to continue
snap.install.available_channels.message=There is no {} channel available for {}. But there are these below snap.install.available_channels.message=There is no {} channel available for {}. But there are these below
snap.install.available_channels.title=Available channels snap.install.available_channels.title=Available channels
snap.install.channel.body=Select a channel to proceed
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.notification.snapd_unavailable={} seems not to be started or enabled. {} packages will not be available. snap.notification.snapd_unavailable={} seems not to be started or enabled. {} packages will not be available.
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.

View File

@@ -2,6 +2,8 @@ gem.snap.info=Aplicativos publicados en https://snapcraft.io/store
snap.action.refresh.confirm=Actualizar {} ? snap.action.refresh.confirm=Actualizar {} ?
snap.action.refresh.label=Actualizar snap.action.refresh.label=Actualizar
snap.action.refresh.status=Actualizando snap.action.refresh.status=Actualizando
snap.config.install_channel=Mostrar canales
snap.config.install_channel.tip=Permite seleccionar uno de los canales disponibles para la aplicación a instalar
snap.info.channel=canal snap.info.channel=canal
snap.info.commands=comandos snap.info.commands=comandos
snap.info.contact=contacto snap.info.contact=contacto
@@ -18,6 +20,7 @@ snap.info.version=versión
snap.install.available_channels.help=Seleccione uno si desea continuar snap.install.available_channels.help=Seleccione uno si desea continuar
snap.install.available_channels.message=No hay un canal {} ( stable ) disponible para {}. Pero hay estos otros abajo snap.install.available_channels.message=No hay un canal {} ( stable ) disponible para {}. Pero hay estos otros abajo
snap.install.available_channels.title=Canales disponibles snap.install.available_channels.title=Canales disponibles
snap.install.channel.body=Seleccione un canal para continuar
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.notification.snapd_unavailable={} parece no estar inicializado o habilitado. Los paquetes {} estarán indisponibles. snap.notification.snapd_unavailable={} parece no estar inicializado o habilitado. Los paquetes {} estarán indisponibles.
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 {}.

View File

@@ -2,6 +2,8 @@ gem.snap.info=Applicazioni pubblicate su https://snapcraft.io/store
snap.action.refresh.confirm=Ripristina {} ? snap.action.refresh.confirm=Ripristina {} ?
snap.action.refresh.label=Ripristina snap.action.refresh.label=Ripristina
snap.action.refresh.status=Ripristinare snap.action.refresh.status=Ripristinare
snap.config.install_channel=Display channels
snap.config.install_channel.tip=It allows to select one of the available channels for the given application to be installed
snap.info.channel=channel snap.info.channel=channel
snap.info.commands=commands snap.info.commands=commands
snap.info.contact=contact snap.info.contact=contact
@@ -18,6 +20,7 @@ snap.info.version=version
snap.install.available_channels.help=Selezionane uno se vuoi continuare snap.install.available_channels.help=Selezionane uno se vuoi continuare
snap.install.available_channels.message=Non esiste un {} canale disponibile per {}. Ma ci sono questi sotto snap.install.available_channels.message=Non esiste un {} canale disponibile per {}. Ma ci sono questi sotto
snap.install.available_channels.title=Canali disponibili snap.install.available_channels.title=Canali disponibili
snap.install.channel.body=Select a channel to proceed
snap.notification.snap.disable=Se non si desidera utilizzare le applicazioni Snap, deselezionare {} in {} snap.notification.snap.disable=Se non si desidera utilizzare le applicazioni Snap, deselezionare {} in {}
snap.notification.snapd_unavailable={} sembra non essere avviato o abilitato. {} i pacchetti non saranno disponibili. snap.notification.snapd_unavailable={} sembra non essere avviato o abilitato. {} i pacchetti non saranno disponibili.
snap.notifications.api.unavailable=Sembra che l'API {} non sia al momento disponibile. Non sarà possibile cercare nuove {} applicazioni. snap.notifications.api.unavailable=Sembra che l'API {} non sia al momento disponibile. Non sarà possibile cercare nuove {} applicazioni.

View File

@@ -2,6 +2,8 @@ gem.snap.info=Aplicativos publicados em https://snapcraft.io/store
snap.action.refresh.confirm=Atualizar {} ? snap.action.refresh.confirm=Atualizar {} ?
snap.action.refresh.label=Atualizar snap.action.refresh.label=Atualizar
snap.action.refresh.status=Atualizando snap.action.refresh.status=Atualizando
snap.config.install_channel=Exibir canais
snap.config.install_channel.tip=Permite-se selecionar um dos canais disponíveis para o aplicativo a ser instalado
snap.info.channel=canal snap.info.channel=canal
snap.info.commands=comandos snap.info.commands=comandos
snap.info.contact=contato snap.info.contact=contato
@@ -18,6 +20,7 @@ snap.info.version=versão
snap.install.available_channels.help=Selecione algum se quiser continuar snap.install.available_channels.help=Selecione algum se quiser continuar
snap.install.available_channels.message=Não há um canal {} ( stable ) disponível para {}. Porém existem estes outros abaixo snap.install.available_channels.message=Não há um canal {} ( stable ) disponível para {}. Porém existem estes outros abaixo
snap.install.available_channels.title=Canais disponíveis snap.install.available_channels.title=Canais disponíveis
snap.install.channel.body=Selecione um canal para continuar
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.notification.snapd_unavailable={} parece não estar inicializado 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.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 {}.

View File

@@ -2,6 +2,8 @@ gem.snap.info=Приложения, опубликованные на https://sn
snap.action.refresh.confirm=Обновить {} ? snap.action.refresh.confirm=Обновить {} ?
snap.action.refresh.label=Обновить snap.action.refresh.label=Обновить
snap.action.refresh.status=Обновляется snap.action.refresh.status=Обновляется
snap.config.install_channel=Display channels
snap.config.install_channel.tip=It allows to select one of the available channels for the given application to be installed
snap.info.channel=channel snap.info.channel=channel
snap.info.commands=Команды snap.info.commands=Команды
snap.info.contact=Контакт snap.info.contact=Контакт
@@ -18,6 +20,7 @@ snap.info.version=Версия
snap.install.available_channels.help=Выберите один, если вы хотите продолжить snap.install.available_channels.help=Выберите один, если вы хотите продолжить
snap.install.available_channels.message=Нет одного канала {}, доступного для {}. Но есть такие ниже snap.install.available_channels.message=Нет одного канала {}, доступного для {}. Но есть такие ниже
snap.install.available_channels.title=Доступные каналы snap.install.available_channels.title=Доступные каналы
snap.install.channel.body=Select a channel to proceed
snap.notification.snap.disable=Если вы не хотите использовать приложения Snap, снимите флажок {} в {} snap.notification.snap.disable=Если вы не хотите использовать приложения Snap, снимите флажок {} в {}
snap.notification.snapd_unavailable={} кажется, не запускается и не включается. {} пакеты будут недоступны. snap.notification.snapd_unavailable={} кажется, не запускается и не включается. {} пакеты будут недоступны.
snap.notifications.api.unavailable=Похоже, что API {} в данный момент недоступен. Невозможно будет искать новые приложения {}. snap.notifications.api.unavailable=Похоже, что API {} в данный момент недоступен. Невозможно будет искать новые приложения {}.

View File

@@ -2,6 +2,8 @@ gem.snap.info=https://snapcraft.io/store adresinde yayınlanan uygulamalar
snap.action.refresh.confirm=Yenile {} ? snap.action.refresh.confirm=Yenile {} ?
snap.action.refresh.label=Yenile snap.action.refresh.label=Yenile
snap.action.refresh.status=Yenileniyor snap.action.refresh.status=Yenileniyor
snap.config.install_channel=Display channels
snap.config.install_channel.tip=It allows to select one of the available channels for the given application to be installed
snap.info.channel=channel snap.info.channel=channel
snap.info.commands=komutlar snap.info.commands=komutlar
snap.info.contact=iletişim snap.info.contact=iletişim
@@ -18,6 +20,7 @@ snap.info.version=sürüm
snap.install.available_channels.help=Devam etmek istiyorsanız birini seçin snap.install.available_channels.help=Devam etmek istiyorsanız birini seçin
snap.install.available_channels.message={} için hiçbir {} kanalı yok. Ama aşağıda bunlar var snap.install.available_channels.message={} için hiçbir {} kanalı yok. Ama aşağıda bunlar var
snap.install.available_channels.title=Kullanılabilir kanallar snap.install.available_channels.title=Kullanılabilir kanallar
snap.install.channel.body=Select a channel to proceed
snap.notification.snap.disable=Snap uygulamalarını kullanmak istemiyorsanız, {} içindeki {} işaretini kaldırın snap.notification.snap.disable=Snap uygulamalarını kullanmak istemiyorsanız, {} içindeki {} işaretini kaldırın
snap.notification.snapd_unavailable={} başlatılmamış veya etkinleştirilmemiş gibi görünüyor. {} paketler mevcut olmayacak. snap.notification.snapd_unavailable={} başlatılmamış veya etkinleştirilmemiş gibi görünüyor. {} paketler mevcut olmayacak.
snap.notifications.api.unavailable=Görünüşe göre {} API şu anda kullanılamıyor. Yeni {} uygulamaları aramak mümkün olmayacak. snap.notifications.api.unavailable=Görünüşe göre {} API şu anda kullanılamıyor. Yeni {} uygulamaları aramak mümkün olmayacak.

View File

@@ -1,7 +1,7 @@
import os import os
import subprocess import subprocess
from io import StringIO from io import StringIO
from typing import Tuple from typing import Tuple, Optional
from bauh.commons.system import run_cmd, SimpleProcess from bauh.commons.system import run_cmd, SimpleProcess
@@ -18,13 +18,16 @@ def uninstall_and_stream(app_name: str, root_password: str) -> SimpleProcess:
shell=True) shell=True)
def install_and_stream(app_name: str, confinement: str, root_password: str) -> SimpleProcess: def install_and_stream(app_name: str, confinement: str, root_password: str, channel: Optional[str] = None) -> SimpleProcess:
install_cmd = [BASE_CMD, 'install', app_name] # default install_cmd = [BASE_CMD, 'install', app_name] # default
if confinement == 'classic': if confinement == 'classic':
install_cmd.append('--classic') install_cmd.append('--classic')
if channel:
install_cmd.append('--channel={}'.format(channel))
return SimpleProcess(install_cmd, root_password=root_password, shell=True) return SimpleProcess(install_cmd, root_password=root_password, shell=True)

View File

@@ -9,7 +9,7 @@ import traceback
from math import floor from math import floor
from pathlib import Path from pathlib import Path
from threading import Thread from threading import Thread
from typing import List, Type, Set, Tuple from typing import List, Type, Set, Tuple, Optional
import requests import requests
import yaml import yaml
@@ -996,7 +996,7 @@ class WebApplicationManager(SoftwareManager):
return PanelComponent([form_env]) return PanelComponent([form_env])
def save_settings(self, component: PanelComponent) -> Tuple[bool, List[str]]: def save_settings(self, component: PanelComponent) -> Tuple[bool, Optional[List[str]]]:
config = read_config() config = read_config()
form_env = component.components[0] form_env = component.components[0]

View File

@@ -266,6 +266,7 @@ class RadioButtonQt(QRadioButton):
self.model = model self.model = model
self.model_parent = model_parent self.model_parent = model_parent
self.toggled.connect(self._set_checked) self.toggled.connect(self._set_checked)
self.setCursor(QCursor(Qt.PointingHandCursor))
if model.icon_path: if model.icon_path:
if model.icon_path.startswith('/'): if model.icon_path.startswith('/'):