comparison frontends/src/primitivus/profile_manager.py @ 1288:7cf32aeeebdb frontends_multi_profiles

quick_frontend, primitivus: moved parts of primitivus's profileManager to quick_frontend
author Goffi <goffi@goffi.org>
date Sat, 24 Jan 2015 00:14:58 +0100
parents e3a9ea76de35
children 948dc273ad93
comparison
equal deleted inserted replaced
1265:e3a9ea76de35 1288:7cf32aeeebdb
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. 18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 19
20 from sat.core.i18n import _ 20 from sat.core.i18n import _
21 from sat.core import log as logging 21 from sat.core import log as logging
22 log = logging.getLogger(__name__) 22 log = logging.getLogger(__name__)
23 from sat_frontends.quick_frontend.quick_profile_manager import QuickProfileManager
23 from sat_frontends.primitivus.constants import Const as C 24 from sat_frontends.primitivus.constants import Const as C
24 from sat_frontends.primitivus.keys import action_key_map as a_key 25 from sat_frontends.primitivus.keys import action_key_map as a_key
25 from urwid_satext import sat_widgets 26 from urwid_satext import sat_widgets
26 import urwid 27 import urwid
27 28
28 class ProfileRecord(object):
29 29
30 def __init__(self, profile=None, login=None, password=None): 30 class ProfileManager(QuickProfileManager, urwid.WidgetWrap):
31 self._profile = profile
32 self._login = login
33 self._password = password
34
35 @property
36 def profile(self):
37 return self._profile
38
39 @profile.setter
40 def profile(self, value):
41 self._profile = value
42 # if we change the profile,
43 # we must have no login/password until backend give them
44 self._login = self._password = None
45
46 @property
47 def login(self):
48 return self._login
49
50 @login.setter
51 def login(self, value):
52 self._login = value
53
54 @property
55 def password(self):
56 return self._password
57
58 @password.setter
59 def password(self, value):
60 self._password = value
61
62
63 class ProfileManager(urwid.WidgetWrap):
64 """Class with manage profiles creation/deletion/connection"""
65 31
66 def __init__(self, host, autoconnect=None): 32 def __init__(self, host, autoconnect=None):
67 """Create the manager 33 QuickProfileManager.__init__(self, host, autoconnect)
68
69 @param host: %(doc_host)s
70 @param autoconnect(iterable): list of profiles to connect automatically
71 """
72 self.host = host
73 self._autoconnect = bool(autoconnect)
74 self.current = ProfileRecord()
75 profiles = self.host.bridge.getProfilesList()
76 profiles.sort()
77 34
78 #login & password box must be created before list because of onProfileChange 35 #login & password box must be created before list because of onProfileChange
79 self.login_wid = sat_widgets.AdvancedEdit(_('Login:'), align='center') 36 self.login_wid = sat_widgets.AdvancedEdit(_('Login:'), align='center')
80 self.pass_wid = sat_widgets.Password(_('Password:'), align='center') 37 self.pass_wid = sat_widgets.Password(_('Password:'), align='center')
81 38
82 style = ['no_first_select'] 39 style = ['no_first_select']
40 profiles = host.bridge.getProfilesList()
41 profiles.sort()
83 self.list_profile = sat_widgets.List(profiles, style=style, align='center', on_change=self.onProfileChange) 42 self.list_profile = sat_widgets.List(profiles, style=style, align='center', on_change=self.onProfileChange)
84 43
85 #new & delete buttons 44 #new & delete buttons
86 buttons = [urwid.Button(_("New"), self.onNewProfile), 45 buttons = [urwid.Button(_("New"), self.onNewProfile),
87 urwid.Button(_("Delete"), self.onDeleteProfile)] 46 urwid.Button(_("Delete"), self.onDeleteProfile)]
97 list_walker = urwid.SimpleFocusListWalker([buttons_flow,self.list_profile, divider, self.login_wid, self.pass_wid, connect_button]) 56 list_walker = urwid.SimpleFocusListWalker([buttons_flow,self.list_profile, divider, self.login_wid, self.pass_wid, connect_button])
98 frame_body = urwid.ListBox(list_walker) 57 frame_body = urwid.ListBox(list_walker)
99 frame = urwid.Frame(frame_body,urwid.AttrMap(urwid.Text(_("Profile Manager"),align='center'),'title')) 58 frame = urwid.Frame(frame_body,urwid.AttrMap(urwid.Text(_("Profile Manager"),align='center'),'title'))
100 self.main_widget = urwid.LineBox(frame) 59 self.main_widget = urwid.LineBox(frame)
101 urwid.WidgetWrap.__init__(self, self.main_widget) 60 urwid.WidgetWrap.__init__(self, self.main_widget)
102 if self._autoconnect:
103 self.autoconnect(autoconnect)
104 61
105 def autoconnect(self, profile_keys): 62 self.go(autoconnect)
106 """Automatically connect profiles
107
108 @param profile_keys(iterable): list of profile keys to connect
109 """
110 if not profile_keys:
111 log.warning("No profile given to autoconnect")
112 return
113 self._autoconnect = True
114 self._autoconnect_profiles=[]
115 self._do_autoconnect(profile_keys)
116 63
117 64
118 def keypress(self, size, key): 65 def keypress(self, size, key):
119 if key == a_key['APP_QUIT']: 66 if key == a_key['APP_QUIT']:
120 self.host.onExit() 67 self.host.onExit()
133 list_box.set_focus(current_focus, 'above' if focus_diff == 1 else 'below') 80 list_box.set_focus(current_focus, 'above' if focus_diff == 1 else 'below')
134 list_box._invalidate() 81 list_box._invalidate()
135 return 82 return
136 return super(ProfileManager, self).keypress(size, key) 83 return super(ProfileManager, self).keypress(size, key)
137 84
138 def _do_autoconnect(self, profile_keys):
139 """Connect automatically given profiles
140
141 @param profile_kes(iterable): profiles to connect
142 """
143 assert self._autoconnect
144
145 def authenticate_cb(callback_id, data, profile):
146
147 if C.bool(data['validated']):
148 self._autoconnect_profiles.append(profile)
149 if len(self._autoconnect_profiles) == len(profile_keys):
150 # all the profiles have been validated
151 self.host.plug_profiles(self._autoconnect_profiles)
152 else:
153 # a profile is not validated, we go to manual mode
154 self._autoconnect=False
155
156 for profile_key in profile_keys:
157 profile = self.host.bridge.getProfileName(profile_key)
158 if not profile:
159 self._autoconnect = False # manual mode
160 msg = _("Trying to plug an unknown profile key ({})".format(profile_key))
161 log.warning(msg)
162 popup = sat_widgets.Alert(_("Profile plugging in error"), msg, ok_cb=self.host.removePopUp)
163 self.host.showPopUp(popup)
164 break
165 self.host.launchAction(C.AUTHENTICATE_PROFILE_ID, callback=authenticate_cb, profile=profile)
166
167 def refillProfiles(self):
168 """Update the list of profiles"""
169 profiles = self.host.bridge.getProfilesList()
170 profiles.sort()
171 self.list_profile.changeValues(profiles)
172 self.host.redraw()
173
174 def cancelDialog(self, button): 85 def cancelDialog(self, button):
175 self.host.removePopUp() 86 self.host.removePopUp()
176 87
177 def newProfile(self, button, edit): 88 def newProfile(self, button, edit):
178 """Create the profile""" 89 """Create the profile"""
187 self.getConnectionParams(profile) 98 self.getConnectionParams(profile)
188 self.host.redraw() 99 self.host.redraw()
189 100
190 def profileCreationFailure(self, reason): 101 def profileCreationFailure(self, reason):
191 self.host.removePopUp() 102 self.host.removePopUp()
192 if reason == "ConflictError": 103 message = self._getErrorMessage(reason)
193 message = _("A profile with this name already exists") 104 self.alert(_("Can't create profile"), message)
194 elif reason == "CancelError":
195 message = _("Profile creation cancelled by backend")
196 elif reason == "ValueError":
197 message = _("You profile name is not valid") # TODO: print a more informative message (empty name, name starting with '@')
198 else:
199 message = _("Can't create profile ({})").format(reason)
200 popup = sat_widgets.Alert(_("Can't create profile"), message, ok_cb=self.host.removePopUp)
201 self.host.showPopUp(popup)
202 105
203 def deleteProfile(self, button): 106 def deleteProfile(self, button):
204 if self.current.profile: 107 self._deleteProfile()
205 self.host.bridge.asyncDeleteProfile(self.current.profile, callback=self.refillProfiles)
206 self.resetFields()
207 self.host.removePopUp() 108 self.host.removePopUp()
208 109
209 def onNewProfile(self, e): 110 def onNewProfile(self, e):
210 pop_up_widget = sat_widgets.InputDialog(_("New profile"), _("Please enter a new profile name"), cancel_cb=self.cancelDialog, ok_cb=self.newProfile) 111 pop_up_widget = sat_widgets.InputDialog(_("New profile"), _("Please enter a new profile name"), cancel_cb=self.cancelDialog, ok_cb=self.newProfile)
211 self.host.showPopUp(pop_up_widget) 112 self.host.showPopUp(pop_up_widget)
213 def onDeleteProfile(self, e): 114 def onDeleteProfile(self, e):
214 if self.current.profile: 115 if self.current.profile:
215 pop_up_widget = sat_widgets.ConfirmDialog(_("Are you sure you want to delete the profile {} ?").format(self.current.profile), no_cb=self.cancelDialog, yes_cb=self.deleteProfile) 116 pop_up_widget = sat_widgets.ConfirmDialog(_("Are you sure you want to delete the profile {} ?").format(self.current.profile), no_cb=self.cancelDialog, yes_cb=self.deleteProfile)
216 self.host.showPopUp(pop_up_widget) 117 self.host.showPopUp(pop_up_widget)
217 118
119 def onConnectProfiles(self, button):
120 """Connect the profiles and start the main widget
121
122 @param button: the connect button
123 """
124 self._onConnectProfiles()
125
218 def resetFields(self): 126 def resetFields(self):
219 """Set profile to None, and reset fields""" 127 """Set profile to None, and reset fields"""
220 self.current.profile=None 128 super(ProfileManager, self).resetFields()
221 self.login_wid.set_edit_text("")
222 self.pass_wid.set_edit_text("")
223 self.list_profile.unselectAll(invisible=True) 129 self.list_profile.unselectAll(invisible=True)
224 130
225 def getConnectionParams(self, profile): 131 def setProfiles(self, profiles):
226 """Get login and password and display them 132 """Update the list of profiles"""
133 self.list_profile.changeValues(profiles)
134 self.host.redraw()
227 135
228 @param profile: %(doc_profile)s 136 def getProfiles(self):
229 """ 137 return self.list_profile.getSelectedValues()
230 def setJID(jabberID):
231 self.login_wid.set_edit_text(jabberID)
232 self.current.login = jabberID
233 self.host.redraw() # FIXME: redraw should be avoided
234 138
235 def setPassword(password): 139 def getJID(self):
236 self.pass_wid.set_edit_text(password) 140 return self.login_wid.get_edit_text()
237 self.current.password = password
238 self.host.redraw()
239 141
240 self.host.bridge.asyncGetParamA("JabberID", "Connection", profile_key=profile, callback=setJID, errback=self.getParamError) 142 def getPassword(self):
241 self.host.bridge.asyncGetParamA("Password", "Connection", profile_key=profile, callback=setPassword, errback=self.getParamError) 143 return self.pass_wid.get_edit_text()
242 144
243 def updateConnectionParams(self): 145 def setJID(self, jid_):
244 """Check if connection parameters have changed, and update them if so""" 146 self.login_wid.set_edit_text(jid_)
245 if self.current.profile: 147 self.current.login = jid_
246 login = self.login_wid.get_edit_text() 148 self.host.redraw() # FIXME: redraw should be avoided
247 password = self.pass_wid.get_edit_text() 149
248 if login != self.current.login and self.current.login is not None: 150 def setPassword(self, password):
249 self.current.login = login 151 self.pass_wid.set_edit_text(password)
250 self.host.bridge.setParam("JabberID", login, "Connection", profile_key=self.current.profile) 152 self.current.password = password
251 log.info("login updated for profile [{}]".format(self.current.profile)) 153 self.host.redraw()
252 if password != self.current.password and self.current.password is not None: 154
253 self.current.password = password 155 def alert(self, title, message):
254 self.host.bridge.setParam("Password", password, "Connection", profile_key=self.current.profile) 156 popup = sat_widgets.alert(title, message, ok_cb=self.host.removePopUp)
255 log.info("password updated for profile [{}]".format(self.current.profile)) 157 self.host.showPopUp(popup)
256 158
257 def onProfileChange(self, list_wid): 159 def onProfileChange(self, list_wid):
258 """This is called when a profile is selected in the profile list. 160 """This is called when a profile is selected in the profile list.
259 161
260 @param list_wid: the List widget who sent the event 162 @param list_wid: the List widget who sent the event
271 focused.setState(True, invisible=True) 173 focused.setState(True, invisible=True)
272 self.getConnectionParams(profile) 174 self.getConnectionParams(profile)
273 self.host.redraw() 175 self.host.redraw()
274 self.host.launchAction(C.AUTHENTICATE_PROFILE_ID, callback=authenticate_cb, profile=focused.text) 176 self.host.launchAction(C.AUTHENTICATE_PROFILE_ID, callback=authenticate_cb, profile=focused.text)
275 177
276 def onConnectProfiles(self, button):
277 """Connect the profiles and start the main widget
278
279 @param button: the connect button
280 """
281 if self._autoconnect:
282 pop_up_widget = sat_widgets.Alert(_('Internal error'), _('You can connect manually and automatically at the same time'), ok_cb=self.cancelDialog)
283 self.host.showPopUp(pop_up_widget)
284 return
285 self.updateConnectionParams()
286 profiles = self.list_profile.getSelectedValues()
287 if not profiles:
288 pop_up_widget = sat_widgets.Alert(_('No profile selected'), _('You need to create and select at least one profile before connecting'), ok_cb=self.cancelDialog)
289 self.host.showPopUp(pop_up_widget)
290 else:
291 # All profiles in the list are already validated, so we can plug them directly
292 self.host.plug_profiles(profiles)
293
294 def getParamError(self, dummy):
295 popup = sat_widgets.Alert("Error", _("Can't get profile parameter"), ok_cb=self.host.removePopUp)
296 self.host.showPopUp(popup)