Mercurial > libervia-backend
view libervia/tui/profile_manager.py @ 4240:79c8a70e1813
backend, frontend: prepare remote control:
This is a series of changes necessary to prepare the implementation of remote control
feature:
- XEP-0166: add a `priority` attribute to `ApplicationData`: this is needed when several
applications are working in a same session, to know which one must be handled first.
Will be used to make Remote Control have precedence over Call content.
- XEP-0166: `_call_plugins` is now async and is not used with `DeferredList` anymore: the
benefit to have methods called in parallels is very low, and it cause a lot of trouble
as we can't predict order. Methods are now called sequentially so workflow can be
predicted.
- XEP-0167: fix `senders` XMPP attribute <=> SDP mapping
- XEP-0234: preflight acceptance key is now `pre-accepted` instead of `file-accepted`, so
the same key can be used with other jingle applications.
- XEP-0167, XEP-0343: move some method to XEP-0167
- XEP-0353: use new `priority` feature to call preflight methods of applications according
to it.
- frontend (webrtc): refactor the sources/sink handling with a more flexible mechanism
based on Pydantic models. It is now possible to have has many Data Channel as necessary,
to have them in addition to A/V streams, to specify manually GStreamer sources and
sinks, etc.
- frontend (webrtc): rework of the pipeline to reduce latency.
- frontend: new `portal_desktop` method. Screenshare portal handling has been moved there,
and RemoteDesktop portal has been added.
- frontend (webrtc): fix `extract_ufrag_pwd` method.
rel 436
author | Goffi <goffi@goffi.org> |
---|---|
date | Sat, 11 May 2024 13:52:41 +0200 |
parents | b620a8e882e1 |
children |
line wrap: on
line source
#!/usr/bin/env python3 # Libervia TUI # 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/>. from libervia.backend.core.i18n import _ from libervia.backend.core import log as logging log = logging.getLogger(__name__) from libervia.frontends.quick_frontend.quick_profile_manager import QuickProfileManager from libervia.tui.constants import Const as C from libervia.tui.keys import action_key_map as a_key from urwid_satext import sat_widgets import urwid class ProfileManager(QuickProfileManager, urwid.WidgetWrap): def __init__(self, host, autoconnect=None): QuickProfileManager.__init__(self, host, autoconnect) # login & password box must be created before list because of on_profile_change self.login_wid = sat_widgets.AdvancedEdit(_("Login:"), align="center") self.pass_wid = sat_widgets.Password(_("Password:"), align="center") style = ["no_first_select"] profiles = host.bridge.profiles_list_get() profiles.sort() self.list_profile = sat_widgets.List( profiles, style=style, align="center", on_change=self.on_profile_change ) # new & delete buttons buttons = [ urwid.Button(_("New"), self.on_new_profile), urwid.Button(_("Delete"), self.on_delete_profile), ] buttons_flow = urwid.GridFlow( buttons, max([len(button.get_label()) for button in buttons]) + 4, 1, 1, "center", ) # second part: login information: divider = urwid.Divider("-") # connect button connect_button = sat_widgets.CustomButton( _("Connect"), self.on_connect_profiles, align="center" ) # we now build the widget list_walker = urwid.SimpleFocusListWalker( [ buttons_flow, self.list_profile, divider, self.login_wid, self.pass_wid, connect_button, ] ) frame_body = urwid.ListBox(list_walker) frame = urwid.Frame( frame_body, urwid.AttrMap(urwid.Text(_("Profile Manager"), align="center"), "title"), ) self.main_widget = urwid.LineBox(frame) urwid.WidgetWrap.__init__(self, self.main_widget) self.go(autoconnect) def keypress(self, size, key): if key == a_key["APP_QUIT"]: self.host.on_exit() raise urwid.ExitMainLoop() elif key in (a_key["FOCUS_UP"], a_key["FOCUS_DOWN"]): focus_diff = 1 if key == a_key["FOCUS_DOWN"] else -1 list_box = self.main_widget.base_widget.body current_focus = list_box.body.get_focus()[1] if current_focus is None: return while True: current_focus += focus_diff if current_focus < 0 or current_focus >= len(list_box.body): break if list_box.body[current_focus].selectable(): list_box.set_focus( current_focus, "above" if focus_diff == 1 else "below" ) list_box._invalidate() return return super(ProfileManager, self).keypress(size, key) def cancel_dialog(self, button): self.host.remove_pop_up() def new_profile(self, button, edit): """Create the profile""" name = edit.get_edit_text() self.host.bridge.profile_create( name, callback=lambda: self.new_profile_created(name), errback=self.profile_creation_failure, ) def new_profile_created(self, profile): # new profile will be selected, and a selected profile assume the session is started self.host.bridge.profile_start_session( "", profile, callback=lambda __: self.new_profile_session_started(profile), errback=self.profile_creation_failure, ) def new_profile_session_started(self, profile): self.host.remove_pop_up() self.refill_profiles() self.list_profile.select_value(profile) self.current.profile = profile self.get_connection_params(profile) self.host.redraw() def profile_creation_failure(self, reason): self.host.remove_pop_up() message = self._get_error_message(reason) self.host.alert(_("Can't create profile"), message) def delete_profile(self, button): self._delete_profile() self.host.remove_pop_up() def on_new_profile(self, e): pop_up_widget = sat_widgets.InputDialog( _("New profile"), _("Please enter a new profile name"), cancel_cb=self.cancel_dialog, ok_cb=self.new_profile, ) self.host.show_pop_up(pop_up_widget) def on_delete_profile(self, e): if self.current.profile: pop_up_widget = sat_widgets.ConfirmDialog( _("Are you sure you want to delete the profile {} ?").format( self.current.profile ), no_cb=self.cancel_dialog, yes_cb=self.delete_profile, ) self.host.show_pop_up(pop_up_widget) def on_connect_profiles(self, button): """Connect the profiles and start the main widget @param button: the connect button """ self._on_connect_profiles() def reset_fields(self): """Set profile to None, and reset fields""" super(ProfileManager, self).reset_fields() self.list_profile.unselect_all(invisible=True) def set_profiles(self, profiles): """Update the list of profiles""" self.list_profile.change_values(profiles) self.host.redraw() def get_profiles(self): return self.list_profile.get_selected_values() def get_jid(self): return self.login_wid.get_edit_text() def getPassword(self): return self.pass_wid.get_edit_text() def set_jid(self, jid_): self.login_wid.set_edit_text(jid_) self.current.login = jid_ self.host.redraw() # FIXME: redraw should be avoided def set_password(self, password): self.pass_wid.set_edit_text(password) self.current.password = password self.host.redraw() def on_profile_change(self, list_wid, widget=None, selected=None): """This is called when a profile is selected in the profile list. @param list_wid: the List widget who sent the event """ self.update_connection_params() focused = list_wid.focus selected = focused.get_state() if focused is not None else False if not selected: # profile was just unselected return focused.set_state( False, invisible=True ) # we don't want the widget to be selected until we are sure we can access it def authenticate_cb(data, cb_id, profile): if C.bool(data.pop("validated", C.BOOL_FALSE)): self.current.profile = profile focused.set_state(True, invisible=True) self.get_connection_params(profile) self.host.redraw() self.host.action_manager(data, callback=authenticate_cb, profile=profile) self.host.action_launch( C.AUTHENTICATE_PROFILE_ID, callback=authenticate_cb, profile=focused.text )