backend, frontends: message refactoring (huge commit):

/!\ several features are temporarily disabled, like notifications in frontends

next step in refactoring, with the following changes:
    - jp: updated jp message to follow changes in backend/bridge
    - jp: added --lang, --subject, --subject_lang, and --type options to jp message + fixed unicode handling for jid
    - quick_frontend (QuickApp, QuickChat):
        - follow backend changes
        - refactored chat, message are now handled in OrderedDict and uid are kept so they can be updated
        - Message and Occupant classes handle metadata, so frontend just have to display them
    - Primitivus (Chat):
        - follow backend/QuickFrontend changes
        - info & standard messages are handled in the same MessageWidget class
        - improved/simplified handling of messages, removed update() method
        - user joined/left messages are merged when next to each other
        - a separator is shown when message is received while widget is out of focus, so user can quickly see the new messages
        - affiliation/role are shown (in a basic way for now) in occupants panel
        - removed "/me" messages handling, as it will be done by a backend plugin
        - message language is displayed when available (only one language per message for now)
        - fixed :history and :search commands
    - core (constants): new constants for messages type, XML namespace, entity type
    - core: *Message methods renamed to follow new code sytle (e.g. sendMessageToBridge => messageSendToBridge)
    - core (messages handling): fixed handling of language
    - core (messages handling): mes_data['from'] and ['to'] are now jid.JID
    - core (core.xmpp): reorganised message methods, added getNick() method to client.roster
    - plugin text commands: fixed plugin and adapted to new messages behaviour. client is now used in arguments instead of profile
    - plugins: added information for cancellation reason in CancelError calls
    - plugin XEP-0045: various improvments, but this plugin still need work:
        - trigger is used to avoid message already handled by the plugin to be handled a second time
        - changed the way to handle history, the last message from DB is checked and we request only messages since this one, in seconds (thanks Poezio folks :))
        - subject reception is waited before sending the roomJoined signal, this way we are sure that everything including history is ready
        - cmd_* method now follow the new convention with client instead of profile
        - roomUserJoined and roomUserLeft messages are removed, the events are now handled with info message with a "ROOM_USER_JOINED" info subtype
    - probably other forgotten stuffs :p
This commit is contained in:
Goffi 2016-06-20 18:41:53 +02:00
commit a7de473107

View file

@ -122,13 +122,6 @@ class ProfileManager(object):
#Now we open the MUC window where we already are:
for room_args in rooms_args:
self.host.roomJoinedHandler(*room_args, profile=self.profile)
self.bridge.getRoomsSubjects(self.profile, callback=self._plug_profile_gotRoomsSubjects)
def _plug_profile_gotRoomsSubjects(self, subjects_args):
for subject_args in subjects_args:
self.host.roomNewSubjectHandler(*subject_args, profile=self.profile)
#Presence must be requested after rooms are filled
self.host.bridge.getPresenceStatuses(self.profile, callback=self._plug_profile_gotPresences)
@ -263,8 +256,6 @@ class QuickApp(object):
self.registerSignal("actionResultExt", self.actionResultHandler)
self.registerSignal("roomJoined", iface="plugin")
self.registerSignal("roomLeft", iface="plugin")
self.registerSignal("roomUserJoined", iface="plugin")
self.registerSignal("roomUserLeft", iface="plugin")
self.registerSignal("roomUserChangedNick", iface="plugin")
self.registerSignal("roomNewSubject", iface="plugin")
self.registerSignal("chatStateReceived", iface="plugin")
@ -490,11 +481,8 @@ class QuickApp(object):
from_me = from_jid.bare == self.profiles[profile].whoami.bare
target = to_jid if from_me else from_jid
chat_type = C.CHAT_GROUP if type_ == C.MESS_TYPE_GROUPCHAT else C.CHAT_ONE2ONE
contact_list = self.contact_lists[profile]
chat_widget = self.widgets.getOrCreateWidget(quick_chat.QuickChat, target, type_=chat_type, on_new_widget=None, profile=profile)
chat_widget = self.widgets.getOrCreateWidget(quick_chat.QuickChat, target, type_=C.CHAT_ONE2ONE, on_new_widget=None, profile=profile)
self.current_action_ids = set() # FIXME: to be removed
self.current_action_ids_cb = {} # FIXME: to be removed
@ -560,14 +548,14 @@ class QuickApp(object):
self.callListeners('presence', entity, show, priority, statuses, profile=profile)
def roomJoinedHandler(self, room_jid_s, room_nicks, user_nick, profile):
def roomJoinedHandler(self, room_jid_s, occupants, user_nick, subject, profile):
"""Called when a MUC room is joined"""
log.debug(u"Room [%(room_jid)s] joined by %(profile)s, users presents:%(users)s" % {'room_jid': room_jid_s, 'profile': profile, 'users': room_nicks})
log.debug(u"Room [{room_jid}] joined by {profile}, users presents:{users}".format(room_jid=room_jid_s, profile=profile, users=occupants.keys()))
room_jid = jid.JID(room_jid_s)
chat_widget = self.widgets.getOrCreateWidget(quick_chat.QuickChat, room_jid, type_=C.CHAT_GROUP, profile=profile)
chat_widget = self.widgets.getOrCreateWidget(quick_chat.QuickChat, room_jid, type_=C.CHAT_GROUP, occupants=occupants, subject=subject, profile=profile)
chat_widget.setUserNick(unicode(user_nick))
self.contact_lists[profile].setSpecial(room_jid, C.CONTACT_SPECIAL_GROUP)
chat_widget.update()
# chat_widget.update()
def roomLeftHandler(self, room_jid_s, profile):
"""Called when a MUC room is left"""
@ -578,20 +566,6 @@ class QuickApp(object):
self.widgets.deleteWidget(chat_widget)
self.contact_lists[profile].removeContact(room_jid)
def roomUserJoinedHandler(self, room_jid_s, user_nick, user_data, profile):
"""Called when an user joined a MUC room"""
room_jid = jid.JID(room_jid_s)
chat_widget = self.widgets.getOrCreateWidget(quick_chat.QuickChat, room_jid, type_=C.CHAT_GROUP, profile=profile)
chat_widget.addUser(user_nick)
log.debug(u"user [%(user_nick)s] joined room [%(room_jid)s]" % {'user_nick': user_nick, 'room_jid': room_jid})
def roomUserLeftHandler(self, room_jid_s, user_nick, user_data, profile):
"""Called when an user joined a MUC room"""
room_jid = jid.JID(room_jid_s)
chat_widget = self.widgets.getOrCreateWidget(quick_chat.QuickChat, room_jid, type_=C.CHAT_GROUP, profile=profile)
chat_widget.removeUser(user_nick)
log.debug(u"user [%(user_nick)s] left room [%(room_jid)s]" % {'user_nick': user_nick, 'room_jid': room_jid})
def roomUserChangedNickHandler(self, room_jid_s, old_nick, new_nick, profile):
"""Called when an user joined a MUC room"""
room_jid = jid.JID(room_jid_s)
@ -613,20 +587,20 @@ class QuickApp(object):
@param state (unicode): new state
@param profile (unicode): current profile
"""
log.debug(_(u"Received new chat state {} from {} [{}]").format(state, from_jid_s, profile))
from_jid = jid.JID(from_jid_s) if from_jid_s != C.ENTITY_ALL else C.ENTITY_ALL
contact_list = self.contact_lists[profile]
for widget in self.widgets.getWidgets(quick_chat.QuickChat):
if profile != widget.profile:
continue
to_display = C.USER_CHAT_STATES[state] if (state and widget.type == C.CHAT_GROUP) else state
if widget.type == C.CHAT_GROUP and from_jid_s == C.ENTITY_ALL:
for occupant in [jid.newResource(widget.target, nick) for nick in widget.occupants]:
contact_list.setCache(occupant, 'chat_state', to_display)
widget.update(occupant)
elif from_jid.bare == widget.target.bare: # roster contact or MUC occupant
contact_list.setCache(from_jid, 'chat_state', to_display)
widget.update(from_jid)
# log.debug(_(u"Received new chat state {} from {} [{}]").format(state, from_jid_s, profile))
# from_jid = jid.JID(from_jid_s) if from_jid_s != C.ENTITY_ALL else C.ENTITY_ALL
# contact_list = self.contact_lists[profile]
# for widget in self.widgets.getWidgets(quick_chat.QuickChat):
# if profile != widget.profile:
# continue
# to_display = C.USER_CHAT_STATES[state] if (state and widget.type == C.CHAT_GROUP) else state
# if widget.type == C.CHAT_GROUP and from_jid_s == C.ENTITY_ALL:
# for occupant in [jid.newResource(widget.target, nick) for nick in widget.occupants]:
# contact_list.setCache(occupant, 'chat_state', to_display)
# widget.update(occupant)
# elif from_jid.bare == widget.target.bare: # roster contact or MUC occupant
# contact_list.setCache(from_jid, 'chat_state', to_display)
# widget.update(from_jid)
def psEventHandler(self, category, service_s, node, event_type, data, profile):
"""Called when a PubSub event is received.