comparison src/browser/libervia_main.py @ 589:a5019e62c3e9 frontends_multi_profiles

browser side: big refactoring to base Libervia on QuickFrontend, first draft: /!\ not finished, partially working and highly instable - add collections module with an OrderedDict like class - SatWebFrontend inherit from QuickApp - general sat_frontends tools.jid module is used - bridge/json methods have moved to json module - UniBox is partially removed (should be totally removed before merge to trunk) - Signals are now register with the generic registerSignal method (which is called mainly in QuickFrontend) - the generic getOrCreateWidget method from QuickWidgetsManager is used instead of Libervia's specific methods - all Widget are now based more or less directly on QuickWidget - with the new QuickWidgetsManager.getWidgets method, it's no more necessary to check all widgets which are instance of a particular class - ChatPanel and related moved to chat module - MicroblogPanel and related moved to blog module - global and overcomplicated send method has been disabled: each class should manage its own sending - for consistency with other frontends, former ContactPanel has been renamed to ContactList and vice versa - for the same reason, ChatPanel has been renamed to Chat - for compatibility with QuickFrontend, a fake profile is used in several places, it is set to C.PROF_KEY_NONE (real profile is managed server side for obvious security reasons) - changed default url for web panel to SàT website, and contact address to generic SàT contact address - ContactList is based on QuickContactList, UI changes are done in update method - bride call (now json module) have been greatly improved, in particular call can be done in the same way as for other frontends (bridge.method_name(arg1, arg2, ..., callback=cb, errback=eb). Blocking method must be called like async methods due to javascript architecture - in bridge calls, a callback can now exists without errback - hard reload on BridgeSignals remote error has been disabled, a better option should be implemented - use of constants where that make sens, some style improvments - avatars are temporarily disabled - lot of code disabled, will be fixed or removed before merge - various other changes, check diff for more details server side: manage remote exception on getEntityData, removed getProfileJid call, added getWaitingConf, added getRoomsSubjects
author Goffi <goffi@goffi.org>
date Sat, 24 Jan 2015 01:45:39 +0100
parents 0a06cf833f5a
children be2891462e63
comparison
equal deleted inserted replaced
585:bade589dbd5a 589:a5019e62c3e9
15 # GNU Affero General Public License for more details. 15 # GNU Affero General Public License for more details.
16 16
17 # You should have received a copy of the GNU Affero General Public License 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/>. 18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 19
20 import pyjd # this is dummy in pyjs
21 20
22 ### logging configuration ### 21 ### logging configuration ###
23 from sat_browser import logging 22 from sat_browser import logging
24 logging.configure() 23 logging.configure()
25 from sat.core.log import getLogger 24 from sat.core.log import getLogger
26 log = getLogger(__name__) 25 log = getLogger(__name__)
27 ### 26 ###
28 27
28 from sat_frontends.quick_frontend.quick_app import QuickApp
29
29 from sat_frontends.tools.misc import InputHistory 30 from sat_frontends.tools.misc import InputHistory
30 from sat_frontends.tools import strings 31 from sat_frontends.tools import strings
32 from sat_frontends.tools import jid
31 from sat.core.i18n import _ 33 from sat.core.i18n import _
32 34
33 from pyjamas.ui.RootPanel import RootPanel 35 from pyjamas.ui.RootPanel import RootPanel
34 from pyjamas.ui.HTML import HTML 36 from pyjamas.ui.HTML import HTML
35 from pyjamas.ui.KeyboardListener import KEY_ESCAPE 37 from pyjamas.ui.KeyboardListener import KEY_ESCAPE
36 from pyjamas.Timer import Timer 38 from pyjamas.Timer import Timer
37 from pyjamas import Window, DOM 39 from pyjamas import Window, DOM
38 from pyjamas.JSONService import JSONProxy 40
39 41 from sat_browser import json
40 from sat_browser import register 42 from sat_browser import register
41 from sat_browser import contact 43 from sat_browser.contact_list import ContactList
42 from sat_browser import base_widget 44 from sat_browser import base_widget
43 from sat_browser import panels 45 from sat_browser import panels
46 from sat_browser import chat
47 from sat_browser import blog
44 from sat_browser import dialog 48 from sat_browser import dialog
45 from sat_browser import jid
46 from sat_browser import xmlui 49 from sat_browser import xmlui
47 from sat_browser import html_tools 50 from sat_browser import html_tools
48 from sat_browser import notification 51 from sat_browser import notification
49 52
50 from sat_browser.constants import Const as C 53 from sat_browser.constants import Const as C
54
51 55
52 try: 56 try:
53 # FIXME: import plugin dynamically 57 # FIXME: import plugin dynamically
54 from sat_browser import plugin_sec_otr 58 from sat_browser import plugin_sec_otr
55 except ImportError: 59 except ImportError:
56 pass 60 pass
61
62 unicode = lambda s: str(s)
57 63
58 MAX_MBLOG_CACHE = 500 # Max microblog entries kept in memories 64 MAX_MBLOG_CACHE = 500 # Max microblog entries kept in memories
59 65
60 # Set to true to not create a new LiberviaWidget when a similar one 66 # Set to true to not create a new LiberviaWidget when a similar one
61 # already exist (i.e. a chat panel with the same target). Instead 67 # already exist (i.e. a chat panel with the same target). Instead
63 # and added to new base_widget.WidgetsPanel, or replaced to the expected 69 # and added to new base_widget.WidgetsPanel, or replaced to the expected
64 # position if the previous and the new parent are the same. 70 # position if the previous and the new parent are the same.
65 REUSE_EXISTING_LIBERVIA_WIDGETS = True 71 REUSE_EXISTING_LIBERVIA_WIDGETS = True
66 72
67 73
68 class LiberviaJsonProxy(JSONProxy): 74 class SatWebFrontend(InputHistory, QuickApp):
69 def __init__(self, *args, **kwargs):
70 JSONProxy.__init__(self, *args, **kwargs)
71 self.handler = self
72 self.cb = {}
73 self.eb = {}
74
75 def call(self, method, cb, *args):
76 _id = self.callMethod(method, args)
77 if cb:
78 if isinstance(cb, tuple):
79 if len(cb) != 2:
80 log.error("tuple syntax for bridge.call is (callback, errback), aborting")
81 return
82 if cb[0] is not None:
83 self.cb[_id] = cb[0]
84 self.eb[_id] = cb[1]
85 else:
86 self.cb[_id] = cb
87
88 def onRemoteResponse(self, response, request_info):
89 if request_info.id in self.cb:
90 _cb = self.cb[request_info.id]
91 # if isinstance(_cb, tuple):
92 # #we have arguments attached to the callback
93 # #we send them after the answer
94 # callback, args = _cb
95 # callback(response, *args)
96 # else:
97 # #No additional argument, we call directly the callback
98 _cb(response)
99 del self.cb[request_info.id]
100 if request_info.id in self.eb:
101 del self.eb[request_info.id]
102
103 def onRemoteError(self, code, errobj, request_info):
104 """def dump(obj):
105 print "\n\nDUMPING %s\n\n" % obj
106 for i in dir(obj):
107 print "%s: %s" % (i, getattr(obj,i))"""
108 if request_info.id in self.eb:
109 _eb = self.eb[request_info.id]
110 _eb((code, errobj))
111 del self.cb[request_info.id]
112 del self.eb[request_info.id]
113 else:
114 if code != 0:
115 log.error("Internal server error")
116 """for o in code, error, request_info:
117 dump(o)"""
118 else:
119 if isinstance(errobj['message'], dict):
120 log.error("Error %s: %s" % (errobj['message']['faultCode'], errobj['message']['faultString']))
121 else:
122 log.error("%s" % errobj['message'])
123
124
125 class RegisterCall(LiberviaJsonProxy):
126 def __init__(self):
127 LiberviaJsonProxy.__init__(self, "/register_api",
128 ["isRegistered", "isConnected", "asyncConnect", "registerParams", "getMenus"])
129
130
131 class BridgeCall(LiberviaJsonProxy):
132 def __init__(self):
133 LiberviaJsonProxy.__init__(self, "/json_api",
134 ["getContacts", "addContact", "sendMessage", "sendMblog", "sendMblogComment",
135 "getLastMblogs", "getMassiveLastMblogs", "getMblogComments", "getProfileJid",
136 "getHistory", "getPresenceStatuses", "joinMUC", "mucLeave", "getRoomsJoined",
137 "inviteMUC", "launchTarotGame", "getTarotCardsPaths", "tarotGameReady",
138 "tarotGamePlayCards", "launchRadioCollective", "getMblogs", "getMblogsWithComments",
139 "getWaitingSub", "subscription", "delContact", "updateContact", "getCard",
140 "getEntityData", "getParamsUI", "asyncGetParamA", "setParam", "launchAction",
141 "disconnect", "chatStateComposing", "getNewAccountDomain", "confirmationAnswer",
142 "syntaxConvert", "getAccountDialogUI", "getLastResource"
143 ])
144
145
146 class BridgeSignals(LiberviaJsonProxy):
147 RETRY_BASE_DELAY = 1000
148
149 def __init__(self, host):
150 self.host = host
151 self.retry_delay = self.RETRY_BASE_DELAY
152 LiberviaJsonProxy.__init__(self, "/json_signal_api",
153 ["getSignals"])
154
155 def onRemoteResponse(self, response, request_info):
156 self.retry_delay = self.RETRY_BASE_DELAY
157 LiberviaJsonProxy.onRemoteResponse(self, response, request_info)
158
159 def onRemoteError(self, code, errobj, request_info):
160 if errobj['message'] == 'Empty Response':
161 Window.getLocation().reload() # XXX: reset page in case of session ended.
162 # FIXME: Should be done more properly without hard reload
163 LiberviaJsonProxy.onRemoteError(self, code, errobj, request_info)
164 #we now try to reconnect
165 if isinstance(errobj['message'], dict) and errobj['message']['faultCode'] == 0:
166 Window.alert('You are not allowed to connect to server')
167 else:
168 def _timerCb(timer):
169 self.host.bridge_signals.call('getSignals', self.host._getSignalsCB)
170 Timer(notify=_timerCb).schedule(self.retry_delay)
171 self.retry_delay *= 2
172
173
174 class SatWebFrontend(InputHistory):
175 def onModuleLoad(self): 75 def onModuleLoad(self):
176 log.info("============ onModuleLoad ==============") 76 log.info("============ onModuleLoad ==============")
177 panels.ChatPanel.registerClass() 77 self.bridge_signals = json.BridgeSignals(self)
178 panels.MicroblogPanel.registerClass() 78 QuickApp.__init__(self, json.BridgeCall)
179 self.whoami = None 79 self.uni_box = None # FIXME: to be removed
180 self._selected_listeners = set()
181 self.bridge = BridgeCall()
182 self.bridge_signals = BridgeSignals(self)
183 self.uni_box = None
184 self.status_panel = HTML('<br />') 80 self.status_panel = HTML('<br />')
185 self.contact_panel = contact.ContactPanel(self) 81 # self.contact_panel = contact.ContactPanel(self)
186 self.panel = panels.MainPanel(self) 82 self.panel = panels.MainPanel(self)
187 self.discuss_panel = self.panel.discuss_panel 83 self.discuss_panel = self.panel.discuss_panel
188 self.tab_panel = self.panel.tab_panel 84 self.tab_panel = self.panel.tab_panel
189 self.tab_panel.addTabListener(self) 85 self.tab_panel.addTabListener(self)
190 self.libervia_widgets = set() # keep track of all actives LiberviaWidgets
191 self.room_list = [] # list of rooms
192 self.mblog_cache = [] # used to keep our own blog entries in memory, to show them in new mblog panel
193 self.avatars_cache = {} # keep track of jid's avatar hash (key=jid, value=file)
194 self._register_box = None 86 self._register_box = None
195 RootPanel().add(self.panel) 87 RootPanel().add(self.panel)
88
196 self.notification = notification.Notification() 89 self.notification = notification.Notification()
197 DOM.addEventPreview(self) 90 DOM.addEventPreview(self)
198 self.importPlugins() 91 self.importPlugins()
199 self._register = RegisterCall() 92 self._register = json.RegisterCall()
200 self._register.call('getMenus', self.gotMenus) 93 self._register.call('getMenus', self.gotMenus)
201 self._register.call('registerParams', None) 94 self._register.call('registerParams', None)
202 self._register.call('isRegistered', self._isRegisteredCB) 95 self._register.call('isRegistered', self._isRegisteredCB)
203 self.initialised = False 96 self.initialised = False
204 self.init_cache = [] # used to cache events until initialisation is done 97 self.init_cache = [] # used to cache events until initialisation is done
205 self.cached_params = {} 98 self.cached_params = {}
99
100 #FIXME: to be removed (managed with cache and in quick_frontend
101 self.avatars_cache = {} # keep track of jid's avatar hash (key=jid, value=file)
102 #FIXME: microblog cache should be managed directly in blog module
103 self.mblog_cache = [] # used to keep our own blog entries in memory, to show them in new mblog panel
104
105
106
107 # panels.ChatPanel.registerClass()
108 # panels.MicroblogPanel.registerClass()
109 # self._selected_listeners = set()
110 # # self.avatars_cache = {} # keep track of jid's avatar hash (key=jid, value=file)
111
112 @property
113 def whoami(self):
114 # XXX: works because Libervia is mono-profile
115 # if one day Libervia manage several profiles at once, this must be deleted
116 return self.profiles[C.PROF_KEY_NONE].whoami
117
118 @property
119 def contact_list(self):
120 return self.contact_lists[C.PROF_KEY_NONE]
121
122 def registerSignal(self, functionName, handler=None, iface="core", with_profile=True):
123 if handler is None:
124 callback = getattr(self, "{}{}".format(functionName, "Handler"))
125 else:
126 callback = handler
127
128 self.bridge_signals.register(functionName, callback, with_profile=with_profile)
206 129
207 def importPlugins(self): 130 def importPlugins(self):
208 self.plugins = {} 131 self.plugins = {}
209 inhibited_menus = [] 132 inhibited_menus = []
210 # FIXME: plugins import should be dynamic and generic like in sat 133 # FIXME: plugins import should be dynamic and generic like in sat
217 def inhibitMenus(self): 140 def inhibitMenus(self):
218 return inhibited_menus 141 return inhibited_menus
219 142
220 self.plugins['dummy_plugin'] = DummyPlugin() 143 self.plugins['dummy_plugin'] = DummyPlugin()
221 144
222 def addSelectedListener(self, callback): 145 # def addSelectedListener(self, callback):
223 self._selected_listeners.add(callback) 146 # self._selected_listeners.add(callback)
224 147
225 def getSelected(self): 148 def getSelected(self):
226 wid = self.tab_panel.getCurrentPanel() 149 wid = self.tab_panel.getCurrentPanel()
227 if not isinstance(wid, base_widget.WidgetsPanel): 150 if not isinstance(wid, base_widget.WidgetsPanel):
228 log.error("Tab widget is not a base_widget.WidgetsPanel, can't get selected widget") 151 log.error("Tab widget is not a base_widget.WidgetsPanel, can't get selected widget")
242 165
243 if selected: 166 if selected:
244 selected.removeStyleName('selected_widget') 167 selected.removeStyleName('selected_widget')
245 168
246 widgets_panel.selected = widget 169 widgets_panel.selected = widget
170 self.selected_widget = widget
247 171
248 if widget: 172 if widget:
249 widgets_panel.selected.addStyleName('selected_widget') 173 widgets_panel.selected.addStyleName('selected_widget')
250 174
251 for callback in self._selected_listeners: 175 # FIXME:
252 callback(widget) 176 # for callback in self._selected_listeners:
177 # callback(widget)
253 178
254 def resize(self): 179 def resize(self):
255 """Resize elements""" 180 """Resize elements"""
256 Window.onResize() 181 Window.onResize()
257 182
258 def onBeforeTabSelected(self, sender, tab_index): 183 def onBeforeTabSelected(self, sender, tab_index):
259 return True 184 return True
260 185
261 def onTabSelected(self, sender, tab_index): 186 def onTabSelected(self, sender, tab_index):
262 selected = self.getSelected() 187 selected = self.getSelected()
263 for callback in self._selected_listeners: 188 # FIXME:
264 callback(selected) 189 # for callback in self._selected_listeners:
190 # callback(selected)
265 191
266 def onEventPreview(self, event): 192 def onEventPreview(self, event):
267 if event.type in ["keydown", "keypress", "keyup"] and event.keyCode == KEY_ESCAPE: 193 if event.type in ["keydown", "keypress", "keyup"] and event.keyCode == KEY_ESCAPE:
268 #needed to prevent request cancellation in Firefox 194 #needed to prevent request cancellation in Firefox
269 event.preventDefault() 195 event.preventDefault()
270 return True 196 return True
271 197
272 def getAvatar(self, jid_str): 198 # FIXME: must not call _entityDataUpdatedCb by itself
273 """Return avatar of a jid if in cache, else ask for it. 199 # should not get VCard, backend plugin must be fixed too
274 200 # def getAvatar(self, jid_str):
275 @param jid_str (str): JID of the contact 201 # """Return avatar of a jid if in cache, else ask for it.
276 @return: the URL to the avatar (str) 202
277 """ 203 # @param jid_str (str): JID of the contact
278 def dataReceived(result): 204 # @return: the URL to the avatar (str)
279 if 'avatar' in result: 205 # """
280 self._entityDataUpdatedCb(jid_str, 'avatar', result['avatar']) 206 # def dataReceived(result):
281 else: 207 # if 'avatar' in result:
282 self.bridge.call("getCard", None, jid_str) 208 # self._entityDataUpdatedCb(jid_str, 'avatar', result['avatar'])
283 209 # else:
284 def avatarError(error_data): 210 # self.bridge.call("getCard", None, jid_str)
285 # The jid is maybe not in our roster, we ask for the VCard 211
286 self.bridge.call("getCard", None, jid_str) 212 # def avatarError(error_data):
287 213 # # The jid is maybe not in our roster, we ask for the VCard
288 if jid_str not in self.avatars_cache: 214 # self.bridge.call("getCard", None, jid_str)
289 self.bridge.call('getEntityData', (dataReceived, avatarError), jid_str, ['avatar']) 215
290 self.avatars_cache[jid_str] = C.DEFAULT_AVATAR 216 # if jid_str not in self.avatars_cache:
291 return self.avatars_cache[jid_str] 217 # self.bridge.call('getEntityData', (dataReceived, avatarError), jid_str, ['avatar'])
218 # self.avatars_cache[jid_str] = C.DEFAULT_AVATAR
219 # return self.avatars_cache[jid_str]
292 220
293 def registerWidget(self, wid): 221 def registerWidget(self, wid):
294 log.debug("Registering %s" % wid.getDebugName()) 222 log.debug("Registering %s" % wid.getDebugName())
295 self.libervia_widgets.add(wid) 223 self.libervia_widgets.add(wid)
296 224
301 log.warning('trying to remove a non registered Widget: %s' % wid.getDebugName()) 229 log.warning('trying to remove a non registered Widget: %s' % wid.getDebugName())
302 230
303 def refresh(self): 231 def refresh(self):
304 """Refresh the general display.""" 232 """Refresh the general display."""
305 self.panel.refresh() 233 self.panel.refresh()
306 if self.getCachedParam(C.COMPOSITION_KEY, C.ENABLE_UNIBOX_PARAM) == 'true':
307 self.uni_box = self.panel.unibox_panel.unibox
308 else:
309 self.uni_box = None
310 for lib_wid in self.libervia_widgets: 234 for lib_wid in self.libervia_widgets:
311 lib_wid.refresh() 235 lib_wid.refresh()
312 self.resize() 236 self.resize()
313 237
314 def addTab(self, label, wid, select=True): 238 def addTab(self, label, wid, select=True):
324 self.tab_panel.selectTab(self.tab_panel.getWidgetCount() - 1) 248 self.tab_panel.selectTab(self.tab_panel.getWidgetCount() - 1)
325 return widgets_panel 249 return widgets_panel
326 250
327 def addWidget(self, wid, tab_index=None): 251 def addWidget(self, wid, tab_index=None):
328 """ Add a widget at the bottom of the current or specified tab 252 """ Add a widget at the bottom of the current or specified tab
253
329 @param wid: LiberviaWidget to add 254 @param wid: LiberviaWidget to add
330 @param tab_index: index of the tab to add the widget to""" 255 @param tab_index: index of the tab to add the widget to
256 """
331 if tab_index is None or tab_index < 0 or tab_index >= self.tab_panel.getWidgetCount(): 257 if tab_index is None or tab_index < 0 or tab_index >= self.tab_panel.getWidgetCount():
332 panel = self.tab_panel.getCurrentPanel() 258 panel = self.tab_panel.getCurrentPanel()
333 else: 259 else:
334 panel = self.tab_panel.tabBar.getTabWidget(tab_index) 260 panel = self.tab_panel.tabBar.getTabWidget(tab_index)
335 panel.addWidget(wid) 261 panel.addWidget(wid)
349 continue 275 continue
350 menus_data = self.menus.setdefault(type_, []) 276 menus_data = self.menus.setdefault(type_, [])
351 menus_data.append((id_, path, path_i18n)) 277 menus_data.append((id_, path, path_i18n))
352 278
353 self.menus = {} 279 self.menus = {}
354 inhibited = set() 280 inhibited = set() # FIXME
355 extras = [] 281 extras = []
356 for plugin in self.plugins.values(): 282 for plugin in self.plugins.values():
357 if hasattr(plugin, "inhibitMenus"): 283 if hasattr(plugin, "inhibitMenus"):
358 inhibited.update(plugin.inhibitMenus()) 284 inhibited.update(plugin.inhibitMenus())
359 if hasattr(plugin, "extraMenus"): 285 if hasattr(plugin, "extraMenus"):
388 # display the real presence status panel 314 # display the real presence status panel
389 self.panel.header.remove(self.status_panel) 315 self.panel.header.remove(self.status_panel)
390 self.status_panel = panels.PresenceStatusPanel(self) 316 self.status_panel = panels.PresenceStatusPanel(self)
391 self.panel.header.add(self.status_panel) 317 self.panel.header.add(self.status_panel)
392 318
319 self.bridge_signals.call('getSignals', self.bridge_signals.signalHandler)
320
393 #it's time to fill the page 321 #it's time to fill the page
394 self.bridge.call('getContacts', self._getContactsCB) 322 # self.bridge.call('getContacts', self._getContactsCB)
395 self.bridge.call('getParamsUI', self._getParamsUICB) 323 # self.bridge.call('getParamsUI', self._getParamsUICB)
396 self.bridge_signals.call('getSignals', self._getSignalsCB) 324 # self.bridge_signals.call('getSignals', self._getSignalsCB)
397 #We want to know our own jid 325 # #We want to know our own jid
398 self.bridge.call('getProfileJid', self._getProfileJidCB) 326 # self.bridge.call('getProfileJid', self._getProfileJidCB)
399 327
400 def domain_cb(value): 328 def domain_cb(value):
401 self._defaultDomain = value 329 self._defaultDomain = value
402 log.info("new account domain: %s" % value) 330 log.info("new account domain: %s" % value)
403 331
404 def domain_eb(value): 332 def domain_eb(value):
405 self._defaultDomain = "libervia.org" 333 self._defaultDomain = "libervia.org"
406 334
407 self.bridge.call("getNewAccountDomain", (domain_cb, domain_eb)) 335 self.bridge.getNewAccountDomain(callback=domain_cb, errback=domain_eb)
408 self.discuss_panel.addWidget(panels.MicroblogPanel(self, [])) 336 self.plug_profiles([C.PROF_KEY_NONE]) # XXX: None was used intitially, but pyjamas bug when using variable arguments and None is the only arg.
409 337 microblog_widget = self.widgets.getOrCreateWidget(blog.MicroblogPanel, (), profile=C.PROF_KEY_NONE)
410 # get cached params and refresh the display 338 self.setSelected(microblog_widget)
411 def param_cb(cat, name, count): 339 # self.discuss_panel.addWidget(panels.MicroblogPanel(self, []))
412 count[0] += 1 340
413 refresh = count[0] == len(C.CACHED_PARAMS) 341 # # get cached params and refresh the display
414 return lambda value: self._paramUpdate(name, value, cat, refresh) 342 # def param_cb(cat, name, count):
415 343 # count[0] += 1
416 count = [0] # used to do something similar to DeferredList 344 # refresh = count[0] == len(C.CACHED_PARAMS)
417 for cat, name in C.CACHED_PARAMS: 345 # return lambda value: self._paramUpdate(name, value, cat, refresh)
418 self.bridge.call('asyncGetParamA', param_cb(cat, name, count), name, cat) 346
347 # count = [0] # used to do something similar to DeferredList
348 # for cat, name in C.CACHED_PARAMS:
349 # self.bridge.call('asyncGetParamA', param_cb(cat, name, count), name, cat)
350
351 def profilePlugged(self, profile):
352 #we fill the panels already here
353 for widget in self.widgets.getWidgets(blog.MicroblogPanel):
354 if widget.accept_all():
355 self.bridge.getMassiveLastMblogs('ALL', [], 10, profile=C.PROF_KEY_NONE, callback=widget.massiveInsert)
356 else:
357 self.bridge.getMassiveLastMblogs('GROUP', widget.accepted_groups, 10, profile=C.PROF_KEY_NONE, callback=widget.massiveInsert)
358
359 #we ask for our own microblogs:
360 self.bridge.getMassiveLastMblogs('JID', [unicode(self.whoami.bare)], 10, profile=C.PROF_KEY_NONE, callback=self._ownBlogsFills)
361
362 # initialize plugins which waited for the connection to be done
363 for plugin in self.plugins.values():
364 if hasattr(plugin, 'profileConnected'):
365 plugin.profileConnected()
366
367 def addContactList(self, dummy):
368 contact_list = ContactList(self)
369 self.contact_lists[C.PROF_KEY_NONE] = contact_list
370 self.panel.addContactList(contact_list)
371 return contact_list
372
373 def newWidget(self, widget):
374 log.debug("newWidget: {}".format(widget))
375 self.addWidget(widget)
376
377 def setStatusOnline(self, online=True, show="", statuses={}, profile=C.PROF_KEY_NONE):
378 log.warning("setStatusOnline is not implemented, as session are for unique profile which is always online for now")
419 379
420 def _tryAutoConnect(self, skip_validation=False): 380 def _tryAutoConnect(self, skip_validation=False):
421 """This method retrieve the eventual URL parameters to auto-connect the user. 381 """This method retrieve the eventual URL parameters to auto-connect the user.
422 @param skip_validation: if True, set the form values but do not validate it 382 @param skip_validation: if True, set the form values but do not validate it
423 """ 383 """
469 def _getContactsCB(self, contacts_data): 429 def _getContactsCB(self, contacts_data):
470 for contact_ in contacts_data: 430 for contact_ in contacts_data:
471 jid, attributes, groups = contact_ 431 jid, attributes, groups = contact_
472 self._newContactCb(jid, attributes, groups) 432 self._newContactCb(jid, attributes, groups)
473 433
474 def _getSignalsCB(self, signal_data):
475 self.bridge_signals.call('getSignals', self._getSignalsCB)
476 if len(signal_data) == 1:
477 signal_data.append([])
478 log.debug("Got signal ==> name: %s, params: %s" % (signal_data[0], signal_data[1]))
479 name, args = signal_data
480 if name == 'personalEvent':
481 self._personalEventCb(*args)
482 elif name == 'newMessage':
483 self._newMessageCb(*args)
484 elif name == 'presenceUpdate':
485 self._presenceUpdateCb(*args)
486 elif name == 'paramUpdate':
487 self._paramUpdate(*args)
488 elif name == 'roomJoined':
489 self._roomJoinedCb(*args)
490 elif name == 'roomLeft':
491 self._roomLeftCb(*args)
492 elif name == 'roomUserJoined':
493 self._roomUserJoinedCb(*args)
494 elif name == 'roomUserLeft':
495 self._roomUserLeftCb(*args)
496 elif name == 'roomUserChangedNick':
497 self._roomUserChangedNickCb(*args)
498 elif name == 'askConfirmation':
499 self._askConfirmation(*args)
500 elif name == 'newAlert':
501 self._newAlert(*args)
502 elif name == 'tarotGamePlayers':
503 self._tarotGameStartedCb(True, *args)
504 elif name == 'tarotGameStarted':
505 self._tarotGameStartedCb(False, *args)
506 elif name == 'tarotGameNew' or \
507 name == 'tarotGameChooseContrat' or \
508 name == 'tarotGameShowCards' or \
509 name == 'tarotGameInvalidCards' or \
510 name == 'tarotGameCardsPlayed' or \
511 name == 'tarotGameYourTurn' or \
512 name == 'tarotGameScore':
513 self._tarotGameGenericCb(name, args[0], args[1:])
514 elif name == 'radiocolPlayers':
515 self._radioColStartedCb(True, *args)
516 elif name == 'radiocolStarted':
517 self._radioColStartedCb(False, *args)
518 elif name == 'radiocolPreload':
519 self._radioColGenericCb(name, args[0], args[1:])
520 elif name == 'radiocolPlay':
521 self._radioColGenericCb(name, args[0], args[1:])
522 elif name == 'radiocolNoUpload':
523 self._radioColGenericCb(name, args[0], args[1:])
524 elif name == 'radiocolUploadOk':
525 self._radioColGenericCb(name, args[0], args[1:])
526 elif name == 'radiocolSongRejected':
527 self._radioColGenericCb(name, args[0], args[1:])
528 elif name == 'subscribe':
529 self._subscribeCb(*args)
530 elif name == 'contactDeleted':
531 self._contactDeletedCb(*args)
532 elif name == 'newContact':
533 self._newContactCb(*args)
534 elif name == 'entityDataUpdated':
535 self._entityDataUpdatedCb(*args)
536 elif name == 'chatStateReceived':
537 self._chatStateReceivedCb(*args)
538
539 def _getParamsUICB(self, xml_ui): 434 def _getParamsUICB(self, xml_ui):
540 """Hide the parameters item if there's nothing to display""" 435 """Hide the parameters item if there's nothing to display"""
541 if not xml_ui: 436 if not xml_ui:
542 self.panel.menu.removeItemParams() 437 self.panel.menu.removeItemParams()
543 438
550 continue 445 continue
551 if 'groups' in mblog: 446 if 'groups' in mblog:
552 _groups = set(mblog['groups'].split() if mblog['groups'] else []) 447 _groups = set(mblog['groups'].split() if mblog['groups'] else [])
553 else: 448 else:
554 _groups = None 449 _groups = None
555 mblog_entry = panels.MicroblogItem(mblog) 450 mblog_entry = blog.MicroblogItem(mblog)
556 self.mblog_cache.append((_groups, mblog_entry)) 451 self.mblog_cache.append((_groups, mblog_entry))
557 452
558 if len(self.mblog_cache) > MAX_MBLOG_CACHE: 453 if len(self.mblog_cache) > MAX_MBLOG_CACHE:
559 del self.mblog_cache[0:len(self.mblog_cache - MAX_MBLOG_CACHE)] 454 del self.mblog_cache[0:len(self.mblog_cache - MAX_MBLOG_CACHE)]
560 for lib_wid in self.libervia_widgets: 455 for widget in self.widgets.getWidgets(blog.MicroblogPanel):
561 if isinstance(lib_wid, panels.MicroblogPanel): 456 self.FillMicroblogPanel(widget)
562 self.FillMicroblogPanel(lib_wid) 457
458 # FIXME
563 self.initialised = True # initialisation phase is finished here 459 self.initialised = True # initialisation phase is finished here
564 for event_data in self.init_cache: # so we have to send all the cached events 460 for event_data in self.init_cache: # so we have to send all the cached events
565 self._personalEventCb(*event_data) 461 self._personalEventCb(*event_data)
566 del self.init_cache 462 del self.init_cache
567 463
568 def _getProfileJidCB(self, jid_s): 464 def _getProfileJidCB(self, jid_s):
569 self.whoami = jid.JID(jid_s) 465 # FIXME
570 #we can now ask our status 466 raise Exception("should not be here !")
571 self.bridge.call('getPresenceStatuses', self._getPresenceStatusesCb) 467 # self.whoami = jid.JID(jid_s)
572 #the rooms where we are 468 # #we can now ask our status
573 self.bridge.call('getRoomsJoined', self._getRoomsJoinedCb) 469 # self.bridge.call('getPresenceStatuses', self._getPresenceStatusesCb)
574 #and if there is any subscription request waiting for us 470 # #the rooms where we are
575 self.bridge.call('getWaitingSub', self._getWaitingSubCb) 471 # self.bridge.call('getRoomsJoined', self._getRoomsJoinedCb)
576 #we fill the panels already here 472 # #and if there is any subscription request waiting for us
577 for lib_wid in self.libervia_widgets: 473 # self.bridge.call('getWaitingSub', self._getWaitingSubCb)
578 if isinstance(lib_wid, panels.MicroblogPanel): 474 # #we fill the panels already here
579 if lib_wid.accept_all(): 475 # for lib_wid in self.libervia_widgets:
580 self.bridge.call('getMassiveLastMblogs', lib_wid.massiveInsert, 'ALL', [], 10) 476 # if isinstance(lib_wid, panels.MicroblogPanel):
581 else: 477 # if lib_wid.accept_all():
582 self.bridge.call('getMassiveLastMblogs', lib_wid.massiveInsert, 'GROUP', lib_wid.accepted_groups, 10) 478 # self.bridge.call('getMassiveLastMblogs', lib_wid.massiveInsert, 'ALL', [], 10)
583 479 # else:
584 #we ask for our own microblogs: 480 # self.bridge.call('getMassiveLastMblogs', lib_wid.massiveInsert, 'GROUP', lib_wid.accepted_groups, 10)
585 self.bridge.call('getMassiveLastMblogs', self._ownBlogsFills, 'JID', [self.whoami.bare], 10) 481
586 482 # #we ask for our own microblogs:
587 # initialize plugins which waited for the connection to be done 483 # self.bridge.call('getMassiveLastMblogs', self._ownBlogsFills, 'JID', [self.whoami.bare], 10)
588 for plugin in self.plugins.values(): 484
589 if hasattr(plugin, 'profileConnected'): 485 # # initialize plugins which waited for the connection to be done
590 plugin.profileConnected() 486 # for plugin in self.plugins.values():
487 # if hasattr(plugin, 'profileConnected'):
488 # plugin.profileConnected()
591 489
592 ## Signals callbacks ## 490 ## Signals callbacks ##
593 491
594 def _personalEventCb(self, sender, event_type, data): 492 def _personalEventCb(self, sender, event_type, data):
595 if not self.initialised: 493 if not self.initialised:
602 return 500 return
603 if 'groups' in data: 501 if 'groups' in data:
604 _groups = set(data['groups'].split() if data['groups'] else []) 502 _groups = set(data['groups'].split() if data['groups'] else [])
605 else: 503 else:
606 _groups = None 504 _groups = None
607 mblog_entry = panels.MicroblogItem(data) 505 mblog_entry = blog.MicroblogItem(data)
608 506
609 for lib_wid in self.libervia_widgets: 507 for widget in self.widgets.getWidgets(blog.MicroblogPanel):
610 if isinstance(lib_wid, panels.MicroblogPanel): 508 self.addBlogEntry(widget, sender, _groups, mblog_entry)
611 self.addBlogEntry(lib_wid, sender, _groups, mblog_entry)
612 509
613 if sender == self.whoami.bare: 510 if sender == self.whoami.bare:
614 found = False 511 found = False
615 for index in xrange(0, len(self.mblog_cache)): 512 for index in xrange(0, len(self.mblog_cache)):
616 entry = self.mblog_cache[index] 513 entry = self.mblog_cache[index]
623 if not found: 520 if not found:
624 self.mblog_cache.append((_groups, mblog_entry)) 521 self.mblog_cache.append((_groups, mblog_entry))
625 if len(self.mblog_cache) > MAX_MBLOG_CACHE: 522 if len(self.mblog_cache) > MAX_MBLOG_CACHE:
626 del self.mblog_cache[0:len(self.mblog_cache - MAX_MBLOG_CACHE)] 523 del self.mblog_cache[0:len(self.mblog_cache - MAX_MBLOG_CACHE)]
627 elif event_type == 'MICROBLOG_DELETE': 524 elif event_type == 'MICROBLOG_DELETE':
628 for lib_wid in self.libervia_widgets: 525 for widget in self.widgets.getWidgets(blog.MicroblogPanel):
629 if isinstance(lib_wid, panels.MicroblogPanel): 526 widget.removeEntry(data['type'], data['id'])
630 lib_wid.removeEntry(data['type'], data['id'])
631 log.debug("%s %s %s" % (self.whoami.bare, sender, data['type'])) 527 log.debug("%s %s %s" % (self.whoami.bare, sender, data['type']))
632 528
633 if sender == self.whoami.bare and data['type'] == 'main_item': 529 if sender == self.whoami.bare and data['type'] == 'main_item':
634 for index in xrange(0, len(self.mblog_cache)): 530 for index in xrange(0, len(self.mblog_cache)):
635 entry = self.mblog_cache[index] 531 entry = self.mblog_cache[index]
661 for lib_wid in self.libervia_widgets: 557 for lib_wid in self.libervia_widgets:
662 if isinstance(lib_wid, panels.MicroblogPanel): 558 if isinstance(lib_wid, panels.MicroblogPanel):
663 if lib_wid.isJidAccepted(entity): 559 if lib_wid.isJidAccepted(entity):
664 self.bridge.call('getMassiveLastMblogs', lib_wid.massiveInsert, 'JID', [entity], 10) 560 self.bridge.call('getMassiveLastMblogs', lib_wid.massiveInsert, 'JID', [entity], 10)
665 561
666 def getLiberviaWidget(self, class_, entity, ignoreOtherTabs=True): 562 # def getLiberviaWidget(self, class_, entity, ignoreOtherTabs=True):
667 """Get the corresponding panel if it exists. 563 # """Get the corresponding panel if it exists.
668 @param class_ (class): class of the panel (ChatPanel, MicroblogPanel...) 564 # @param class_ (class): class of the panel (ChatPanel, MicroblogPanel...)
669 @param entity (dict): dictionnary to define the entity. 565 # @param entity (dict): dictionnary to define the entity.
670 @param ignoreOtherTabs (bool): if True, the widgets that are not 566 # @param ignoreOtherTabs (bool): if True, the widgets that are not
671 contained by the currently selected tab will be ignored 567 # contained by the currently selected tab will be ignored
672 @return: the existing widget that has been found or None.""" 568 # @return: the existing widget that has been found or None."""
673 selected_tab = self.tab_panel.getCurrentPanel() 569 # selected_tab = self.tab_panel.getCurrentPanel()
674 for lib_wid in self.libervia_widgets: 570 # for lib_wid in self.libervia_widgets:
675 parent = lib_wid.getWidgetsPanel(expect=False) 571 # parent = lib_wid.getWidgetsPanel(expect=False)
676 if parent is None or (ignoreOtherTabs and parent != selected_tab): 572 # if parent is None or (ignoreOtherTabs and parent != selected_tab):
677 # do not return a widget that is not in the currently selected tab 573 # # do not return a widget that is not in the currently selected tab
678 continue 574 # continue
679 if isinstance(lib_wid, class_): 575 # if isinstance(lib_wid, class_):
680 try: 576 # try:
681 if lib_wid.matchEntity(*(entity.values())): # XXX: passing **entity bugs! 577 # if lib_wid.matchEntity(*(entity.values())): # XXX: passing **entity bugs!
682 log.debug("existing widget found: %s" % lib_wid.getDebugName()) 578 # log.debug("existing widget found: %s" % lib_wid.getDebugName())
683 return lib_wid 579 # return lib_wid
684 except AttributeError as e: 580 # except AttributeError as e:
685 e.stack_list() 581 # e.stack_list()
686 return None 582 # return None
687 return None 583 # return None
688 584
689 def getOrCreateLiberviaWidget(self, class_, entity, select=True, new_tab=None): 585 # def getOrCreateLiberviaWidget(self, class_, entity, select=True, new_tab=None):
690 """Get the matching LiberviaWidget if it exists, or create a new one. 586 # """Get the matching LiberviaWidget if it exists, or create a new one.
691 @param class_ (class): class of the panel (ChatPanel, MicroblogPanel...) 587 # @param class_ (class): class of the panel (ChatPanel, MicroblogPanel...)
692 @param entity (dict): dictionnary to define the entity. 588 # @param entity (dict): dictionnary to define the entity.
693 @param select (bool): if True, select the widget that has been found or created 589 # @param select (bool): if True, select the widget that has been found or created
694 @param new_tab (str): if not None, a widget which is created is created in 590 # @param new_tab (str): if not None, a widget which is created is created in
695 a new tab. In that case new_tab is a unicode to label that new tab. 591 # a new tab. In that case new_tab is a unicode to label that new tab.
696 If new_tab is not None and a widget is found, no tab is created. 592 # If new_tab is not None and a widget is found, no tab is created.
697 @return: the newly created wigdet if REUSE_EXISTING_LIBERVIA_WIDGETS 593 # @return: the newly created wigdet if REUSE_EXISTING_LIBERVIA_WIDGETS
698 is set to False or if the widget has not been found, the existing 594 # is set to False or if the widget has not been found, the existing
699 widget that has been found otherwise.""" 595 # widget that has been found otherwise."""
700 lib_wid = None 596 # lib_wid = None
701 tab = None 597 # tab = None
702 if REUSE_EXISTING_LIBERVIA_WIDGETS: 598 # if REUSE_EXISTING_LIBERVIA_WIDGETS:
703 lib_wid = self.getLiberviaWidget(class_, entity, new_tab is None) 599 # lib_wid = self.getLiberviaWidget(class_, entity, new_tab is None)
704 if lib_wid is None: # create a new widget 600 # if lib_wid is None: # create a new widget
705 lib_wid = class_.createPanel(self, *(entity.values())) # XXX: passing **entity bugs! 601 # lib_wid = class_.createPanel(self, *(entity.values())) # XXX: passing **entity bugs!
706 if new_tab is None: 602 # if new_tab is None:
707 self.addWidget(lib_wid) 603 # self.addWidget(lib_wid)
708 else: 604 # else:
709 tab = self.addTab(new_tab, lib_wid, False) 605 # tab = self.addTab(new_tab, lib_wid, False)
710 else: # reuse existing widget 606 # else: # reuse existing widget
711 tab = lib_wid.getWidgetsPanel(expect=False) 607 # tab = lib_wid.getWidgetsPanel(expect=False)
712 if new_tab is None: 608 # if new_tab is None:
713 if tab is not None: 609 # if tab is not None:
714 tab.removeWidget(lib_wid) 610 # tab.removeWidget(lib_wid)
715 self.addWidget(lib_wid) 611 # self.addWidget(lib_wid)
716 if select: 612 # if select:
717 if new_tab is not None: 613 # if new_tab is not None:
718 self.tab_panel.selectTab(tab) 614 # self.tab_panel.selectTab(tab)
719 # must be done after the widget is added, 615 # # must be done after the widget is added,
720 # for example to scroll to the bottom 616 # # for example to scroll to the bottom
721 self.setSelected(lib_wid) 617 # self.setSelected(lib_wid)
722 lib_wid.refresh() 618 # lib_wid.refresh()
723 return lib_wid 619 # return lib_wid
724 620
725 def getRoomWidget(self, target): 621 # def getRoomWidget(self, target):
726 """Get the MUC widget for the given target. 622 # """Get the MUC widget for the given target.
727 623
728 @param target (jid.JID): BARE jid of the MUC 624 # @param target (jid.JID): BARE jid of the MUC
729 @return: panels.ChatPanel instance or None 625 # @return: panels.ChatPanel instance or None
730 """ 626 # """
731 entity = {'item': target, 'type_': 'group'} 627 # entity = {'item': target, 'type_': 'group'}
732 if target.full() in self.room_list or target in self.room_list: # as JID is a string-based class, we don't know what will please Pyjamas... 628 # if target.full() in self.room_list or target in self.room_list: # as JID is a string-based class, we don't know what will please Pyjamas...
733 return self.getLiberviaWidget(panels.ChatPanel, entity, ignoreOtherTabs=False) 629 # return self.getLiberviaWidget(panels.ChatPanel, entity, ignoreOtherTabs=False)
734 return None 630 # return None
735 631
736 def getOrCreateRoomWidget(self, target): 632 # def getOrCreateRoomWidget(self, target):
737 """Get the MUC widget for the given target, create it if necessary. 633 # """Get the MUC widget for the given target, create it if necessary.
738 634
739 @param target (jid.JID): BARE jid of the MUC 635 # @param target (jid.JID): BARE jid of the MUC
740 @return: panels.ChatPanel instance 636 # @return: panels.ChatPanel instance
741 """ 637 # """
742 lib_wid = self.getRoomWidget(target) 638 # lib_wid = self.getRoomWidget(target)
743 if lib_wid: 639 # if lib_wid:
744 return lib_wid 640 # return lib_wid
745 641
746 # XXX: target.node.startwith(...) raises an error "startswith is not a function" 642 # # XXX: target.node.startwith(...) raises an error "startswith is not a function"
747 # This happens when node a is property defined in the JID class 643 # # This happens when node a is property defined in the JID class
748 # FIXME: pyjamas doesn't handle the properties well 644 # # FIXME: pyjamas doesn't handle the properties well
749 node = target.node 645 # node = target.node
750 646
751 # XXX: it's not really beautiful, but it works :) 647 # # XXX: it's not really beautiful, but it works :)
752 if node.startswith('sat_tarot_'): 648 # if node.startswith('sat_tarot_'):
753 tab_name = "Tarot" 649 # tab_name = "Tarot"
754 elif node.startswith('sat_radiocol_'): 650 # elif node.startswith('sat_radiocol_'):
755 tab_name = "Radio collective" 651 # tab_name = "Radio collective"
756 else: 652 # else:
757 tab_name = target.node 653 # tab_name = target.node
758 654
759 self.room_list.append(target) 655 # self.room_list.append(target)
760 entity = {'item': target, 'type_': 'group'} 656 # entity = {'item': target, 'type_': 'group'}
761 return self.getOrCreateLiberviaWidget(panels.ChatPanel, entity, new_tab=tab_name) 657 # return self.getOrCreateLiberviaWidget(panels.ChatPanel, entity, new_tab=tab_name)
762 658
763 def _newMessageCb(self, from_jid_s, msg, msg_type, to_jid_s, extra): 659 # def _newMessageCb(self, from_jid_s, msg, msg_type, to_jid_s, extra):
764 from_jid = jid.JID(from_jid_s) 660 # from_jid = jid.JID(from_jid_s)
765 to_jid = jid.JID(to_jid_s) 661 # to_jid = jid.JID(to_jid_s)
766 for plugin in self.plugins.values(): 662 # for plugin in self.plugins.values():
767 if hasattr(plugin, 'messageReceivedTrigger'): 663 # if hasattr(plugin, 'messageReceivedTrigger'):
768 if not plugin.messageReceivedTrigger(from_jid, msg, msg_type, to_jid, extra): 664 # if not plugin.messageReceivedTrigger(from_jid, msg, msg_type, to_jid, extra):
769 return # plugin returned False to interrupt the process 665 # return # plugin returned False to interrupt the process
770 self.newMessageCb(from_jid, msg, msg_type, to_jid, extra) 666 # self.newMessageCb(from_jid, msg, msg_type, to_jid, extra)
771 667
772 def newMessageCb(self, from_jid, msg, msg_type, to_jid, extra): 668 # def newMessageCb(self, from_jid, msg, msg_type, to_jid, extra):
773 other = to_jid if from_jid.bare == self.whoami.bare else from_jid 669 # other = to_jid if from_jid.bare == self.whoami.bare else from_jid
774 lib_wid = self.getLiberviaWidget(panels.ChatPanel, {'item': other}, ignoreOtherTabs=False) 670 # lib_wid = self.getLiberviaWidget(panels.ChatPanel, {'item': other}, ignoreOtherTabs=False)
775 self.displayNotification(from_jid, msg) 671 # self.displayNotification(from_jid, msg)
776 if msg_type == 'headline' and from_jid.full() == self._defaultDomain: 672 # if msg_type == 'headline' and from_jid.full() == self._defaultDomain:
777 try: 673 # try:
778 assert extra['subject'] # subject is defined and not empty 674 # assert extra['subject'] # subject is defined and not empty
779 title = extra['subject'] 675 # title = extra['subject']
780 except (KeyError, AssertionError): 676 # except (KeyError, AssertionError):
781 title = _('Announcement from %s') % from_jid.full() 677 # title = _('Announcement from %s') % from_jid.full()
782 msg = strings.addURLToText(html_tools.XHTML2Text(msg)) 678 # msg = strings.addURLToText(html_tools.XHTML2Text(msg))
783 dialog.InfoDialog(title, msg).show() 679 # dialog.InfoDialog(title, msg).show()
784 return 680 # return
785 if lib_wid is not None: 681 # if lib_wid is not None:
786 if msg_type == C.MESS_TYPE_INFO: 682 # if msg_type == C.MESS_TYPE_INFO:
787 lib_wid.printInfo(msg) 683 # lib_wid.printInfo(msg)
788 else: 684 # else:
789 lib_wid.printMessage(from_jid, msg, extra) 685 # lib_wid.printMessage(from_jid, msg, extra)
790 if 'header_info' in extra: 686 # if 'header_info' in extra:
791 lib_wid.setHeaderInfo(extra['header_info']) 687 # lib_wid.setHeaderInfo(extra['header_info'])
792 else: 688 # else:
793 # FIXME: "info" message and header info will be lost here 689 # # FIXME: "info" message and header info will be lost here
794 if not self.contact_panel.isContactInRoster(other.bare): 690 # if not self.contact_panel.isContactInRoster(other.bare):
795 self.contact_panel.updateContact(other.bare, {}, [C.GROUP_NOT_IN_ROSTER]) 691 # self.contact_panel.updateContact(other.bare, {}, [C.GROUP_NOT_IN_ROSTER])
796 # The message has not been shown, we must indicate it 692 # # The message has not been shown, we must indicate it
797 self.contact_panel.setContactMessageWaiting(other.bare, True) 693 # self.contact_panel.setContactMessageWaiting(other.bare, True)
798 694
799 def _presenceUpdateCb(self, entity, show, priority, statuses): 695 # def _presenceUpdateCb(self, entity, show, priority, statuses):
800 entity_jid = jid.JID(entity) 696 # entity_jid = jid.JID(entity)
801 if self.whoami and self.whoami == entity_jid: # XXX: QnD way to get our presence/status 697 # if self.whoami and self.whoami == entity_jid: # XXX: QnD way to get our presence/status
802 assert(isinstance(self.status_panel, panels.PresenceStatusPanel)) 698 # assert(isinstance(self.status_panel, panels.PresenceStatusPanel))
803 self.status_panel.setPresence(show) # pylint: disable=E1103 699 # self.status_panel.setPresence(show) # pylint: disable=E1103
804 if statuses: 700 # if statuses:
805 self.status_panel.setStatus(statuses.values()[0]) # pylint: disable=E1103 701 # self.status_panel.setStatus(statuses.values()[0]) # pylint: disable=E1103
806 else: 702 # else:
807 bare_jid = entity_jid.bareJID() 703 # bare_jid = entity_jid.bareJID()
808 if bare_jid.full() in self.room_list or bare_jid in self.room_list: # as JID is a string-based class, we don't know what will please Pyjamas... 704 # if bare_jid.full() in self.room_list or bare_jid in self.room_list: # as JID is a string-based class, we don't know what will please Pyjamas...
809 wid = self.getRoomWidget(bare_jid) 705 # wid = self.getRoomWidget(bare_jid)
810 else: 706 # else:
811 wid = self.contact_panel 707 # wid = self.contact_panel
812 if show == 'unavailable': # XXX: save some resources as for now we only need 'unavailable' 708 # if show == 'unavailable': # XXX: save some resources as for now we only need 'unavailable'
813 for plugin in self.plugins.values(): 709 # for plugin in self.plugins.values():
814 if hasattr(plugin, 'presenceReceivedTrigger'): 710 # if hasattr(plugin, 'presenceReceivedTrigger'):
815 plugin.presenceReceivedTrigger(entity_jid, show, priority, statuses) 711 # plugin.presenceReceivedTrigger(entity_jid, show, priority, statuses)
816 if wid: 712 # if wid:
817 wid.setConnected(entity_jid.bare, entity_jid.resource, show, priority, statuses) 713 # wid.setConnected(entity_jid.bare, entity_jid.resource, show, priority, statuses)
818 714
819 def _roomJoinedCb(self, room_jid_s, room_nicks, user_nick): 715 # def _roomJoinedCb(self, room_jid_s, room_nicks, user_nick):
820 chat_panel = self.getOrCreateRoomWidget(jid.JID(room_jid_s)) 716 # chat_panel = self.getOrCreateRoomWidget(jid.JID(room_jid_s))
821 chat_panel.setUserNick(user_nick) 717 # chat_panel.setUserNick(user_nick)
822 chat_panel.setPresents(room_nicks) 718 # chat_panel.setPresents(room_nicks)
823 chat_panel.refresh() 719 # chat_panel.refresh()
824 720
825 def _roomLeftCb(self, room_jid_s, room_nicks, user_nick): 721 # def _roomLeftCb(self, room_jid_s, room_nicks, user_nick):
826 try: 722 # try:
827 del self.room_list[room_jid_s] 723 # del self.room_list[room_jid_s]
828 except KeyError: 724 # except KeyError:
829 try: # as JID is a string-based class, we don't know what will please Pyjamas... 725 # try: # as JID is a string-based class, we don't know what will please Pyjamas...
830 del self.room_list[jid.JID(room_jid_s)] 726 # del self.room_list[jid.JID(room_jid_s)]
831 except KeyError: 727 # except KeyError:
832 pass 728 # pass
833 729
834 def _roomUserJoinedCb(self, room_jid_s, user_nick, user_data): 730 # def _roomUserJoinedCb(self, room_jid_s, user_nick, user_data):
835 lib_wid = self.getOrCreateRoomWidget(jid.JID(room_jid_s)) 731 # lib_wid = self.getOrCreateRoomWidget(jid.JID(room_jid_s))
836 if lib_wid: 732 # if lib_wid:
837 lib_wid.userJoined(user_nick, user_data) 733 # lib_wid.userJoined(user_nick, user_data)
838 734
839 def _roomUserLeftCb(self, room_jid_s, user_nick, user_data): 735 # def _roomUserLeftCb(self, room_jid_s, user_nick, user_data):
840 lib_wid = self.getRoomWidget(jid.JID(room_jid_s)) 736 # lib_wid = self.getRoomWidget(jid.JID(room_jid_s))
841 if lib_wid: 737 # if lib_wid:
842 lib_wid.userLeft(user_nick, user_data) 738 # lib_wid.userLeft(user_nick, user_data)
843 739
844 def _roomUserChangedNickCb(self, room_jid_s, old_nick, new_nick): 740 # def _roomUserChangedNickCb(self, room_jid_s, old_nick, new_nick):
845 """Called when an user joined a MUC room""" 741 # """Called when an user joined a MUC room"""
846 lib_wid = self.getRoomWidget(jid.JID(room_jid_s)) 742 # lib_wid = self.getRoomWidget(jid.JID(room_jid_s))
847 if lib_wid: 743 # if lib_wid:
848 lib_wid.changeUserNick(old_nick, new_nick) 744 # lib_wid.changeUserNick(old_nick, new_nick)
849 745
850 def _tarotGameStartedCb(self, waiting, room_jid_s, referee, players): 746 # def _tarotGameStartedCb(self, waiting, room_jid_s, referee, players):
851 lib_wid = self.getRoomWidget(jid.JID(room_jid_s)) 747 # lib_wid = self.getRoomWidget(jid.JID(room_jid_s))
852 if lib_wid: 748 # if lib_wid:
853 lib_wid.startGame("Tarot", waiting, referee, players) 749 # lib_wid.startGame("Tarot", waiting, referee, players)
854 750
855 def _tarotGameGenericCb(self, event_name, room_jid_s, args): 751 # def _tarotGameGenericCb(self, event_name, room_jid_s, args):
856 lib_wid = self.getRoomWidget(jid.JID(room_jid_s)) 752 # lib_wid = self.getRoomWidget(jid.JID(room_jid_s))
857 if lib_wid: 753 # if lib_wid:
858 getattr(lib_wid.getGame("Tarot"), event_name)(*args) 754 # getattr(lib_wid.getGame("Tarot"), event_name)(*args)
859 755
860 def _radioColStartedCb(self, waiting, room_jid_s, referee, players, queue_data): 756 # def _radioColStartedCb(self, waiting, room_jid_s, referee, players, queue_data):
861 lib_wid = self.getRoomWidget(jid.JID(room_jid_s)) 757 # lib_wid = self.getRoomWidget(jid.JID(room_jid_s))
862 if lib_wid: 758 # if lib_wid:
863 lib_wid.startGame("RadioCol", waiting, referee, players, queue_data) 759 # lib_wid.startGame("RadioCol", waiting, referee, players, queue_data)
864 760
865 def _radioColGenericCb(self, event_name, room_jid_s, args): 761 # def _radioColGenericCb(self, event_name, room_jid_s, args):
866 lib_wid = self.getRoomWidget(jid.JID(room_jid_s)) 762 # lib_wid = self.getRoomWidget(jid.JID(room_jid_s))
867 if lib_wid: 763 # if lib_wid:
868 getattr(lib_wid.getGame("RadioCol"), event_name)(*args) 764 # getattr(lib_wid.getGame("RadioCol"), event_name)(*args)
869 765
870 def _getPresenceStatusesCb(self, presence_data): 766 def _getPresenceStatusesCb(self, presence_data):
871 for entity in presence_data: 767 for entity in presence_data:
872 for resource in presence_data[entity]: 768 for resource in presence_data[entity]:
873 args = presence_data[entity][resource] 769 args = presence_data[entity][resource]
921 for lib_wid in self.libervia_widgets: 817 for lib_wid in self.libervia_widgets:
922 if isinstance(lib_wid, panels.MicroblogPanel): 818 if isinstance(lib_wid, panels.MicroblogPanel):
923 if lib_wid.isJidAccepted(entity_jid_s) or (self.whoami and entity_jid_s == self.whoami.bare): 819 if lib_wid.isJidAccepted(entity_jid_s) or (self.whoami and entity_jid_s == self.whoami.bare):
924 lib_wid.updateValue('avatar', entity_jid_s, avatar) 820 lib_wid.updateValue('avatar', entity_jid_s, avatar)
925 821
926 def _chatStateReceivedCb(self, from_jid_s, state): 822 # def _chatStateReceivedCb(self, from_jid_s, state):
927 """Callback when a new chat state is received. 823 # """Callback when a new chat state is received.
928 @param from_jid_s: JID of the contact who sent his state, or '@ALL@' 824 # @param from_jid_s: JID of the contact who sent his state, or '@ALL@'
929 @param state: new state (string) 825 # @param state: new state (string)
930 """ 826 # """
931 if from_jid_s == '@ALL@': 827 # if from_jid_s == '@ALL@':
932 for lib_wid in self.libervia_widgets: 828 # for lib_wid in self.libervia_widgets:
933 if isinstance(lib_wid, panels.ChatPanel): 829 # if isinstance(lib_wid, panels.ChatPanel):
934 lib_wid.setState(state, nick=C.ALL_OCCUPANTS) 830 # lib_wid.setState(state, nick=C.ALL_OCCUPANTS)
935 return 831 # return
936 from_jid = jid.JID(from_jid_s) 832 # from_jid = jid.JID(from_jid_s)
937 lib_wid = self.getLiberviaWidget(panels.ChatPanel, {'item': from_jid}, ignoreOtherTabs=False) 833 # lib_wid = self.getLiberviaWidget(panels.ChatPanel, {'item': from_jid}, ignoreOtherTabs=False)
938 lib_wid.setState(state, nick=from_jid.resource) 834 # lib_wid.setState(state, nick=from_jid.resource)
939 835
940 def _askConfirmation(self, confirmation_id, confirmation_type, data): 836 def _askConfirmation(self, confirmation_id, confirmation_type, data):
941 answer_data = {} 837 answer_data = {}
942 838
943 def confirm_cb(result): 839 def confirm_cb(result):
972 def sendError(self, errorData): 868 def sendError(self, errorData):
973 dialog.InfoDialog("Error while sending message", 869 dialog.InfoDialog("Error while sending message",
974 "Your message can't be sent", Width="400px").center() 870 "Your message can't be sent", Width="400px").center()
975 log.error("sendError: %s" % str(errorData)) 871 log.error("sendError: %s" % str(errorData))
976 872
977 def send(self, targets, text, extra={}): 873 # FIXME: this method is fat too complicated and depend of widget type
978 """Send a message to any target type. 874 # must be refactored and moved to each widget instead
979 @param targets: list of tuples (type, entities, addr) with: 875 # def send(self, targets, text, extra={}):
980 - type in ("PUBLIC", "GROUP", "COMMENT", "STATUS" , "groupchat" , "chat") 876 # """Send a message to any target type.
981 - entities could be a JID, a list groups, a node hash... depending the target 877 # @param targets: list of tuples (type, entities, addr) with:
982 - addr in ("To", "Cc", "Bcc") - ignore case 878 # - type in ("PUBLIC", "GROUP", "COMMENT", "STATUS" , "groupchat" , "chat")
983 @param text: the message content 879 # - entities could be a JID, a list groups, a node hash... depending the target
984 @param extra: options 880 # - addr in ("To", "Cc", "Bcc") - ignore case
985 """ 881 # @param text: the message content
986 # FIXME: too many magic strings, we should use constants instead 882 # @param extra: options
987 addresses = [] 883 # """
988 for target in targets: 884 # # FIXME: too many magic strings, we should use constants instead
989 type_, entities, addr = target[0], target[1], 'to' if len(target) < 3 else target[2].lower() 885 # addresses = []
990 if type_ in ("PUBLIC", "GROUP"): 886 # for target in targets:
991 self.bridge.call("sendMblog", None, type_, entities if type_ == "GROUP" else None, text, extra) 887 # type_, entities, addr = target[0], target[1], 'to' if len(target) < 3 else target[2].lower()
992 elif type_ == "COMMENT": 888 # if type_ in ("PUBLIC", "GROUP"):
993 self.bridge.call("sendMblogComment", None, entities, text, extra) 889 # self.bridge.call("sendMblog", None, type_, entities if type_ == "GROUP" else None, text, extra)
994 elif type_ == "STATUS": 890 # elif type_ == "COMMENT":
995 assert(isinstance(self.status_panel, panels.PresenceStatusPanel)) 891 # self.bridge.call("sendMblogComment", None, entities, text, extra)
996 self.bridge.call('setStatus', None, self.status_panel.presence, text) # pylint: disable=E1103 892 # elif type_ == "STATUS":
997 elif type_ in ("groupchat", "chat"): 893 # assert(isinstance(self.status_panel, panels.PresenceStatusPanel))
998 addresses.append((addr, entities)) 894 # self.bridge.call('setStatus', None, self.status_panel.presence, text) # pylint: disable=E1103
999 else: 895 # elif type_ in ("groupchat", "chat"):
1000 log.error("Unknown target type") 896 # addresses.append((addr, entities))
1001 if addresses: 897 # else:
1002 if len(addresses) == 1 and addresses[0][0] == 'to': 898 # log.error("Unknown target type")
1003 to_jid_s = addresses[0][1] 899 # if addresses:
1004 for plugin in self.plugins.values(): 900 # if len(addresses) == 1 and addresses[0][0] == 'to':
1005 if hasattr(plugin, 'sendMessageTrigger'): 901 # to_jid_s = addresses[0][1]
1006 if not plugin.sendMessageTrigger(jid.JID(to_jid_s), text, type_, extra): 902 # for plugin in self.plugins.values():
1007 return # plugin returned False to interrupt the process 903 # if hasattr(plugin, 'sendMessageTrigger'):
1008 self.bridge.call('sendMessage', (None, self.sendError), to_jid_s, text, '', type_, extra) 904 # if not plugin.sendMessageTrigger(jid.JID(to_jid_s), text, type_, extra):
1009 else: 905 # return # plugin returned False to interrupt the process
1010 extra.update({'address': '\n'.join([('%s:%s' % entry) for entry in addresses])}) 906 # self.bridge.call('sendMessage', (None, self.sendError), to_jid_s, text, '', type_, extra)
1011 self.bridge.call('sendMessage', (None, self.sendError), self.whoami.domain, text, '', type_, extra) 907 # else:
908 # extra.update({'address': '\n'.join([('%s:%s' % entry) for entry in addresses])})
909 # self.bridge.call('sendMessage', (None, self.sendError), self.whoami.domain, text, '', type_, extra)
1012 910
1013 def showWarning(self, type_=None, msg=None): 911 def showWarning(self, type_=None, msg=None):
1014 """Display a popup information message, e.g. to notify the recipient of a message being composed. 912 """Display a popup information message, e.g. to notify the recipient of a message being composed.
1015 If type_ is None, a popup being currently displayed will be hidden. 913 If type_ is None, a popup being currently displayed will be hidden.
1016 @type_: a type determining the CSS style to be applied (see WarningPopup.showWarning) 914 @type_: a type determining the CSS style to be applied (see WarningPopup.showWarning)
1022 920
1023 921
1024 if __name__ == '__main__': 922 if __name__ == '__main__':
1025 app = SatWebFrontend() 923 app = SatWebFrontend()
1026 app.onModuleLoad() 924 app.onModuleLoad()
1027 pyjd.run()