# HG changeset patch # User Goffi # Date 1365366835 -7200 # Node ID aa76793da3530214be3c73e239f12905965ffe96 # Parent 0f5c2f799913ac5c59a1e74d29cc1396f27b889e server + browser: message warning level/sending refactoring: - widgets now manage themselves warning level - widgets now manage themselves text entered (if they are selectable, onTextEntered must be present) - Unibox now default to selected widget/status bar, except if a hook syntax is used (e.g. "@@: public microblog") - warning message is now GROUP (in blue with default theme) when sending a message to a MUC room (instead of green before) - "@.*: " syntaxes are now fully managed by browser, no more by server diff -r 0f5c2f799913 -r aa76793da353 browser_side/base_widget.py --- a/browser_side/base_widget.py Mon Mar 25 14:09:10 2013 +0100 +++ b/browser_side/base_widget.py Sun Apr 07 22:33:55 2013 +0200 @@ -284,6 +284,22 @@ self.addClickListener(self) self.__selectable = selectable + def getWarningData(self): + """ Return exposition warning level when this widget is selected and something is sent to it + This method should be overriden by children + @return: tuple (warning level type/HTML msg). Type can be one of: + - PUBLIC + - GROUP + - ONE2ONE + - MISC + - NONE + """ + if not self.__selectable: + print "ERROR: getWarningLevel must not be called for an unselectable widget" + raise Exception + # TODO: cleaner warning types (more general constants) + return ("NONE", None) + def setWidget(self, widget, scrollable=True): """Set the widget that will be in the body of the LiberviaWidget @param widget: widget to put in the body diff -r 0f5c2f799913 -r aa76793da353 browser_side/panels.py --- a/browser_side/panels.py Mon Mar 25 14:09:10 2013 +0100 +++ b/browser_side/panels.py Sun Apr 07 22:33:55 2013 +0200 @@ -87,21 +87,23 @@ def showWarning(self, target_data): - type, target = target_data - if type == "PUBLIC": - msg = "This message will be PUBLIC and everybody will be able to see it, even people you don't know" + target_hook, _type, msg = target_data + if _type == "NONE": + return + if not msg: + print "WARNING: no msg set uniBox warning" + return + if _type == "PUBLIC": style = "targetPublic" - elif type == "GROUP": - msg = "This message will be published for all the people of the group %s" % (target or '') + elif _type == "GROUP": style = "targetGroup" - elif type == "STATUS": + elif _type == "STATUS": msg = "This will be your new status message" style = "targetStatus" - elif type == "ONE2ONE": - msg = "This message will be sent to your contact %s" % target + elif _type == "ONE2ONE": style = "targetOne2One" else: - print "WARNING: undetermined target for this message" + print "ERROR: unknown message type" return contents = HTML(msg) @@ -115,7 +117,6 @@ left = 0 top = 0 #max(0, self.getAbsoluteTop() - contents.getOffsetHeight() - 2) self._popup.setPopupPosition(left, top) - self._popup.setPopupPosition(left, top) self._popup.show() def _timeCb(self, timer): @@ -125,30 +126,47 @@ self._popup = None def _getTarget(self, txt): - """Say who will receive the messsage - Return a tuple (target_type, target info)""" - type = None - target = None - if txt.startswith('@@: '): - type = "PUBLIC" + """ Say who will receive the messsage + @return: a tuple (selected, target_type, target info) with: + - target_hook: None if we use the selected widget, (msg, data) if we have a hook (e.g. "@@: " for a public blog), where msg is the parsed message (i.e. without the "hook key: "@@: bla" become ("bla", None)) + - target_type: one of PUBLIC, GROUP, ONE2ONE, STATUS, MISC + - msg: HTML message which will appear in the privacy warning banner """ + target = self._selected_cache + + def getSelectedOrStatus(): + if target: + _type, msg = target.getWarningData() + target_hook = None # we use the selected widget, not a hook + else: + _type, msg = "STATUS", "This will be your new status message" + target_hook = (txt, None) + return (target_hook, _type, msg) + + if not txt.startswith('@'): + target_hook, _type, msg = getSelectedOrStatus() + elif txt.startswith('@@: '): + _type = "PUBLIC" + msg = MicroblogPanel.warning_msg_public + target_hook = (txt[4:], None) elif txt.startswith('@'): - type = "GROUP" _end = txt.find(': ') if _end == -1: - type = "STATUS" + target_hook, _type, msg = getSelectedOrStatus() else: - target = txt[1:_end] #only one target group is managed for the moment - if not target in self.host.contact_panel.getGroups(): - target = None - elif self._selected_cache == None: - type = "STATUS" - elif isinstance(self._selected_cache, ChatPanel): - type = "ONE2ONE" - target = str(self._selected_cache.target) + group = txt[1:_end] #only one target group is managed for the moment + if not group or not group in self.host.contact_panel.getGroups(): + # the group doesn't exists, we ignore the key + group = None + target_hook, _type, msg = getSelectedOrStatus() + else: + _type = "GROUP" + msg = MicroblogPanel.warning_msg_group % group + target_hook = (txt[_end+2:], group) else: - print "Unknown selected host:",self._selected_cache - type = "UNKNOWN" - return (type, target) + print "ERROR: Unknown target" + target_hook, _type, msg = getSelectedOrStatus() + + return (target_hook, _type, msg) def onBrowserEvent(self, event): #XXX: woraroung a pyjamas bug: self.currentEvent is not set @@ -159,27 +177,31 @@ def onKeyPress(self, sender, keycode, modifiers): _txt = self.getText() + target = self._getTarget(_txt) if not self._popup: - self.showWarning(self._getTarget(_txt)) - else: - _target = self._getTarget(_txt) - if _target != self._popup.target_data: - self._timeCb(None) #we remove the popup - self.showWarning(_target) + self.showWarning(target) + elif target != self._popup.target_data: + self._timeCb(None) #we remove the popup + self.showWarning(target) self._timer.schedule(2000) #if keycode == KEY_ENTER and not self.visible: if keycode == KEY_ENTER: if _txt: - if _txt.startswith('@'): - self.host.bridge.call('sendMblog', None, self.getText()) - elif self._selected_cache == None: - self.host.bridge.call('setStatus', None, _txt) - elif isinstance(self._selected_cache, ChatPanel): - _chat = self._selected_cache - mess_type = "groupchat" if _chat.type=='group' else "chat" - self.host.bridge.call('sendMessage', None, str(_chat.target), _txt, '', mess_type) + target_hook, _type, msg = target + if target_hook: + parsed_txt, data = target_hook + if _type == "PUBLIC": + self.host.bridge.call("sendMblog", None, "PUBLIC", None, parsed_txt) + elif _type == "GROUP": + self.host.bridge.call("sendMblog", None, "GROUP", data, parsed_txt) + elif _type == "STATUS": + self.host.bridge.call('setStatus', None, parsed_txt) + else: + print "ERROR: Unknown target hook type" + else: #we send the message to the selected target + self._selected_cache.onTextEntered(_txt) self.setText('') self._timeCb(None) #we remove the popup sender.cancelKey() @@ -246,6 +268,8 @@ class MicroblogPanel(base_widget.LiberviaWidget): + warning_msg_public = "This message will be PUBLIC and everybody will be able to see it, even people you don't know" + warning_msg_group = "This message will be published for all the people of the group %s" def __init__(self, host, accepted_groups): """Panel used to show microblog @@ -281,6 +305,22 @@ host.bridge.call('getMassiveLastMblogs', _new_panel.massiveInsert, 'ALL', [], 10) return _new_panel + def getWarningData(self): + if not self.accepted_groups: + # we have a meta MicroblogPanel, we publish publicly + return ("PUBLIC", self.warning_msg_public) + else: + # we only accept one group at the moment + # FIXME: manage several groups + return ("GROUP", self.warning_msg_group % self.accepted_groups[0]) + + def onTextEntered(self, text): + if not self.accepted_groups: + self.host.bridge.call("sendMblog", None, "PUBLIC", None, text) + else: + # FIXME: manage several groups + self.host.bridge.call("sendMblog", None, "GROUP", self.accepted_groups[0], text) + def accept_all(self): return not self.accepted_groups #we accept every microblog only if we are not filtering by groups @@ -486,6 +526,19 @@ _new_panel.historyPrint() return _new_panel + def getWarningData(self): + if self.type not in ["one2one", "group"]: + raise Exception("Unmanaged type !") + if self.type == "one2one": + msg = "This message will be sent to your contact %s" % self.target + elif self.type == "group": + msg = "This message will be sent to all the participants of the multi-user room %s" % self.target + return ("ONE2ONE" if self.type == "one2one" else "GROUP", msg) + + def onTextEntered(self, text): + mess_type = "groupchat" if self.type=='group' else "chat" + self.host.bridge.call('sendMessage', None, str(self.target), text, '', mess_type) + def onQuit(self): base_widget.LiberviaWidget.onQuit(self) if self.type == 'group': diff -r 0f5c2f799913 -r aa76793da353 libervia.tac --- a/libervia.tac Mon Mar 25 14:09:10 2013 +0100 +++ b/libervia.tac Sun Apr 07 22:33:55 2013 +0200 @@ -185,28 +185,28 @@ self.sat_host.bridge.setPresence('', '', 0, {'':status}, profile) - def jsonrpc_sendMessage(self, to_jid, msg, subject, type): + def jsonrpc_sendMessage(self, to_jid, msg, subject, _type): """send message""" profile = ISATSession(self.session).profile - return self.sat_host.bridge.sendMessage(to_jid, msg, subject, type, profile) + return self.sat_host.bridge.sendMessage(to_jid, msg, subject, _type, profile) - def jsonrpc_sendMblog(self, raw_text): - """Parse raw_text of the microblog box, and send message consequently""" + def jsonrpc_sendMblog(self, _type, dest, text): + """ Send microblog message + @param _type: one of "PUBLIC", "GROUP" + @param dest: destinees (list of groups, ignored for "PUBLIC") + @param text: microblog's text + """ profile = ISATSession(self.session).profile - match = re.match(r'@(.+?): *(.*$)', raw_text) - if match: - recip = match.group(1) - text = match.group(2) - #if recip == '@' and text: - # #This text if for the public microblog - # return self.sat_host.bridge.sendPersonalEvent("MICROBLOG", {'content':text}, profile) - if recip == '@' and text: + if _type in ("PUBLIC", "GROUP") and text: + if _type == "PUBLIC": #This text if for the public microblog print "sending public blog" return self.sat_host.bridge.sendGroupBlog("PUBLIC", [], text, profile) else: print "sending group blog" - return self.sat_host.bridge.sendGroupBlog("GROUP", [recip], text, profile) + return self.sat_host.bridge.sendGroupBlog("GROUP", [dest], text, profile) + else: + raise Exception("Invalid data") def jsonrpc_getLastMblogs(self, publisher_jid, max_item): """Get last microblogs posted by a contact