Author: bct
Date: 2008-02-06 02:40:51 +0100 (Wed, 06 Feb 2008)
New Revision: 9307
Added:
branches/session_centric/src/session.py
Modified:
branches/session_centric/src/common/connection_handlers.py
branches/session_centric/src/common/events.py
branches/session_centric/src/gajim.py
branches/session_centric/src/roster_window.py
Log:
move message handling into ChatControlSession
Modified: branches/session_centric/src/common/connection_handlers.py
===================================================================
--- branches/session_centric/src/common/connection_handlers.py 2008-02-05 22:13:16 UTC (rev 9306)
+++ branches/session_centric/src/common/connection_handlers.py 2008-02-06 01:40:51 UTC (rev 9307)
@@ -49,7 +49,8 @@
import dbus
from music_track_listener import MusicTrackListener
-from common.stanza_session import EncryptedStanzaSession
+# XXX interface leaking into the back end?
+import session
STATUS_LIST = ['offline', 'connecting', 'online', 'chat', 'away', 'xa', 'dnd',
'invisible', 'error']
@@ -1713,9 +1714,9 @@
treat_as = gajim.config.get('treat_incoming_messages')
if treat_as:
mtype = treat_as
- self.dispatch('MSG', (frm, msgtxt, tim, encrypted, mtype,
- subject, chatstate, msg_id, composing_xep, user_nick, msghtml,
- session, form_node))
+
+ session.received(frm, msgtxt, tim, encrypted, mtype, subject, chatstate,
+ msg_id, composing_xep, user_nick, msghtml, form_node)
# END messageCB
def get_session(self, jid, thread_id, type):
@@ -1786,7 +1787,7 @@
return None
def make_new_session(self, jid, thread_id = None, type = 'chat'):
- sess = EncryptedStanzaSession(self, common.xmpp.JID(jid), thread_id, type)
+ sess = session.ChatControlSession(self, common.xmpp.JID(jid), thread_id, type)
if not jid in self.sessions:
self.sessions[jid] = {}
Modified: branches/session_centric/src/common/events.py
===================================================================
--- branches/session_centric/src/common/events.py 2008-02-05 22:13:16 UTC (rev 9306)
+++ branches/session_centric/src/common/events.py 2008-02-06 01:40:51 UTC (rev 9307)
@@ -168,7 +168,7 @@
'''returns all events from the given account of the form
{jid1: [], jid2: []}
if jid is given, returns all events from the given jid in a list: []
- optionnaly only from given type'''
+ optionally only from given type'''
if not self._events.has_key(account):
return []
if not jid:
Modified: branches/session_centric/src/gajim.py
===================================================================
--- branches/session_centric/src/gajim.py 2008-02-05 22:13:16 UTC (rev 9306)
+++ branches/session_centric/src/gajim.py 2008-02-06 01:40:51 UTC (rev 9307)
@@ -727,141 +727,6 @@
self.handle_event_gc_notify(account, (jid, array[1], status_message,
array[3], None, None, None, None, None, [], None, None))
-
- def handle_event_msg(self, account, array):
- # 'MSG' (account, (jid, msg, time, encrypted, msg_type, subject,
- # chatstate, msg_id, composing_xep, user_nick, xhtml, session, form_node))
- # user_nick is JEP-0172
-
- full_jid_with_resource = array[0]
- jid = gajim.get_jid_without_resource(full_jid_with_resource)
- resource = gajim.get_resource_from_jid(full_jid_with_resource)
-
- message = array[1]
- encrypted = array[3]
- msg_type = array[4]
- subject = array[5]
- chatstate = array[6]
- msg_id = array[7]
- composing_xep = array[8]
- xhtml = array[10]
- session = array[11]
- if gajim.config.get('ignore_incoming_xhtml'):
- xhtml = None
- if gajim.jid_is_transport(jid):
- jid = jid.replace('@', '')
-
- groupchat_control = self.msg_win_mgr.get_control(jid, account)
- if not groupchat_control and \
- jid in self.minimized_controls[account]:
- groupchat_control = self.minimized_controls[account][jid]
- pm = False
- if groupchat_control and groupchat_control.type_id == \
- message_control.TYPE_GC:
- # It's a Private message
- pm = True
- msg_type = 'pm'
-
- chat_control = None
- jid_of_control = full_jid_with_resource
- highest_contact = gajim.contacts.get_contact_with_highest_priority(
- account, jid)
- # Look for a chat control that has the given resource, or default to one
- # without resource
- ctrl = self.msg_win_mgr.get_control(full_jid_with_resource, account)
- if ctrl:
- chat_control = ctrl
- elif not pm and (not highest_contact or not highest_contact.resource):
- # unknow contact or offline message
- jid_of_control = jid
- chat_control = self.msg_win_mgr.get_control(jid, account)
- elif highest_contact and resource != highest_contact.resource and \
- highest_contact.show != 'offline':
- jid_of_control = full_jid_with_resource
- chat_control = None
- elif not pm:
- jid_of_control = jid
- chat_control = self.msg_win_mgr.get_control(jid, account)
-
- # Handle chat states
- contact = gajim.contacts.get_contact(account, jid, resource)
- if contact:
- if contact.composing_xep != 'XEP-0085': # We cache xep85 support
- contact.composing_xep = composing_xep
- if chat_control and chat_control.type_id == message_control.TYPE_CHAT:
- if chatstate is not None:
- # other peer sent us reply, so he supports jep85 or jep22
- contact.chatstate = chatstate
- if contact.our_chatstate == 'ask': # we were jep85 disco?
- contact.our_chatstate = 'active' # no more
- chat_control.handle_incoming_chatstate()
- elif contact.chatstate != 'active':
- # got no valid jep85 answer, peer does not support it
- contact.chatstate = False
- elif chatstate == 'active':
- # Brand new message, incoming.
- contact.our_chatstate = chatstate
- contact.chatstate = chatstate
- if msg_id: # Do not overwrite an existing msg_id with None
- contact.msg_id = msg_id
-
- # THIS MUST BE AFTER chatstates handling
- # AND BEFORE playsound (else we ear sounding on chatstates!)
- if not message: # empty message text
- return
-
- if gajim.config.get('ignore_unknown_contacts') and \
- not gajim.contacts.get_contacts(account, jid) and not pm:
- return
- if not contact:
- # contact is not in the roster, create a fake one to display
- # notification
- contact = common.contacts.Contact(jid = jid, resource = resource)
- advanced_notif_num = notify.get_advanced_notification('message_received',
- account, contact)
-
- # Is it a first or next message received ?
- first = False
- if msg_type == 'normal':
- if not gajim.events.get_events(account, jid, ['normal']):
- first = True
- elif not chat_control and not gajim.events.get_events(account,
- jid_of_control, [msg_type]): # msg_type can be chat or pm
- first = True
-
- if pm:
- nickname = resource
- groupchat_control.on_private_message(nickname, message, array[2],
- xhtml, session, msg_id)
- else:
- # array: (jid, msg, time, encrypted, msg_type, subject)
- if encrypted:
- self.roster.on_message(jid, message, array[2], account, array[3],
- msg_type, subject, resource, msg_id, array[9],
- advanced_notif_num, session=session, form_node=array[12])
- else:
- # xhtml in last element
- self.roster.on_message(jid, message, array[2], account, array[3],
- msg_type, subject, resource, msg_id, array[9],
- advanced_notif_num, xhtml=xhtml, session=session,
- form_node=array[12])
- nickname = gajim.get_name_from_jid(account, jid)
- # Check and do wanted notifications
- msg = message
- if subject:
- msg = _('Subject: %s') % subject + '\n' + msg
- focused = False
- if chat_control:
- parent_win = chat_control.parent_win
- if chat_control == parent_win.get_active_control() and \
- parent_win.window.has_focus:
- focused = True
- notify.notify('new_message', jid_of_control, account, [msg_type,
- first, nickname, msg, focused], advanced_notif_num)
-
- if self.remote_ctrl:
- self.remote_ctrl.raise_signal('NewMessage', (account, array))
-
def handle_event_msgerror(self, account, array):
#'MSGERROR' (account, (jid, error_code, error_msg, msg, time))
full_jid_with_resource = array[0]
@@ -2556,7 +2421,6 @@
'ERROR_ANSWER': self.handle_event_error_answer,
'STATUS': self.handle_event_status,
'NOTIFY': self.handle_event_notify,
- 'MSG': self.handle_event_msg,
'MSGERROR': self.handle_event_msgerror,
'MSGSENT': self.handle_event_msgsent,
'MSGNOTSENT': self.handle_event_msgnotsent,
Modified: branches/session_centric/src/roster_window.py
===================================================================
--- branches/session_centric/src/roster_window.py 2008-02-05 22:13:16 UTC (rev 9306)
+++ branches/session_centric/src/roster_window.py 2008-02-06 01:40:51 UTC (rev 9307)
@@ -3929,7 +3929,7 @@
# We call this here to avoid race conditions with widget validation
chat_control.read_queue()
- def new_chat(self, contact, account, resource = None, session = None):
+ def new_chat(self, session, contact, account, resource = None):
# Get target window, create a control, and associate it with the window
type_ = message_control.TYPE_CHAT
@@ -3945,9 +3945,7 @@
mw.new_tab(chat_control)
- if len(gajim.events.get_events(account, fjid)):
- # We call this here to avoid race conditions with widget validation
- chat_control.read_queue()
+ return chat_control
def new_chat_from_jid(self, account, fjid):
jid, resource = gajim.get_room_and_nick_from_fjid(fjid)
@@ -3963,7 +3961,12 @@
resource = resource)
if not gajim.interface.msg_win_mgr.has_window(fjid, account):
- self.new_chat(contact, account, resource = resource)
+ session = account.make_new_session(account, fjid)
+ self.control = self.new_chat(session, contact, account, resource = resource)
+
+ if len(gajim.events.get_events(account, fjid)):
+ chat_control.read_queue()
+
mw = gajim.interface.msg_win_mgr.get_window(fjid, account)
mw.set_active_tab(fjid, account)
mw.window.present()
@@ -3983,114 +3986,6 @@
is_continued=is_continued)
mw.new_tab(gc_control)
- def on_message(self, jid, msg, tim, account, encrypted=False, msg_type='',
- subject=None, resource='', msg_id=None, user_nick='',
- advanced_notif_num=None, xhtml=None, session=None, form_node=None):
- '''when we receive a message'''
- contact = None
- # if chat window will be for specific resource
- resource_for_chat = resource
- fjid = jid
- # Try to catch the contact with correct resource
- if resource:
- fjid = jid + '/' + resource
- contact = gajim.contacts.get_contact(account, jid, resource)
- highest_contact = gajim.contacts.get_contact_with_highest_priority(
- account, jid)
- if not contact:
- # If there is another resource, it may be a message from an invisible
- # resource
- lcontact = gajim.contacts.get_contacts(account, jid)
- if (len(lcontact) > 1 or (lcontact and lcontact[0].resource and \
- lcontact[0].show != 'offline')) and jid.find('@') > 0:
- contact = gajim.contacts.copy_contact(highest_contact)
- contact.resource = resource
- if resource:
- fjid = jid + '/' + resource
- contact.priority = 0
- contact.show = 'offline'
- contact.status = ''
- gajim.contacts.add_contact(account, contact)
-
- else:
- # Default to highest prio
- fjid = jid
- resource_for_chat = None
- contact = highest_contact
- if not contact:
- # contact is not in roster
- contact = self.add_to_not_in_the_roster(account, jid, user_nick)
-
- path = self.get_path(jid, account) # Try to get line of contact in roster
-
- # Look for a chat control that has the given resource
- ctrl = gajim.interface.msg_win_mgr.get_control(fjid, account)
- if not ctrl:
- # if not, if message comes from highest prio, get control or open one
- # without resource
- if highest_contact and contact.resource == highest_contact.resource \
- and not jid == gajim.get_jid_from_account(account):
- ctrl = gajim.interface.msg_win_mgr.get_control(jid, account)
- fjid = jid
- resource_for_chat = None
-
- # Do we have a queue?
- no_queue = len(gajim.events.get_events(account, fjid)) == 0
-
- popup = helpers.allow_popup_window(account, advanced_notif_num)
-
- if msg_type == 'normal' and popup: # it's single message to be autopopuped
- dialogs.SingleMessageWindow(account, contact.jid, action='receive',
- from_whom=jid, subject=subject, message=msg, resource=resource,
- session=session, form_node=form_node)
- return
-
- # We print if window is opened and it's not a single message
- if ctrl and msg_type != 'normal':
- typ = ''
- if msg_type == 'error':
- typ = 'status'
- if session:
- ctrl.set_session(session)
- ctrl.print_conversation(msg, typ, tim = tim, encrypted = encrypted,
- subject = subject, xhtml = xhtml)
- if msg_id:
- gajim.logger.set_read_messages([msg_id])
- return
-
- # We save it in a queue
- type_ = 'chat'
- event_type = 'message_received'
- if msg_type == 'normal':
- type_ = 'normal'
- event_type = 'single_message_received'
- show_in_roster = notify.get_show_in_roster(event_type, account, contact)
- show_in_systray = notify.get_show_in_systray(event_type, account, contact)
- event = gajim.events.create_event(type_, (msg, subject, msg_type, tim,
- encrypted, resource, msg_id, xhtml, session, form_node),
- show_in_roster=show_in_roster, show_in_systray=show_in_systray)
- gajim.events.add_event(account, fjid, event)
- if popup:
- if not ctrl:
- self.new_chat(contact, account, resource=resource_for_chat)
- if path and not self.dragging and gajim.config.get(
- 'scroll_roster_to_last_message'):
- # we curently see contact in our roster OR he
- # is not in the roster at all.
- # show and select his line in roster
- # do not change selection while DND'ing
- self.tree.expand_row(path[0:1], False)
- self.tree.expand_row(path[0:2], False)
- self.tree.scroll_to_cell(path)
- self.tree.set_cursor(path)
- else:
- if no_queue: # We didn't have a queue: we change icons
- self.draw_contact(jid, account)
- self.show_title() # we show the * or [n]
- # Show contact in roster (if he is invisible for example) and select
- # line
- self.show_and_select_path(path, jid, account)
-
def on_preferences_menuitem_activate(self, widget):
if gajim.interface.instances.has_key('preferences'):
gajim.interface.instances['preferences'].window.present()
@@ -4399,7 +4294,7 @@
fjid += '/' + resource
win = gajim.interface.msg_win_mgr.get_window(fjid, account)
if not win:
- self.new_chat(contact, account, resource = resource, session = session)
+ self.new_chat(session, contact, account, resource = resource)
win = gajim.interface.msg_win_mgr.get_window(fjid, account)
ctrl = win.get_control(fjid, account)
# last message is long time ago
Added: branches/session_centric/src/session.py
===================================================================
--- branches/session_centric/src/session.py (rev 0)
+++ branches/session_centric/src/session.py 2008-02-06 01:40:51 UTC (rev 9307)
@@ -0,0 +1,224 @@
+from common import helpers
+
+from common import gajim
+from common import stanza_session
+from common import contacts
+
+import dialogs
+
+import message_control
+
+import notify
+
+class ChatControlSession(stanza_session.EncryptedStanzaSession):
+ def __init__(self, conn, jid, thread_id, type = 'chat'):
+ stanza_session.EncryptedStanzaSession.__init__(self, conn, jid, thread_id, type = 'chat')
+
+ self.control = None
+
+ def received(self, full_jid_with_resource, message, tim, encrypted, msg_type, subject, chatstate, msg_id, composing_xep, user_nick, xhtml, form_node):
+
+ jid = gajim.get_jid_without_resource(full_jid_with_resource)
+ resource = gajim.get_resource_from_jid(full_jid_with_resource)
+
+ if gajim.config.get('ignore_incoming_xhtml'):
+ xhtml = None
+ if gajim.jid_is_transport(jid):
+ jid = jid.replace('@', '')
+
+ groupchat_control = gajim.interface.msg_win_mgr.get_control(jid, self.conn.name)
+ if not groupchat_control and \
+ jid in gajim.interface.minimized_controls[self.conn.name]:
+ groupchat_control = self.minimized_controls[self.conn.name][jid]
+
+ pm = False
+ if groupchat_control and groupchat_control.type_id == \
+ message_control.TYPE_GC:
+ # It's a Private message
+ pm = True
+ msg_type = 'pm'
+
+ jid_of_control = full_jid_with_resource
+
+ # Handle chat states
+ contact = gajim.contacts.get_contact(self.conn.name, jid, resource)
+ if contact:
+ if contact.composing_xep != 'XEP-0085': # We cache xep85 support
+ contact.composing_xep = composing_xep
+ if self.control and self.control.type_id == message_control.TYPE_CHAT:
+ if chatstate is not None:
+ # other peer sent us reply, so he supports jep85 or jep22
+ contact.chatstate = chatstate
+ if contact.our_chatstate == 'ask': # we were jep85 disco?
+ contact.our_chatstate = 'active' # no more
+ self.control.handle_incoming_chatstate()
+ elif contact.chatstate != 'active':
+ # got no valid jep85 answer, peer does not support it
+ contact.chatstate = False
+ elif chatstate == 'active':
+ # Brand new message, incoming.
+ contact.our_chatstate = chatstate
+ contact.chatstate = chatstate
+ if msg_id: # Do not overwrite an existing msg_id with None
+ contact.msg_id = msg_id
+
+ # THIS MUST BE AFTER chatstates handling
+ # AND BEFORE playsound (else we ear sounding on chatstates!)
+ if not message: # empty message text
+ return
+
+ if gajim.config.get('ignore_unknown_contacts') and \
+ not gajim.contacts.get_contacts(self.conn.name, jid) and not pm:
+ return
+
+ if not contact:
+ # contact is not in the roster, create a fake one to display
+ # notification
+ contact = contacts.Contact(jid = jid, resource = resource)
+ advanced_notif_num = notify.get_advanced_notification('message_received',
+ self.conn.name, contact)
+
+ # Is it a first or next message received ?
+ first = False
+ if not self.control:
+ first = True
+
+ if pm:
+ nickname = resource
+ groupchat_control.on_private_message(nickname, message, array[2],
+ xhtml, session, msg_id)
+ else:
+ self.roster_message(jid, message, tim, encrypted, msg_type,
+ subject, resource, msg_id, user_nick, advanced_notif_num,
+ xhtml=xhtml, form_node=form_node)
+
+ nickname = gajim.get_name_from_jid(self.conn.name, jid)
+ # Check and do wanted notifications
+ msg = message
+ if subject:
+ msg = _('Subject: %s') % subject + '\n' + msg
+ focused = False
+
+ if self.control:
+ parent_win = self.control.parent_win
+ if self.control == parent_win.get_active_control() and \
+ parent_win.window.has_focus:
+ focused = True
+
+ notify.notify('new_message', jid_of_control, self.conn.name, [msg_type,
+ first, nickname, msg, focused], advanced_notif_num)
+
+ if gajim.interface.remote_ctrl:
+ gajim.interface.remote_ctrl.raise_signal('NewMessage', (self.conn.name, [full_jid_with_resource, message, tim, encrypted, msg_type, subject, chatstate, msg_id, composing_xep, user_nick, xhtml, form_node]))
+
+ def roster_message(self, jid, msg, tim, encrypted=False, msg_type='',
+ subject=None, resource='', msg_id=None, user_nick='',
+ advanced_notif_num=None, xhtml=None, form_node=None):
+ contact = None
+ # if chat window will be for specific resource
+ resource_for_chat = resource
+
+ fjid = jid
+
+ # Try to catch the contact with correct resource
+ if resource:
+ fjid = jid + '/' + resource
+ contact = gajim.contacts.get_contact(self.conn.name, jid, resource)
+
+ highest_contact = gajim.contacts.get_contact_with_highest_priority(
+ self.conn.name, jid)
+ if not contact:
+ # If there is another resource, it may be a message from an invisible
+ # resource
+ lcontact = gajim.contacts.get_contacts(self.conn.name, jid)
+ if (len(lcontact) > 1 or (lcontact and lcontact[0].resource and \
+ lcontact[0].show != 'offline')) and jid.find('@') > 0:
+ contact = gajim.contacts.copy_contact(highest_contact)
+ contact.resource = resource
+ if resource:
+ fjid = jid + '/' + resource
+ contact.priority = 0
+ contact.show = 'offline'
+ contact.status = ''
+ gajim.contacts.add_contact(self.conn.name, contact)
+
+ else:
+ # Default to highest prio
+ fjid = jid
+ resource_for_chat = None
+ contact = highest_contact
+
+ if not contact:
+ # contact is not in roster
+ contact = gajim.interface.roster.add_to_not_in_the_roster(self.conn.name, jid, user_nick)
+
+ path = gajim.interface.roster.get_path(jid, self.conn.name) # Try to get line of contact in roster
+
+ # Do we have a queue?
+ no_queue = len(gajim.events.get_events(self.conn.name, fjid)) == 0
+
+ popup = helpers.allow_popup_window(self.conn.name, advanced_notif_num)
+
+ if msg_type == 'normal' and popup: # it's single message to be autopopuped
+ dialogs.SingleMessageWindow(self.conn.name, contact.jid, action='receive',
+ from_whom=jid, subject=subject, message=msg, resource=resource,
+ session=self, form_node=form_node)
+ return
+
+ # We print if window is opened and it's not a single message
+ if self.control and msg_type != 'normal':
+ typ = ''
+
+ if msg_type == 'error':
+ typ = 'status'
+
+ self.control.print_conversation(msg, typ, tim = tim,
+ encrypted = encrypted, subject = subject, xhtml = xhtml)
+
+ if msg_id:
+ gajim.logger.set_read_messages([msg_id])
+
+ return
+
+ # We save it in a queue
+ type_ = 'chat'
+ event_type = 'message_received'
+
+ if msg_type == 'normal':
+ type_ = 'normal'
+ event_type = 'single_message_received'
+
+ show_in_roster = notify.get_show_in_roster(event_type, self.conn.name, contact)
+ show_in_systray = notify.get_show_in_systray(event_type, self.conn.name, contact)
+
+ event = gajim.events.create_event(type_, (msg, subject, msg_type, tim,
+ encrypted, resource, msg_id, xhtml, self, form_node),
+ show_in_roster=show_in_roster, show_in_systray=show_in_systray)
+
+ gajim.events.add_event(self.conn.name, fjid, event)
+
+ if popup:
+ if not self.control:
+ self.control = self.new_chat(self, contact, self.conn.name, resource=resource_for_chat)
+
+ if len(gajim.events.get_events(self.conn.name, fjid)):
+ self.control.read_queue()
+
+ if path and not gajim.interface.dragging and gajim.config.get(
+ 'scroll_roster_to_last_message'):
+ # we curently see contact in our roster OR he
+ # is not in the roster at all.
+ # show and select his line in roster
+ # do not change selection while DND'ing
+ self.tree.expand_row(path[0:1], False)
+ self.tree.expand_row(path[0:2], False)
+ self.tree.scroll_to_cell(path)
+ self.tree.set_cursor(path)
+ else:
+ if no_queue: # We didn't have a queue: we change icons
+ gajim.interface.roster.draw_contact(jid, self.conn.name)
+
+ gajim.interface.roster.show_title() # we show the * or [n]
+ # Show contact in roster (if he is invisible for example) and select
+ # line
+ gajim.interface.roster.show_and_select_path(path, jid, self.conn.name)