# HG changeset patch # User souliane # Date 1413997435 -7200 # Node ID 0a06cf833f5acfe9abc2abb25ab3649ac59bd391 # Parent 4c6c61696ba09319e052376b0797861e4bad5694 browser_side: various improvements, especially for MUC diff -r 4c6c61696ba0 -r 0a06cf833f5a setup.py --- a/setup.py Wed Oct 22 14:19:25 2014 +0200 +++ b/setup.py Wed Oct 22 19:03:55 2014 +0200 @@ -119,7 +119,7 @@ os.symlink(os.path.dirname(sat.__file__), os.path.join(tmp_dir,"sat")) # FIXME: only work on unixes os.symlink(os.path.dirname(sat_frontends.__file__), os.path.join(tmp_dir,"sat_frontends")) # FIXME: only work on unixes os.symlink(os.path.dirname(libervia.__file__), os.path.join(tmp_dir,"libervia")) # FIXME: only work on unixes - result = subprocess.call(['pyjsbuild', 'libervia_main', '--no-compile-inplace', '-I', tmp_dir, '-o', self.pyjamas_output_dir]) + result = subprocess.call(['pyjsbuild', 'libervia_main', '-d', '--no-compile-inplace', '-I', tmp_dir, '-o', self.pyjamas_output_dir]) shutil.rmtree(tmp_dir) os.chdir(cwd) return result diff -r 4c6c61696ba0 -r 0a06cf833f5a src/browser/libervia_main.py --- a/src/browser/libervia_main.py Wed Oct 22 14:19:25 2014 +0200 +++ b/src/browser/libervia_main.py Wed Oct 22 19:03:55 2014 +0200 @@ -722,6 +722,44 @@ lib_wid.refresh() return lib_wid + def getRoomWidget(self, target): + """Get the MUC widget for the given target. + + @param target (jid.JID): BARE jid of the MUC + @return: panels.ChatPanel instance or None + """ + entity = {'item': target, 'type_': 'group'} + 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... + return self.getLiberviaWidget(panels.ChatPanel, entity, ignoreOtherTabs=False) + return None + + def getOrCreateRoomWidget(self, target): + """Get the MUC widget for the given target, create it if necessary. + + @param target (jid.JID): BARE jid of the MUC + @return: panels.ChatPanel instance + """ + lib_wid = self.getRoomWidget(target) + if lib_wid: + return lib_wid + + # XXX: target.node.startwith(...) raises an error "startswith is not a function" + # This happens when node a is property defined in the JID class + # FIXME: pyjamas doesn't handle the properties well + node = target.node + + # XXX: it's not really beautiful, but it works :) + if node.startswith('sat_tarot_'): + tab_name = "Tarot" + elif node.startswith('sat_radiocol_'): + tab_name = "Radio collective" + else: + tab_name = target.node + + self.room_list.append(target) + entity = {'item': target, 'type_': 'group'} + return self.getOrCreateLiberviaWidget(panels.ChatPanel, entity, new_tab=tab_name) + def _newMessageCb(self, from_jid_s, msg, msg_type, to_jid_s, extra): from_jid = jid.JID(from_jid_s) to_jid = jid.JID(to_jid_s) @@ -766,8 +804,9 @@ if statuses: self.status_panel.setStatus(statuses.values()[0]) # pylint: disable=E1103 else: - if entity_jid.bare in self.room_list: - wid = self.getLiberviaWidget(panels.ChatPanel, {'item': entity_jid, 'type_': 'group'}, ignoreOtherTabs=False) + bare_jid = entity_jid.bareJID() + 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... + wid = self.getRoomWidget(bare_jid) else: wid = self.contact_panel if show == 'unavailable': # XXX: save some resources as for now we only need 'unavailable' @@ -777,75 +816,56 @@ if wid: wid.setConnected(entity_jid.bare, entity_jid.resource, show, priority, statuses) - def _roomJoinedCb(self, room_jid, room_nicks, user_nick): - _target = jid.JID(room_jid) - - # XXX: _target.node.startwith(...) raises an error "startswith is not a function" - # This happens when node a is property defined in the JID class - # FIXME: pyjamas doesn't handle the properties well - node = _target.node - - if _target not in self.room_list: - self.room_list.append(_target) - - # XXX: it's not really beautiful, but it works :) - if node.startswith('sat_tarot_'): - tab_name = "Tarot" - elif node.startswith('sat_radiocol_'): - tab_name = "Radio collective" - else: - tab_name = _target.node - - chat_panel = self.getOrCreateLiberviaWidget(panels.ChatPanel, {'item': _target, 'type_': 'group'}, new_tab=tab_name) + def _roomJoinedCb(self, room_jid_s, room_nicks, user_nick): + chat_panel = self.getOrCreateRoomWidget(jid.JID(room_jid_s)) chat_panel.setUserNick(user_nick) chat_panel.setPresents(room_nicks) - chat_panel.historyPrint() chat_panel.refresh() - def _roomLeftCb(self, room_jid, room_nicks, user_nick): - # FIXME: room_list contains jid.JID instances so why MUST we do - # 'remove(room_jid)' and not 'remove(jid.JID(room_jid))' ????!! - # This looks like a pyjamas bug --> check/report + def _roomLeftCb(self, room_jid_s, room_nicks, user_nick): try: - self.room_list.remove(room_jid) + del self.room_list[room_jid_s] except KeyError: - pass + try: # as JID is a string-based class, we don't know what will please Pyjamas... + del self.room_list[jid.JID(room_jid_s)] + except KeyError: + pass def _roomUserJoinedCb(self, room_jid_s, user_nick, user_data): - for lib_wid in self.libervia_widgets: - if isinstance(lib_wid, panels.ChatPanel) and lib_wid.type == 'group' and lib_wid.target.bare == room_jid_s: - lib_wid.userJoined(user_nick, user_data) + lib_wid = self.getOrCreateRoomWidget(jid.JID(room_jid_s)) + if lib_wid: + lib_wid.userJoined(user_nick, user_data) def _roomUserLeftCb(self, room_jid_s, user_nick, user_data): - for lib_wid in self.libervia_widgets: - if isinstance(lib_wid, panels.ChatPanel) and lib_wid.type == 'group' and lib_wid.target.bare == room_jid_s: - lib_wid.userLeft(user_nick, user_data) + lib_wid = self.getRoomWidget(jid.JID(room_jid_s)) + if lib_wid: + lib_wid.userLeft(user_nick, user_data) def _roomUserChangedNickCb(self, room_jid_s, old_nick, new_nick): """Called when an user joined a MUC room""" - for lib_wid in self.libervia_widgets: - if isinstance(lib_wid, panels.ChatPanel) and lib_wid.type == 'group' and lib_wid.target.bare == room_jid_s: - lib_wid.changeUserNick(old_nick, new_nick) + lib_wid = self.getRoomWidget(jid.JID(room_jid_s)) + if lib_wid: + lib_wid.changeUserNick(old_nick, new_nick) def _tarotGameStartedCb(self, waiting, room_jid_s, referee, players): - for lib_wid in self.libervia_widgets: - if isinstance(lib_wid, panels.ChatPanel) and lib_wid.type == 'group' and lib_wid.target.bare == room_jid_s: - lib_wid.startGame("Tarot", waiting, referee, players) + lib_wid = self.getRoomWidget(jid.JID(room_jid_s)) + if lib_wid: + lib_wid.startGame("Tarot", waiting, referee, players) def _tarotGameGenericCb(self, event_name, room_jid_s, args): - for lib_wid in self.libervia_widgets: - if isinstance(lib_wid, panels.ChatPanel) and lib_wid.type == 'group' and lib_wid.target.bare == room_jid_s: - getattr(lib_wid.getGame("Tarot"), event_name)(*args) + lib_wid = self.getRoomWidget(jid.JID(room_jid_s)) + if lib_wid: + getattr(lib_wid.getGame("Tarot"), event_name)(*args) def _radioColStartedCb(self, waiting, room_jid_s, referee, players, queue_data): - for lib_wid in self.libervia_widgets: - if isinstance(lib_wid, panels.ChatPanel) and lib_wid.type == 'group' and lib_wid.target.bare == room_jid_s: - lib_wid.startGame("RadioCol", waiting, referee, players, queue_data) + lib_wid = self.getRoomWidget(jid.JID(room_jid_s)) + if lib_wid: + lib_wid.startGame("RadioCol", waiting, referee, players, queue_data) def _radioColGenericCb(self, event_name, room_jid_s, args): - for lib_wid in self.libervia_widgets: - if isinstance(lib_wid, panels.ChatPanel) and lib_wid.type == 'group' and lib_wid.target.bare == room_jid_s: - getattr(lib_wid.getGame("RadioCol"), event_name)(*args) + lib_wid = self.getRoomWidget(jid.JID(room_jid_s)) + if lib_wid: + getattr(lib_wid.getGame("RadioCol"), event_name)(*args) def _getPresenceStatusesCb(self, presence_data): for entity in presence_data: @@ -909,17 +929,13 @@ @param state: new state (string) """ if from_jid_s == '@ALL@': - target = '@ALL@' - nick = C.ALL_OCCUPANTS - else: - from_jid = jid.JID(from_jid_s) - target = from_jid.bare - nick = from_jid.resource - - for lib_wid in self.libervia_widgets: - if isinstance(lib_wid, panels.ChatPanel): - if target == '@ALL@' or lib_wid.matchEntity(target): - lib_wid.setState(state, nick=nick) + for lib_wid in self.libervia_widgets: + if isinstance(lib_wid, panels.ChatPanel): + lib_wid.setState(state, nick=C.ALL_OCCUPANTS) + return + from_jid = jid.JID(from_jid_s) + lib_wid = self.getLiberviaWidget(panels.ChatPanel, {'item': from_jid}, ignoreOtherTabs=False) + lib_wid.setState(state, nick=from_jid.resource) def _askConfirmation(self, confirmation_id, confirmation_type, data): answer_data = {} diff -r 4c6c61696ba0 -r 0a06cf833f5a src/browser/sat_browser/base_panels.py --- a/src/browser/sat_browser/base_panels.py Wed Oct 22 14:19:25 2014 +0200 +++ b/src/browser/sat_browser/base_panels.py Wed Oct 22 19:03:55 2014 +0200 @@ -113,6 +113,8 @@ self.setStyleName('occupantsList') def addOccupant(self, nick): + if nick in self.occupants_list: + return _occupant = Occupant(nick) self.occupants_list[nick] = _occupant self.add(_occupant) diff -r 4c6c61696ba0 -r 0a06cf833f5a src/browser/sat_browser/jid.py --- a/src/browser/sat_browser/jid.py Wed Oct 22 14:19:25 2014 +0200 +++ b/src/browser/sat_browser/jid.py Wed Oct 22 19:03:55 2014 +0200 @@ -113,3 +113,6 @@ def full(self): return str(self) + + def bareJID(self): + return JID(self.bare) diff -r 4c6c61696ba0 -r 0a06cf833f5a src/browser/sat_browser/panels.py --- a/src/browser/sat_browser/panels.py Wed Oct 22 14:19:25 2014 +0200 +++ b/src/browser/sat_browser/panels.py Wed Oct 22 19:03:55 2014 +0200 @@ -1133,6 +1133,7 @@ chat_area.setStyleName('chatArea') if type_ == 'group': self.occupants_list = base_panels.OccupantsList() + self.occupants_initialised = False chat_area.add(self.occupants_list) self.__body.add(chat_area) self.content = AbsolutePanel() @@ -1157,7 +1158,8 @@ _contact = item if isinstance(item, jid.JID) else jid.JID(item) host.contact_panel.setContactMessageWaiting(_contact.bare, False) _new_panel = ChatPanel(host, _contact, type_) # XXX: pyjamas doesn't seems to support creating with cls directly - _new_panel.historyPrint() + if type == 'one2one': + _new_panel.historyPrint() host.setSelected(_new_panel) _new_panel.refresh() return _new_panel @@ -1187,7 +1189,6 @@ def matchEntity(self, item, type_=None): """ @param entity: target jid as a string or jid.JID instance. - Could also be a couple with a type in the second element. @return: True if self matches the given entity """ if type_ is None: @@ -1234,13 +1235,16 @@ def setPresents(self, nicks): """Set the users presents in this room @param occupants: list of nicks (string)""" - self.occupants_list.clear() for nick in nicks: self.occupants_list.addOccupant(nick) + self.occupants_initialised = True def userJoined(self, nick, data): + if self.occupants_list.getOccupantBox(nick): + return # user is already displayed self.occupants_list.addOccupant(nick) - self.printInfo("=> %s has joined the room" % nick) + if self.occupants_initialised: + self.printInfo("=> %s has joined the room" % nick) def userLeft(self, nick, data): self.occupants_list.removeOccupant(nick) @@ -1333,7 +1337,7 @@ to set the state for a one2one conversation, or give a nickname or C.ALL_OCCUPANTS to set the state of a participant within a MUC. @param state: the new chat state - @param nick: None for one2one, the MUC user nick or ALL_OCCUPANTS + @param nick: ignored for one2one, otherwise the MUC user nick or C.ALL_OCCUPANTS """ if self.type == 'group': assert(nick) diff -r 4c6c61696ba0 -r 0a06cf833f5a src/browser/sat_browser/plugin_sec_otr.py --- a/src/browser/sat_browser/plugin_sec_otr.py Wed Oct 22 14:19:25 2014 +0200 +++ b/src/browser/sat_browser/plugin_sec_otr.py Wed Oct 22 19:03:55 2014 +0200 @@ -344,7 +344,7 @@ log.debug(u"getContextForUser [%s]" % other_jid) if not other_jid.resource: log.error("getContextForUser called with a bare jid") - running_sessions = [jid.userhostJID() for jid in self.contexts.keys() if self.contexts[jid].state == otr.context.STATE_ENCRYPTED] + running_sessions = [jid.bareJID() for jid in self.contexts.keys() if self.contexts[jid].state == otr.context.STATE_ENCRYPTED] if start or (other_jid in running_sessions): users_ml = DIALOG_USERS_ML.format(subject=D_("OTR issue in Libervia: getContextForUser called with a bare jid in an encrypted context")) text = RESOURCE_ISSUE.format(eol=DIALOG_EOL, jid=other_jid.full(), users_ml=users_ml)