Mercurial > libervia-web
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() |