[Geobert] Don't send bot JEP85 and JEP22 when only JEP22 is supported by contact. Fixes #1317
This commit is contained in:
parent
554b508e9f
commit
1c13fcd648
|
@ -337,14 +337,15 @@ class ChatControlBase(MessageControl):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def send_message(self, message, keyID = '', type = 'chat', chatstate = None, msg_id = None):
|
def send_message(self, message, keyID = '', type = 'chat', chatstate = None, msg_id = None,
|
||||||
|
composing_jep = None):
|
||||||
'''Send the given message to the active tab'''
|
'''Send the given message to the active tab'''
|
||||||
if not message or message == '\n':
|
if not message or message == '\n':
|
||||||
return
|
return
|
||||||
|
|
||||||
if not self._process_command(message):
|
if not self._process_command(message):
|
||||||
MessageControl.send_message(self, message, keyID, type = type,
|
MessageControl.send_message(self, message, keyID, type = type,
|
||||||
chatstate = chatstate, msg_id = msg_id)
|
chatstate = chatstate, msg_id = msg_id, composing_jep = composing_jep)
|
||||||
# Record message history
|
# Record message history
|
||||||
self.save_sent_message(message)
|
self.save_sent_message(message)
|
||||||
|
|
||||||
|
@ -954,7 +955,7 @@ class ChatControl(ChatControlBase):
|
||||||
chatstates_on = gajim.config.get('chat_state_notifications') != 'disabled'
|
chatstates_on = gajim.config.get('chat_state_notifications') != 'disabled'
|
||||||
chatstate_to_send = None
|
chatstate_to_send = None
|
||||||
if chatstates_on and contact is not None:
|
if chatstates_on and contact is not None:
|
||||||
if contact.our_chatstate is None:
|
if contact.composing_jep is None:
|
||||||
# no info about peer
|
# no info about peer
|
||||||
# send active to discover chat state capabilities
|
# send active to discover chat state capabilities
|
||||||
# this is here (and not in send_chatstate)
|
# this is here (and not in send_chatstate)
|
||||||
|
@ -964,7 +965,7 @@ class ChatControl(ChatControlBase):
|
||||||
contact.our_chatstate = 'ask' # pseudo state
|
contact.our_chatstate = 'ask' # pseudo state
|
||||||
# if peer supports jep85 and we are not 'ask', send 'active'
|
# if peer supports jep85 and we are not 'ask', send 'active'
|
||||||
# NOTE: first active and 'ask' is set in gajim.py
|
# NOTE: first active and 'ask' is set in gajim.py
|
||||||
elif contact.our_chatstate not in (False, 'ask'):
|
elif contact.composing_jep is not False:
|
||||||
#send active chatstate on every message (as JEP says)
|
#send active chatstate on every message (as JEP says)
|
||||||
chatstate_to_send = 'active'
|
chatstate_to_send = 'active'
|
||||||
contact.our_chatstate = 'active'
|
contact.our_chatstate = 'active'
|
||||||
|
@ -974,7 +975,8 @@ class ChatControl(ChatControlBase):
|
||||||
self._schedule_activity_timers()
|
self._schedule_activity_timers()
|
||||||
|
|
||||||
ChatControlBase.send_message(self, message, keyID, type = 'chat',
|
ChatControlBase.send_message(self, message, keyID, type = 'chat',
|
||||||
chatstate = chatstate_to_send, msg_id = contact.msg_id)
|
chatstate = chatstate_to_send,
|
||||||
|
composing_jep = contact.composing_jep)
|
||||||
self.print_conversation(message, self.contact.jid, encrypted = encrypted)
|
self.print_conversation(message, self.contact.jid, encrypted = encrypted)
|
||||||
|
|
||||||
def check_for_possible_paused_chatstate(self, arg):
|
def check_for_possible_paused_chatstate(self, arg):
|
||||||
|
@ -1183,20 +1185,17 @@ class ChatControl(ChatControlBase):
|
||||||
|
|
||||||
if contact is None:
|
if contact is None:
|
||||||
contact = self.parent_win.get_active_contact()
|
contact = self.parent_win.get_active_contact()
|
||||||
jid = contact.jid
|
if contact is None:
|
||||||
else:
|
# contact was from pm in MUC, and left the room so contact is None
|
||||||
jid = contact.jid
|
# so we cannot send chatstate anymore
|
||||||
|
return
|
||||||
if contact is None:
|
jid = contact.jid
|
||||||
# contact was from pm in MUC, and left the room so contact is None
|
|
||||||
# so we cannot send chatstate anymore
|
|
||||||
return
|
|
||||||
|
|
||||||
# Don't send chatstates to offline contacts
|
# Don't send chatstates to offline contacts
|
||||||
if contact.show == 'offline':
|
if contact.show == 'offline':
|
||||||
return
|
return
|
||||||
|
|
||||||
if contact.our_chatstate is False: # jid cannot do jep85
|
if contact.composing_jep is False: # jid cannot do jep85 nor jep22
|
||||||
return
|
return
|
||||||
|
|
||||||
# if the new state we wanna send (state) equals
|
# if the new state we wanna send (state) equals
|
||||||
|
@ -1204,7 +1203,7 @@ class ChatControl(ChatControlBase):
|
||||||
if contact.our_chatstate == state:
|
if contact.our_chatstate == state:
|
||||||
return
|
return
|
||||||
|
|
||||||
if contact.our_chatstate is None:
|
if contact.composing_jep is None:
|
||||||
# we don't know anything about jid, so return
|
# we don't know anything about jid, so return
|
||||||
# NOTE:
|
# NOTE:
|
||||||
# send 'active', set current state to 'ask' and return is done
|
# send 'active', set current state to 'ask' and return is done
|
||||||
|
@ -1216,6 +1215,15 @@ class ChatControl(ChatControlBase):
|
||||||
if contact.our_chatstate == 'ask':
|
if contact.our_chatstate == 'ask':
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# in JEP22, when we already sent stop composing
|
||||||
|
# notification on paused, don't resend it
|
||||||
|
if contact.composing_jep == 'JEP-0022' and \
|
||||||
|
contact.our_chatstate in ('paused', 'active', 'inactive') and \
|
||||||
|
state is not 'composing': # not composing == in (active, inactive, gone)
|
||||||
|
contact.our_chatstate = 'active'
|
||||||
|
self.reset_kbd_mouse_timeout_vars()
|
||||||
|
return
|
||||||
|
|
||||||
# prevent going paused if we we were not composing (JEP violation)
|
# prevent going paused if we we were not composing (JEP violation)
|
||||||
if state == 'paused' and not contact.our_chatstate == 'composing':
|
if state == 'paused' and not contact.our_chatstate == 'composing':
|
||||||
MessageControl.send_message(self, None, chatstate = 'active') # go active before
|
MessageControl.send_message(self, None, chatstate = 'active') # go active before
|
||||||
|
@ -1228,7 +1236,8 @@ class ChatControl(ChatControlBase):
|
||||||
contact.our_chatstate = 'active'
|
contact.our_chatstate = 'active'
|
||||||
self.reset_kbd_mouse_timeout_vars()
|
self.reset_kbd_mouse_timeout_vars()
|
||||||
|
|
||||||
MessageControl.send_message(self, None, chatstate = state)
|
MessageControl.send_message(self, None, chatstate = state, msg_id = contact.msg_id,
|
||||||
|
composing_jep = contact.composing_jep)
|
||||||
contact.our_chatstate = state
|
contact.our_chatstate = state
|
||||||
if contact.our_chatstate == 'active':
|
if contact.our_chatstate == 'active':
|
||||||
self.reset_kbd_mouse_timeout_vars()
|
self.reset_kbd_mouse_timeout_vars()
|
||||||
|
|
|
@ -398,6 +398,7 @@ class Connection:
|
||||||
invite = None
|
invite = None
|
||||||
delayed = msg.getTag('x', namespace = common.xmpp.NS_DELAY) != None
|
delayed = msg.getTag('x', namespace = common.xmpp.NS_DELAY) != None
|
||||||
msg_id = None
|
msg_id = None
|
||||||
|
composing_jep = None
|
||||||
# FIXME: Msn transport (CMSN1.2.1 and PyMSN0.10) do NOT RECOMMENDED
|
# FIXME: Msn transport (CMSN1.2.1 and PyMSN0.10) do NOT RECOMMENDED
|
||||||
# invitation
|
# invitation
|
||||||
# stanza (MUC JEP) remove in 2007, as we do not do NOT RECOMMENDED
|
# stanza (MUC JEP) remove in 2007, as we do not do NOT RECOMMENDED
|
||||||
|
@ -409,16 +410,19 @@ class Connection:
|
||||||
return
|
return
|
||||||
# chatstates - look for chatstate tags in a message if not delayed
|
# chatstates - look for chatstate tags in a message if not delayed
|
||||||
if not delayed:
|
if not delayed:
|
||||||
|
composing_jep = False
|
||||||
children = msg.getChildren()
|
children = msg.getChildren()
|
||||||
for child in children:
|
for child in children:
|
||||||
if child.getNamespace() == 'http://jabber.org/protocol/chatstates':
|
if child.getNamespace() == 'http://jabber.org/protocol/chatstates':
|
||||||
chatstate = child.getName()
|
chatstate = child.getName()
|
||||||
|
composing_jep = 'JEP-0085'
|
||||||
break
|
break
|
||||||
# No JEP-0085 support, fallback to JEP-0022
|
# No JEP-0085 support, fallback to JEP-0022
|
||||||
if not chatstate:
|
if not chatstate:
|
||||||
chatstate_child = msg.getTag('x', namespace = common.xmpp.NS_EVENT)
|
chatstate_child = msg.getTag('x', namespace = common.xmpp.NS_EVENT)
|
||||||
if chatstate_child:
|
if chatstate_child:
|
||||||
chatstate = 'active'
|
chatstate = 'active'
|
||||||
|
composing_jep = 'JEP-0022'
|
||||||
if not msgtxt and chatstate_child.getTag('composing'):
|
if not msgtxt and chatstate_child.getTag('composing'):
|
||||||
chatstate = 'composing'
|
chatstate = 'composing'
|
||||||
|
|
||||||
|
@ -456,7 +460,7 @@ class Connection:
|
||||||
no_log_for:
|
no_log_for:
|
||||||
gajim.logger.write('chat_msg_recv', frm, msgtxt, tim = tim, subject = subject)
|
gajim.logger.write('chat_msg_recv', frm, msgtxt, tim = tim, subject = subject)
|
||||||
self.dispatch('MSG', (frm, msgtxt, tim, encrypted, mtype, subject,
|
self.dispatch('MSG', (frm, msgtxt, tim, encrypted, mtype, subject,
|
||||||
chatstate, msg_id))
|
chatstate, msg_id, composing_jep))
|
||||||
else: # it's single message
|
else: # it's single message
|
||||||
if self.name not in no_log_for and jid not in no_log_for:
|
if self.name not in no_log_for and jid not in no_log_for:
|
||||||
gajim.logger.write('single_msg_recv', frm, msgtxt, tim = tim, subject = subject)
|
gajim.logger.write('single_msg_recv', frm, msgtxt, tim = tim, subject = subject)
|
||||||
|
@ -469,7 +473,7 @@ class Connection:
|
||||||
self.dispatch('GC_INVITATION',(frm, jid_from, reason, password))
|
self.dispatch('GC_INVITATION',(frm, jid_from, reason, password))
|
||||||
else:
|
else:
|
||||||
self.dispatch('MSG', (frm, msgtxt, tim, encrypted, 'normal',
|
self.dispatch('MSG', (frm, msgtxt, tim, encrypted, 'normal',
|
||||||
subject, chatstate, msg_id))
|
subject, chatstate, msg_id, composing_jep))
|
||||||
# END messageCB
|
# END messageCB
|
||||||
|
|
||||||
def _presenceCB(self, con, prs):
|
def _presenceCB(self, con, prs):
|
||||||
|
@ -2112,7 +2116,8 @@ class Connection:
|
||||||
msg_iq = common.xmpp.Message(to = jid, body = msg, subject = subject)
|
msg_iq = common.xmpp.Message(to = jid, body = msg, subject = subject)
|
||||||
self.connection.send(msg_iq)
|
self.connection.send(msg_iq)
|
||||||
|
|
||||||
def send_message(self, jid, msg, keyID, type = 'chat', subject='', chatstate = None, msg_id = None):
|
def send_message(self, jid, msg, keyID, type = 'chat', subject='',
|
||||||
|
chatstate = None, msg_id = None, composing_jep = None):
|
||||||
if not self.connection:
|
if not self.connection:
|
||||||
return
|
return
|
||||||
if not msg and chatstate is None:
|
if not msg and chatstate is None:
|
||||||
|
@ -2144,14 +2149,19 @@ class Connection:
|
||||||
# please note that the only valid tag inside a message containing a <body>
|
# please note that the only valid tag inside a message containing a <body>
|
||||||
# tag is the active event
|
# tag is the active event
|
||||||
if chatstate is not None:
|
if chatstate is not None:
|
||||||
# JEP-0085
|
if composing_jep == 'JEP-0085' or not composing_jep:
|
||||||
msg_iq.setTag(chatstate, namespace = common.xmpp.NS_CHATSTATES)
|
# JEP-0085
|
||||||
# JEP-0022
|
msg_iq.setTag(chatstate, namespace = common.xmpp.NS_CHATSTATES)
|
||||||
chatstate_node = msg_iq.setTag('x', namespace = common.xmpp.NS_EVENT)
|
if composing_jep == 'JEP-0022' or not composing_jep:
|
||||||
if msg_id:
|
# JEP-0022
|
||||||
chatstate_node.setTagData('id', msg_id)
|
chatstate_node = msg_iq.setTag('x', namespace = common.xmpp.NS_EVENT)
|
||||||
if chatstate is 'composing' or msgtxt:
|
if not msgtxt: # when no <body>, add <id>
|
||||||
chatstate_node.addChild(name = 'composing') # we request JEP-0022 composing notification
|
if not msg_id: # avoid putting 'None' in <id> tag
|
||||||
|
msg_id = ''
|
||||||
|
chatstate_node.setTagData('id', msg_id)
|
||||||
|
# when msgtxt, requests JEP-0022 composing notification
|
||||||
|
if chatstate is 'composing' or msgtxt:
|
||||||
|
chatstate_node.addChild(name = 'composing')
|
||||||
|
|
||||||
self.connection.send(msg_iq)
|
self.connection.send(msg_iq)
|
||||||
no_log_for = gajim.config.get_per('accounts', self.name, 'no_log_for')
|
no_log_for = gajim.config.get_per('accounts', self.name, 'no_log_for')
|
||||||
|
|
|
@ -28,7 +28,7 @@ class Contact:
|
||||||
'''Information concerning each contact'''
|
'''Information concerning each contact'''
|
||||||
def __init__(self, jid='', name='', groups=[], show='', status='', sub='',
|
def __init__(self, jid='', name='', groups=[], show='', status='', sub='',
|
||||||
ask='', resource='', priority=5, keyID='', our_chatstate=None,
|
ask='', resource='', priority=5, keyID='', our_chatstate=None,
|
||||||
chatstate=None, last_status_time=None):
|
chatstate=None, last_status_time=None, msg_id = None, composing_jep = None):
|
||||||
self.jid = jid
|
self.jid = jid
|
||||||
self.name = name
|
self.name = name
|
||||||
self.groups = groups
|
self.groups = groups
|
||||||
|
@ -48,7 +48,11 @@ class Contact:
|
||||||
# 'ask' if we sent the first 'active' chatstate and are waiting for reply
|
# 'ask' if we sent the first 'active' chatstate and are waiting for reply
|
||||||
# this holds what WE SEND to contact (our current chatstate)
|
# this holds what WE SEND to contact (our current chatstate)
|
||||||
self.our_chatstate = our_chatstate
|
self.our_chatstate = our_chatstate
|
||||||
self.msg_id = None
|
self.msg_id = msg_id
|
||||||
|
# tell which JEP we're using for composing state
|
||||||
|
# None = have to ask, JEP-0022 = use this jep,
|
||||||
|
# JEP-0085 = use this jep, False = no composing support
|
||||||
|
self.composing_jep = composing_jep
|
||||||
# this is contact's chatstate
|
# this is contact's chatstate
|
||||||
self.chatstate = chatstate
|
self.chatstate = chatstate
|
||||||
self.last_status_time = last_status_time
|
self.last_status_time = last_status_time
|
||||||
|
@ -120,9 +124,10 @@ class Contacts:
|
||||||
|
|
||||||
def create_contact(self, jid='', name='', groups=[], show='', status='',
|
def create_contact(self, jid='', name='', groups=[], show='', status='',
|
||||||
sub='', ask='', resource='', priority=5, keyID='', our_chatstate=None,
|
sub='', ask='', resource='', priority=5, keyID='', our_chatstate=None,
|
||||||
chatstate=None, last_status_time=None):
|
chatstate=None, last_status_time=None, composing_jep=None):
|
||||||
return Contact(jid, name, groups, show, status, sub, ask, resource,
|
return Contact(jid, name, groups, show, status, sub, ask, resource,
|
||||||
priority, keyID, our_chatstate, chatstate, last_status_time)
|
priority, keyID, our_chatstate, chatstate, last_status_time,
|
||||||
|
composing_jep)
|
||||||
|
|
||||||
def copy_contact(self, contact):
|
def copy_contact(self, contact):
|
||||||
return self.create_contact(jid = contact.jid, name = contact.name,
|
return self.create_contact(jid = contact.jid, name = contact.name,
|
||||||
|
|
|
@ -388,7 +388,7 @@ class Interface:
|
||||||
# reset chatstate if needed:
|
# reset chatstate if needed:
|
||||||
# (when contact signs out or has errors)
|
# (when contact signs out or has errors)
|
||||||
if array[1] in ('offline', 'error'):
|
if array[1] in ('offline', 'error'):
|
||||||
contact1.our_chatstate = contact1.chatstate = None
|
contact1.our_chatstate = contact1.chatstate = contact1.composing_jep = None
|
||||||
self.roster.chg_contact_status(contact1, array[1], array[2], account)
|
self.roster.chg_contact_status(contact1, array[1], array[2], account)
|
||||||
# play sound
|
# play sound
|
||||||
if old_show < 2 and new_show > 1:
|
if old_show < 2 and new_show > 1:
|
||||||
|
@ -474,6 +474,7 @@ class Interface:
|
||||||
msg_type = array[4]
|
msg_type = array[4]
|
||||||
chatstate = array[6]
|
chatstate = array[6]
|
||||||
msg_id = array[7]
|
msg_id = array[7]
|
||||||
|
composing_jep = array[8]
|
||||||
if jid.find('@') <= 0:
|
if jid.find('@') <= 0:
|
||||||
jid = jid.replace('@', '')
|
jid = jid.replace('@', '')
|
||||||
|
|
||||||
|
@ -512,6 +513,7 @@ class Interface:
|
||||||
|
|
||||||
# Handle chat states
|
# Handle chat states
|
||||||
contact = gajim.contacts.get_first_contact_from_jid(account, jid)
|
contact = gajim.contacts.get_first_contact_from_jid(account, jid)
|
||||||
|
contact.composing_jep = composing_jep
|
||||||
if chat_control and chat_control.type_id == message_control.TYPE_CHAT:
|
if chat_control and chat_control.type_id == message_control.TYPE_CHAT:
|
||||||
if chatstate is not None: # he or she sent us reply, so he supports jep85 or jep22
|
if chatstate is not None: # he or she sent us reply, so he supports jep85 or jep22
|
||||||
contact.chatstate = chatstate
|
contact.chatstate = chatstate
|
||||||
|
@ -520,7 +522,7 @@ class Interface:
|
||||||
|
|
||||||
chat_control.handle_incoming_chatstate()
|
chat_control.handle_incoming_chatstate()
|
||||||
elif contact.chatstate != 'active':
|
elif contact.chatstate != 'active':
|
||||||
# got no valid jep85 no jep22 answer, peer does not support it
|
# got no valid jep85 answer, peer does not support it
|
||||||
contact.chatstate = False
|
contact.chatstate = False
|
||||||
elif contact and chatstate == 'active':
|
elif contact and chatstate == 'active':
|
||||||
# Brand new message, incoming.
|
# Brand new message, incoming.
|
||||||
|
|
|
@ -133,12 +133,14 @@ class MessageControl:
|
||||||
n = len(gajim.awaiting_events[self.account][self.contact.jid])
|
n = len(gajim.awaiting_events[self.account][self.contact.jid])
|
||||||
return n
|
return n
|
||||||
|
|
||||||
def send_message(self, message, keyID = '', type = 'chat', chatstate = None, msg_id = None):
|
def send_message(self, message, keyID = '', type = 'chat',
|
||||||
|
chatstate = None, msg_id = None, composing_jep = None):
|
||||||
'''Send the given message to the active tab'''
|
'''Send the given message to the active tab'''
|
||||||
jid = self.contact.jid
|
jid = self.contact.jid
|
||||||
# Send and update history
|
# Send and update history
|
||||||
gajim.connections[self.account].send_message(jid, message, keyID,
|
gajim.connections[self.account].send_message(jid, message, keyID,
|
||||||
type = type, chatstate = chatstate, msg_id = msg_id)
|
type = type, chatstate = chatstate, msg_id = msg_id,
|
||||||
|
composing_jep = composing_jep)
|
||||||
|
|
||||||
def position_menu_under_button(self, menu):
|
def position_menu_under_button(self, menu):
|
||||||
#FIXME: BUG http://bugs.gnome.org/show_bug.cgi?id=316786
|
#FIXME: BUG http://bugs.gnome.org/show_bug.cgi?id=316786
|
||||||
|
|
Loading…
Reference in New Issue