Mercurial > libervia-backend
diff libervia/cli/cmd_profile.py @ 4075:47401850dec6
refactoring: rename `libervia.frontends.jp` to `libervia.cli`
author | Goffi <goffi@goffi.org> |
---|---|
date | Fri, 02 Jun 2023 14:54:26 +0200 |
parents | libervia/frontends/jp/cmd_profile.py@26b7ed2817da |
children | 0d7bb4df2343 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libervia/cli/cmd_profile.py Fri Jun 02 14:54:26 2023 +0200 @@ -0,0 +1,280 @@ +#!/usr/bin/env python3 + + +# Libervia CLI +# Copyright (C) 2009-2021 Jérôme Poisson (goffi@goffi.org) + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. + +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +"""This module permits to manage profiles. It can list, create, delete +and retrieve information about a profile.""" + +from libervia.cli.constants import Const as C +from libervia.backend.core.log import getLogger +from libervia.backend.core.i18n import _ +from libervia.cli import base + +log = getLogger(__name__) + + +__commands__ = ["Profile"] + +PROFILE_HELP = _('The name of the profile') + + +class ProfileConnect(base.CommandBase): + """Dummy command to use profile_session parent, i.e. to be able to connect without doing anything else""" + + def __init__(self, host): + # it's weird to have a command named "connect" with need_connect=False, but it can be handy to be able + # to launch just the session, so some paradoxes don't hurt + super(ProfileConnect, self).__init__(host, 'connect', need_connect=False, help=('connect a profile')) + + def add_parser_options(self): + pass + + async def start(self): + # connection is already managed by profile common commands + # so we just need to check arguments and quit + if not self.args.connect and not self.args.start_session: + self.parser.error(_("You need to use either --connect or --start-session")) + self.host.quit() + +class ProfileDisconnect(base.CommandBase): + + def __init__(self, host): + super(ProfileDisconnect, self).__init__(host, 'disconnect', need_connect=False, help=('disconnect a profile')) + + def add_parser_options(self): + pass + + async def start(self): + try: + await self.host.bridge.disconnect(self.args.profile) + except Exception as e: + self.disp(f"can't disconnect profile: {e}", error=True) + self.host.quit(C.EXIT_BRIDGE_ERRBACK) + else: + self.host.quit() + + +class ProfileCreate(base.CommandBase): + def __init__(self, host): + super(ProfileCreate, self).__init__( + host, 'create', use_profile=False, help=('create a new profile')) + + def add_parser_options(self): + self.parser.add_argument('profile', type=str, help=_('the name of the profile')) + self.parser.add_argument( + '-p', '--password', type=str, default='', + help=_('the password of the profile')) + self.parser.add_argument( + '-j', '--jid', type=str, help=_('the jid of the profile')) + self.parser.add_argument( + '-x', '--xmpp-password', type=str, + help=_( + 'the password of the XMPP account (use profile password if not specified)' + ), + metavar='PASSWORD') + self.parser.add_argument( + '-A', '--autoconnect', choices=[C.BOOL_TRUE, C.BOOL_FALSE], nargs='?', + const=C.BOOL_TRUE, + help=_('connect this profile automatically when backend starts') + ) + self.parser.add_argument( + '-C', '--component', default='', + help=_('set to component import name (entry point) if this is a component')) + + async def start(self): + """Create a new profile""" + if self.args.profile in await self.host.bridge.profiles_list_get(): + self.disp(f"Profile {self.args.profile} already exists.", error=True) + self.host.quit(C.EXIT_BRIDGE_ERROR) + try: + await self.host.bridge.profile_create( + self.args.profile, self.args.password, self.args.component) + except Exception as e: + self.disp(f"can't create profile: {e}", error=True) + self.host.quit(C.EXIT_BRIDGE_ERRBACK) + + try: + await self.host.bridge.profile_start_session( + self.args.password, self.args.profile) + except Exception as e: + self.disp(f"can't start profile session: {e}", error=True) + self.host.quit(C.EXIT_BRIDGE_ERRBACK) + + if self.args.jid: + await self.host.bridge.param_set( + "JabberID", self.args.jid, "Connection", profile_key=self.args.profile) + xmpp_pwd = self.args.password or self.args.xmpp_password + if xmpp_pwd: + await self.host.bridge.param_set( + "Password", xmpp_pwd, "Connection", profile_key=self.args.profile) + + if self.args.autoconnect is not None: + await self.host.bridge.param_set( + "autoconnect_backend", self.args.autoconnect, "Connection", + profile_key=self.args.profile) + + self.disp(f'profile {self.args.profile} created successfully', 1) + self.host.quit() + + +class ProfileDefault(base.CommandBase): + def __init__(self, host): + super(ProfileDefault, self).__init__( + host, 'default', use_profile=False, help=('print default profile')) + + def add_parser_options(self): + pass + + async def start(self): + print(await self.host.bridge.profile_name_get('@DEFAULT@')) + self.host.quit() + + +class ProfileDelete(base.CommandBase): + def __init__(self, host): + super(ProfileDelete, self).__init__(host, 'delete', use_profile=False, help=('delete a profile')) + + def add_parser_options(self): + self.parser.add_argument('profile', type=str, help=PROFILE_HELP) + self.parser.add_argument('-f', '--force', action='store_true', help=_('delete profile without confirmation')) + + async def start(self): + if self.args.profile not in await self.host.bridge.profiles_list_get(): + log.error(f"Profile {self.args.profile} doesn't exist.") + self.host.quit(C.EXIT_NOT_FOUND) + if not self.args.force: + message = f"Are you sure to delete profile [{self.args.profile}] ?" + cancel_message = "Profile deletion cancelled" + await self.host.confirm_or_quit(message, cancel_message) + + await self.host.bridge.profile_delete_async(self.args.profile) + self.host.quit() + + +class ProfileInfo(base.CommandBase): + + def __init__(self, host): + super(ProfileInfo, self).__init__( + host, 'info', need_connect=False, use_output=C.OUTPUT_DICT, + help=_('get information about a profile')) + self.to_show = [(_("jid"), "Connection", "JabberID"),] + + def add_parser_options(self): + self.parser.add_argument( + '--show-password', action='store_true', + help=_('show the XMPP password IN CLEAR TEXT')) + + async def start(self): + if self.args.show_password: + self.to_show.append((_("XMPP password"), "Connection", "Password")) + self.to_show.append((_("autoconnect (backend)"), "Connection", + "autoconnect_backend")) + data = {} + for label, category, name in self.to_show: + try: + value = await self.host.bridge.param_get_a_async( + name, category, profile_key=self.host.profile) + except Exception as e: + self.disp(f"can't get {name}/{category} param: {e}", error=True) + else: + data[label] = value + + await self.output(data) + self.host.quit() + + +class ProfileList(base.CommandBase): + def __init__(self, host): + super(ProfileList, self).__init__( + host, 'list', use_profile=False, use_output='list', help=('list profiles')) + + def add_parser_options(self): + group = self.parser.add_mutually_exclusive_group() + group.add_argument( + '-c', '--clients', action='store_true', help=_('get clients profiles only')) + group.add_argument( + '-C', '--components', action='store_true', + help=('get components profiles only')) + + async def start(self): + if self.args.clients: + clients, components = True, False + elif self.args.components: + clients, components = False, True + else: + clients, components = True, True + await self.output(await self.host.bridge.profiles_list_get(clients, components)) + self.host.quit() + + +class ProfileModify(base.CommandBase): + + def __init__(self, host): + super(ProfileModify, self).__init__( + host, 'modify', need_connect=False, help=_('modify an existing profile')) + + def add_parser_options(self): + profile_pwd_group = self.parser.add_mutually_exclusive_group() + profile_pwd_group.add_argument( + '-w', '--password', help=_('change the password of the profile')) + profile_pwd_group.add_argument( + '--disable-password', action='store_true', + help=_('disable profile password (dangerous!)')) + self.parser.add_argument('-j', '--jid', help=_('the jid of the profile')) + self.parser.add_argument( + '-x', '--xmpp-password', help=_('change the password of the XMPP account'), + metavar='PASSWORD') + self.parser.add_argument( + '-D', '--default', action='store_true', help=_('set as default profile')) + self.parser.add_argument( + '-A', '--autoconnect', choices=[C.BOOL_TRUE, C.BOOL_FALSE], nargs='?', + const=C.BOOL_TRUE, + help=_('connect this profile automatically when backend starts') + ) + + async def start(self): + if self.args.disable_password: + self.args.password = '' + if self.args.password is not None: + await self.host.bridge.param_set( + "Password", self.args.password, "General", profile_key=self.host.profile) + if self.args.jid is not None: + await self.host.bridge.param_set( + "JabberID", self.args.jid, "Connection", profile_key=self.host.profile) + if self.args.xmpp_password is not None: + await self.host.bridge.param_set( + "Password", self.args.xmpp_password, "Connection", + profile_key=self.host.profile) + if self.args.default: + await self.host.bridge.profile_set_default(self.host.profile) + if self.args.autoconnect is not None: + await self.host.bridge.param_set( + "autoconnect_backend", self.args.autoconnect, "Connection", + profile_key=self.host.profile) + + self.host.quit() + + +class Profile(base.CommandBase): + subcommands = ( + ProfileConnect, ProfileDisconnect, ProfileCreate, ProfileDefault, ProfileDelete, + ProfileInfo, ProfileList, ProfileModify) + + def __init__(self, host): + super(Profile, self).__init__( + host, 'profile', use_profile=False, help=_('profile commands'))