Mercurial > libervia-backend
comparison 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 |
comparison
equal
deleted
inserted
replaced
4074:26b7ed2817da | 4075:47401850dec6 |
---|---|
1 #!/usr/bin/env python3 | |
2 | |
3 | |
4 # Libervia CLI | |
5 # Copyright (C) 2009-2021 Jérôme Poisson (goffi@goffi.org) | |
6 | |
7 # This program is free software: you can redistribute it and/or modify | |
8 # it under the terms of the GNU Affero General Public License as published by | |
9 # the Free Software Foundation, either version 3 of the License, or | |
10 # (at your option) any later version. | |
11 | |
12 # This program is distributed in the hope that it will be useful, | |
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 # GNU Affero General Public License for more details. | |
16 | |
17 # You should have received a copy of the GNU Affero General Public License | |
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
19 | |
20 """This module permits to manage profiles. It can list, create, delete | |
21 and retrieve information about a profile.""" | |
22 | |
23 from libervia.cli.constants import Const as C | |
24 from libervia.backend.core.log import getLogger | |
25 from libervia.backend.core.i18n import _ | |
26 from libervia.cli import base | |
27 | |
28 log = getLogger(__name__) | |
29 | |
30 | |
31 __commands__ = ["Profile"] | |
32 | |
33 PROFILE_HELP = _('The name of the profile') | |
34 | |
35 | |
36 class ProfileConnect(base.CommandBase): | |
37 """Dummy command to use profile_session parent, i.e. to be able to connect without doing anything else""" | |
38 | |
39 def __init__(self, host): | |
40 # it's weird to have a command named "connect" with need_connect=False, but it can be handy to be able | |
41 # to launch just the session, so some paradoxes don't hurt | |
42 super(ProfileConnect, self).__init__(host, 'connect', need_connect=False, help=('connect a profile')) | |
43 | |
44 def add_parser_options(self): | |
45 pass | |
46 | |
47 async def start(self): | |
48 # connection is already managed by profile common commands | |
49 # so we just need to check arguments and quit | |
50 if not self.args.connect and not self.args.start_session: | |
51 self.parser.error(_("You need to use either --connect or --start-session")) | |
52 self.host.quit() | |
53 | |
54 class ProfileDisconnect(base.CommandBase): | |
55 | |
56 def __init__(self, host): | |
57 super(ProfileDisconnect, self).__init__(host, 'disconnect', need_connect=False, help=('disconnect a profile')) | |
58 | |
59 def add_parser_options(self): | |
60 pass | |
61 | |
62 async def start(self): | |
63 try: | |
64 await self.host.bridge.disconnect(self.args.profile) | |
65 except Exception as e: | |
66 self.disp(f"can't disconnect profile: {e}", error=True) | |
67 self.host.quit(C.EXIT_BRIDGE_ERRBACK) | |
68 else: | |
69 self.host.quit() | |
70 | |
71 | |
72 class ProfileCreate(base.CommandBase): | |
73 def __init__(self, host): | |
74 super(ProfileCreate, self).__init__( | |
75 host, 'create', use_profile=False, help=('create a new profile')) | |
76 | |
77 def add_parser_options(self): | |
78 self.parser.add_argument('profile', type=str, help=_('the name of the profile')) | |
79 self.parser.add_argument( | |
80 '-p', '--password', type=str, default='', | |
81 help=_('the password of the profile')) | |
82 self.parser.add_argument( | |
83 '-j', '--jid', type=str, help=_('the jid of the profile')) | |
84 self.parser.add_argument( | |
85 '-x', '--xmpp-password', type=str, | |
86 help=_( | |
87 'the password of the XMPP account (use profile password if not specified)' | |
88 ), | |
89 metavar='PASSWORD') | |
90 self.parser.add_argument( | |
91 '-A', '--autoconnect', choices=[C.BOOL_TRUE, C.BOOL_FALSE], nargs='?', | |
92 const=C.BOOL_TRUE, | |
93 help=_('connect this profile automatically when backend starts') | |
94 ) | |
95 self.parser.add_argument( | |
96 '-C', '--component', default='', | |
97 help=_('set to component import name (entry point) if this is a component')) | |
98 | |
99 async def start(self): | |
100 """Create a new profile""" | |
101 if self.args.profile in await self.host.bridge.profiles_list_get(): | |
102 self.disp(f"Profile {self.args.profile} already exists.", error=True) | |
103 self.host.quit(C.EXIT_BRIDGE_ERROR) | |
104 try: | |
105 await self.host.bridge.profile_create( | |
106 self.args.profile, self.args.password, self.args.component) | |
107 except Exception as e: | |
108 self.disp(f"can't create profile: {e}", error=True) | |
109 self.host.quit(C.EXIT_BRIDGE_ERRBACK) | |
110 | |
111 try: | |
112 await self.host.bridge.profile_start_session( | |
113 self.args.password, self.args.profile) | |
114 except Exception as e: | |
115 self.disp(f"can't start profile session: {e}", error=True) | |
116 self.host.quit(C.EXIT_BRIDGE_ERRBACK) | |
117 | |
118 if self.args.jid: | |
119 await self.host.bridge.param_set( | |
120 "JabberID", self.args.jid, "Connection", profile_key=self.args.profile) | |
121 xmpp_pwd = self.args.password or self.args.xmpp_password | |
122 if xmpp_pwd: | |
123 await self.host.bridge.param_set( | |
124 "Password", xmpp_pwd, "Connection", profile_key=self.args.profile) | |
125 | |
126 if self.args.autoconnect is not None: | |
127 await self.host.bridge.param_set( | |
128 "autoconnect_backend", self.args.autoconnect, "Connection", | |
129 profile_key=self.args.profile) | |
130 | |
131 self.disp(f'profile {self.args.profile} created successfully', 1) | |
132 self.host.quit() | |
133 | |
134 | |
135 class ProfileDefault(base.CommandBase): | |
136 def __init__(self, host): | |
137 super(ProfileDefault, self).__init__( | |
138 host, 'default', use_profile=False, help=('print default profile')) | |
139 | |
140 def add_parser_options(self): | |
141 pass | |
142 | |
143 async def start(self): | |
144 print(await self.host.bridge.profile_name_get('@DEFAULT@')) | |
145 self.host.quit() | |
146 | |
147 | |
148 class ProfileDelete(base.CommandBase): | |
149 def __init__(self, host): | |
150 super(ProfileDelete, self).__init__(host, 'delete', use_profile=False, help=('delete a profile')) | |
151 | |
152 def add_parser_options(self): | |
153 self.parser.add_argument('profile', type=str, help=PROFILE_HELP) | |
154 self.parser.add_argument('-f', '--force', action='store_true', help=_('delete profile without confirmation')) | |
155 | |
156 async def start(self): | |
157 if self.args.profile not in await self.host.bridge.profiles_list_get(): | |
158 log.error(f"Profile {self.args.profile} doesn't exist.") | |
159 self.host.quit(C.EXIT_NOT_FOUND) | |
160 if not self.args.force: | |
161 message = f"Are you sure to delete profile [{self.args.profile}] ?" | |
162 cancel_message = "Profile deletion cancelled" | |
163 await self.host.confirm_or_quit(message, cancel_message) | |
164 | |
165 await self.host.bridge.profile_delete_async(self.args.profile) | |
166 self.host.quit() | |
167 | |
168 | |
169 class ProfileInfo(base.CommandBase): | |
170 | |
171 def __init__(self, host): | |
172 super(ProfileInfo, self).__init__( | |
173 host, 'info', need_connect=False, use_output=C.OUTPUT_DICT, | |
174 help=_('get information about a profile')) | |
175 self.to_show = [(_("jid"), "Connection", "JabberID"),] | |
176 | |
177 def add_parser_options(self): | |
178 self.parser.add_argument( | |
179 '--show-password', action='store_true', | |
180 help=_('show the XMPP password IN CLEAR TEXT')) | |
181 | |
182 async def start(self): | |
183 if self.args.show_password: | |
184 self.to_show.append((_("XMPP password"), "Connection", "Password")) | |
185 self.to_show.append((_("autoconnect (backend)"), "Connection", | |
186 "autoconnect_backend")) | |
187 data = {} | |
188 for label, category, name in self.to_show: | |
189 try: | |
190 value = await self.host.bridge.param_get_a_async( | |
191 name, category, profile_key=self.host.profile) | |
192 except Exception as e: | |
193 self.disp(f"can't get {name}/{category} param: {e}", error=True) | |
194 else: | |
195 data[label] = value | |
196 | |
197 await self.output(data) | |
198 self.host.quit() | |
199 | |
200 | |
201 class ProfileList(base.CommandBase): | |
202 def __init__(self, host): | |
203 super(ProfileList, self).__init__( | |
204 host, 'list', use_profile=False, use_output='list', help=('list profiles')) | |
205 | |
206 def add_parser_options(self): | |
207 group = self.parser.add_mutually_exclusive_group() | |
208 group.add_argument( | |
209 '-c', '--clients', action='store_true', help=_('get clients profiles only')) | |
210 group.add_argument( | |
211 '-C', '--components', action='store_true', | |
212 help=('get components profiles only')) | |
213 | |
214 async def start(self): | |
215 if self.args.clients: | |
216 clients, components = True, False | |
217 elif self.args.components: | |
218 clients, components = False, True | |
219 else: | |
220 clients, components = True, True | |
221 await self.output(await self.host.bridge.profiles_list_get(clients, components)) | |
222 self.host.quit() | |
223 | |
224 | |
225 class ProfileModify(base.CommandBase): | |
226 | |
227 def __init__(self, host): | |
228 super(ProfileModify, self).__init__( | |
229 host, 'modify', need_connect=False, help=_('modify an existing profile')) | |
230 | |
231 def add_parser_options(self): | |
232 profile_pwd_group = self.parser.add_mutually_exclusive_group() | |
233 profile_pwd_group.add_argument( | |
234 '-w', '--password', help=_('change the password of the profile')) | |
235 profile_pwd_group.add_argument( | |
236 '--disable-password', action='store_true', | |
237 help=_('disable profile password (dangerous!)')) | |
238 self.parser.add_argument('-j', '--jid', help=_('the jid of the profile')) | |
239 self.parser.add_argument( | |
240 '-x', '--xmpp-password', help=_('change the password of the XMPP account'), | |
241 metavar='PASSWORD') | |
242 self.parser.add_argument( | |
243 '-D', '--default', action='store_true', help=_('set as default profile')) | |
244 self.parser.add_argument( | |
245 '-A', '--autoconnect', choices=[C.BOOL_TRUE, C.BOOL_FALSE], nargs='?', | |
246 const=C.BOOL_TRUE, | |
247 help=_('connect this profile automatically when backend starts') | |
248 ) | |
249 | |
250 async def start(self): | |
251 if self.args.disable_password: | |
252 self.args.password = '' | |
253 if self.args.password is not None: | |
254 await self.host.bridge.param_set( | |
255 "Password", self.args.password, "General", profile_key=self.host.profile) | |
256 if self.args.jid is not None: | |
257 await self.host.bridge.param_set( | |
258 "JabberID", self.args.jid, "Connection", profile_key=self.host.profile) | |
259 if self.args.xmpp_password is not None: | |
260 await self.host.bridge.param_set( | |
261 "Password", self.args.xmpp_password, "Connection", | |
262 profile_key=self.host.profile) | |
263 if self.args.default: | |
264 await self.host.bridge.profile_set_default(self.host.profile) | |
265 if self.args.autoconnect is not None: | |
266 await self.host.bridge.param_set( | |
267 "autoconnect_backend", self.args.autoconnect, "Connection", | |
268 profile_key=self.host.profile) | |
269 | |
270 self.host.quit() | |
271 | |
272 | |
273 class Profile(base.CommandBase): | |
274 subcommands = ( | |
275 ProfileConnect, ProfileDisconnect, ProfileCreate, ProfileDefault, ProfileDelete, | |
276 ProfileInfo, ProfileList, ProfileModify) | |
277 | |
278 def __init__(self, host): | |
279 super(Profile, self).__init__( | |
280 host, 'profile', use_profile=False, help=_('profile commands')) |