we now keep last_status_time, show it in tooltip and information window, ask it (jabber:iq:last, JEP-0012) when we open information window. Fixes #1133

This commit is contained in:
Yann Leboulanger 2006-02-22 14:31:01 +00:00
parent acdb712838
commit 0b2f9d4617
5 changed files with 116 additions and 32 deletions

View File

@ -1266,7 +1266,7 @@ class Connection:
self.connection.send(iq_obj) self.connection.send(iq_obj)
raise common.xmpp.NodeProcessed raise common.xmpp.NodeProcessed
def _IdleCB(self, con, iq_obj): def _LastCB(self, con, iq_obj):
gajim.log.debug('IdleCB') gajim.log.debug('IdleCB')
iq_obj = iq_obj.buildReply('result') iq_obj = iq_obj.buildReply('result')
qp = iq_obj.getTag('query') qp = iq_obj.getTag('query')
@ -1278,6 +1278,19 @@ class Connection:
self.connection.send(iq_obj) self.connection.send(iq_obj)
raise common.xmpp.NodeProcessed raise common.xmpp.NodeProcessed
def _LastResultCB(self, con, iq_obj):
gajim.log.debug('LastResultCB')
qp = iq_obj.getTag('query')
seconds = qp.getAttr('seconds')
status = qp.getData()
try:
seconds = int(seconds)
except:
return
who = self.get_full_jid(iq_obj)
jid_stripped, resource = gajim.get_room_and_nick_from_fjid(who)
self.dispatch('LAST_STATUS_TIME', (jid_stripped, resource, seconds, status))
def _VersionResultCB(self, con, iq_obj): def _VersionResultCB(self, con, iq_obj):
gajim.log.debug('VersionResultCB') gajim.log.debug('VersionResultCB')
client_info = '' client_info = ''
@ -1837,7 +1850,9 @@ class Connection:
common.xmpp.NS_DISCO_INFO) common.xmpp.NS_DISCO_INFO)
con.RegisterHandler('iq', self._VersionCB, 'get', con.RegisterHandler('iq', self._VersionCB, 'get',
common.xmpp.NS_VERSION) common.xmpp.NS_VERSION)
con.RegisterHandler('iq', self._IdleCB, 'get', con.RegisterHandler('iq', self._LastCB, 'get',
common.xmpp.NS_LAST)
con.RegisterHandler('iq', self._LastResultCB, 'result',
common.xmpp.NS_LAST) common.xmpp.NS_LAST)
con.RegisterHandler('iq', self._VersionResultCB, 'result', con.RegisterHandler('iq', self._VersionResultCB, 'result',
common.xmpp.NS_VERSION) common.xmpp.NS_VERSION)
@ -2272,6 +2287,16 @@ class Connection:
def account_changed(self, new_name): def account_changed(self, new_name):
self.name = new_name self.name = new_name
def request_last_status_time(self, jid, resource):
if not self.connection:
return
to_whom_jid = jid
if resource:
to_whom_jid += '/' + resource
iq = common.xmpp.Iq(to = to_whom_jid, typ = 'get', queryNS =\
common.xmpp.NS_LAST)
self.connection.send(iq)
def request_os_info(self, jid, resource): def request_os_info(self, jid, resource):
if not self.connection: if not self.connection:
return return

View File

@ -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): chatstate=None, last_status_time=None):
self.jid = jid self.jid = jid
self.name = name self.name = name
self.groups = groups self.groups = groups
@ -50,6 +50,7 @@ class Contact:
self.our_chatstate = our_chatstate self.our_chatstate = our_chatstate
# this is contact's chatstate # this is contact's chatstate
self.chatstate = chatstate self.chatstate = chatstate
self.last_status_time = last_status_time
def get_full_jid(self): def get_full_jid(self):
if self.resource: if self.resource:
@ -118,16 +119,17 @@ 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): chatstate=None, last_status_time=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) priority, keyID, our_chatstate, chatstate, last_status_time)
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,
groups = contact.groups, show = contact.show, status = contact.status, groups = contact.groups, show = contact.show, status = contact.status,
sub = contact.sub, ask = contact.ask, resource = contact.resource, sub = contact.sub, ask = contact.ask, resource = contact.resource,
priority = contact.priority, keyID = contact.keyID, priority = contact.priority, keyID = contact.keyID,
our_chatstate = contact.our_chatstate, chatstate = contact.chatstate) our_chatstate = contact.our_chatstate, chatstate = contact.chatstate,
last_status_time = contact.last_status_time)
def add_contact(self, account, contact): def add_contact(self, account, contact):
# No such account before ? # No such account before ?

View File

@ -372,6 +372,8 @@ class Interface:
contact1.status = array[2] contact1.status = array[2]
contact1.priority = priority contact1.priority = priority
contact1.keyID = keyID contact1.keyID = keyID
if contact1.jid not in gajim.newly_added[account]:
contact1.last_status_time = time.localtime()
if jid.find('@') <= 0: if jid.find('@') <= 0:
# It must be an agent # It must be an agent
if ji in jid_list: if ji in jid_list:
@ -757,6 +759,26 @@ class Interface:
if self.remote_ctrl: if self.remote_ctrl:
self.remote_ctrl.raise_signal('VcardInfo', (account, vcard)) self.remote_ctrl.raise_signal('VcardInfo', (account, vcard))
def handle_event_last_status_time(self, account, array):
# ('LAST_STATUS_TIME', account, (jid, resource, seconds, status))
win = None
if self.instances[account]['infos'].has_key(array[0]):
win = self.instances[account]['infos'][array[0]]
elif self.instances[account]['infos'].has_key(array[0] + '/' + array[1]):
win = self.instances[account]['infos'][array[0] + '/' + array[1]]
if win:
c = gajim.contacts.get_contact(account, array[0], array[1])
# c is a list when no resource is given. it probably means that contact
# is offline, so only on Contact instance
if isinstance(c, list):
c = c[0]
c.last_status_time = time.localtime(time.time() - array[2])
if array[3]:
c.status = array[3]
win.set_last_status_time()
if self.remote_ctrl:
self.remote_ctrl.raise_signal('LastStatusTime', (account, array))
def handle_event_os_info(self, account, array): def handle_event_os_info(self, account, array):
win = None win = None
if self.instances[account]['infos'].has_key(array[0]): if self.instances[account]['infos'].has_key(array[0]):
@ -1387,6 +1409,7 @@ class Interface:
'ACC_NOT_OK': self.handle_event_acc_not_ok, 'ACC_NOT_OK': self.handle_event_acc_not_ok,
'MYVCARD': self.handle_event_myvcard, 'MYVCARD': self.handle_event_myvcard,
'VCARD': self.handle_event_vcard, 'VCARD': self.handle_event_vcard,
'LAST_STATUS_TIME': self.handle_event_last_status_time,
'OS_INFO': self.handle_event_os_info, 'OS_INFO': self.handle_event_os_info,
'GC_NOTIFY': self.handle_event_gc_notify, 'GC_NOTIFY': self.handle_event_gc_notify,
'GC_MSG': self.handle_event_gc_msg, 'GC_MSG': self.handle_event_gc_msg,

View File

@ -27,6 +27,7 @@
import gtk import gtk
import gobject import gobject
import os import os
import time
import gtkgui_helpers import gtkgui_helpers
import message_control import message_control
@ -155,7 +156,7 @@ class StatusTable:
str_status += ' - ' + status str_status += ' - ' + status
return gtkgui_helpers.escape_for_pango_markup(str_status) return gtkgui_helpers.escape_for_pango_markup(str_status)
def add_status_row(self, file_path, show, str_status): def add_status_row(self, file_path, show, str_status, status_time = None):
''' appends a new row with status icon to the table ''' ''' appends a new row with status icon to the table '''
self.current_row += 1 self.current_row += 1
state_file = show.replace(' ', '_') state_file = show.replace(' ', '_')
@ -179,6 +180,11 @@ class StatusTable:
status_label.set_alignment(0, 0) status_label.set_alignment(0, 0)
self.table.attach(status_label, 3, 4, self.current_row, self.table.attach(status_label, 3, 4, self.current_row,
self.current_row + 1, gtk.EXPAND | gtk.FILL, 0, 0, 0) self.current_row + 1, gtk.EXPAND | gtk.FILL, 0, 0, 0)
if status_time:
self.current_row += 1
status_time_label = gtk.Label(time.strftime("%c", status_time))
self.table.attach(status_time_label, 2, 4, self.current_row,
self.current_row + 1, gtk.EXPAND | gtk.FILL, 0, 0, 0)
class NotificationAreaTooltip(BaseTooltip, StatusTable): class NotificationAreaTooltip(BaseTooltip, StatusTable):
''' Tooltip that is shown in the notification area ''' ''' Tooltip that is shown in the notification area '''
@ -441,7 +447,8 @@ class RosterTooltip(NotificationAreaTooltip):
status_line = self.get_status_info(contact.resource, status_line = self.get_status_info(contact.resource,
contact.priority, contact.show, contact.status) contact.priority, contact.show, contact.status)
icon_name = helpers.get_icon_name_to_show(contact) icon_name = helpers.get_icon_name_to_show(contact)
self.add_status_row(file_path, icon_name, status_line) self.add_status_row(file_path, icon_name, status_line,
contact.last_status_time)
else: # only one resource else: # only one resource
if contact.resource: if contact.resource:
@ -459,6 +466,9 @@ class RosterTooltip(NotificationAreaTooltip):
status = gtkgui_helpers.reduce_chars_newlines(status, 130, 5) status = gtkgui_helpers.reduce_chars_newlines(status, 130, 5)
# escape markup entities. # escape markup entities.
info += ' - ' + gtkgui_helpers.escape_for_pango_markup(status) info += ' - ' + gtkgui_helpers.escape_for_pango_markup(status)
if contact.last_status_time:
info += '\n<span weight="bold">' + _('Status time: ') + '%s</span>'\
% time.strftime('%c', contact.last_status_time)
for type_ in ('jpeg', 'png'): for type_ in ('jpeg', 'png'):
file = os.path.join(gajim.AVATAR_PATH, prim_contact.jid + '.' + type_) file = os.path.join(gajim.AVATAR_PATH, prim_contact.jid + '.' + type_)

View File

@ -31,6 +31,7 @@ import base64
import mimetypes import mimetypes
import os import os
import sys import sys
import time
import gtkgui_helpers import gtkgui_helpers
import dialogs import dialogs
@ -275,6 +276,9 @@ class VcardWindow:
else: else:
self.set_value(i + '_entry', vcard[i]) self.set_value(i + '_entry', vcard[i])
def set_last_status_time(self):
self.fill_status_label()
def set_os_info(self, resource, client_info, os_info): def set_os_info(self, resource, client_info, os_info):
i = 0 i = 0
client = '' client = ''
@ -298,6 +302,30 @@ class VcardWindow:
self.xml.get_widget('client_name_version_label').set_text(client) self.xml.get_widget('client_name_version_label').set_text(client)
self.xml.get_widget('os_label').set_text(os) self.xml.get_widget('os_label').set_text(os)
def fill_status_label(self):
contact_list = gajim.contacts.get_contact(self.account, self.contact.jid)
# stats holds show and status message
stats = ''
one = True # Are we adding the first line ?
if contact_list:
for c in contact_list:
if not one:
stats += '\n'
stats += helpers.get_uf_show(c.show)
if c.status:
stats += ': ' + c.status
if c.last_status_time:
stats += '\n ' + _('since') + time.strftime(' %c',
c.last_status_time)
one = False
status_label = self.xml.get_widget('status_label')
status_label.set_max_width_chars(15)
status_label.set_text(stats)
tip = gtk.Tooltips()
status_label_eventbox = self.xml.get_widget('status_label_eventbox')
tip.set_tip(status_label_eventbox, stats)
def fill_jabber_page(self): def fill_jabber_page(self):
tooltips = gtk.Tooltips() tooltips = gtk.Tooltips()
self.xml.get_widget('nickname_label').set_text( self.xml.get_widget('nickname_label').set_text(
@ -339,10 +367,12 @@ class VcardWindow:
if not self.contact.status: if not self.contact.status:
self.contact.status = '' self.contact.status = ''
# stats holds show and status message # Request list time status
stats = helpers.get_uf_show(self.contact.show) gajim.connections[self.account].request_last_status_time(self.contact.jid,
if self.contact.status: self.contact.resource)
stats += ': ' + self.contact.status
# Request os info in contact is connected
if self.contact.show not in ('offline', 'error'):
gajim.connections[self.account].request_os_info(self.contact.jid, gajim.connections[self.account].request_os_info(self.contact.jid,
self.contact.resource) self.contact.resource)
self.os_info = {0: {'resource': self.contact.resource, 'client': '', self.os_info = {0: {'resource': self.contact.resource, 'client': '',
@ -354,28 +384,22 @@ class VcardWindow:
if c.resource != self.contact.resource: if c.resource != self.contact.resource:
resources += '\n%s (%s)' % (c.resource, resources += '\n%s (%s)' % (c.resource,
unicode(c.priority)) unicode(c.priority))
uf_resources += '\n' + c.resource + _(' resource with priority ')\ uf_resources += '\n' + c.resource + \
+ unicode(c.priority) _(' resource with priority ') + unicode(c.priority)
if not c.status: if c.show not in ('offline', 'error'):
c.status = '' gajim.connections[self.account].request_os_info(c.jid,
stats += '\n' + c.show + ': ' + c.status c.resource)
gajim.connections[self.account].request_os_info(self.contact.jid, gajim.connections[self.account].request_last_status_time(c.jid,
c.resource) c.resource)
self.os_info[i] = {'resource': c.resource, 'client': '', self.os_info[i] = {'resource': c.resource, 'client': '',
'os': ''} 'os': ''}
i += 1 i += 1
self.xml.get_widget('resource_prio_label').set_text(resources) self.xml.get_widget('resource_prio_label').set_text(resources)
tip = gtk.Tooltips()
resource_prio_label_eventbox = self.xml.get_widget( resource_prio_label_eventbox = self.xml.get_widget(
'resource_prio_label_eventbox') 'resource_prio_label_eventbox')
tip.set_tip(resource_prio_label_eventbox, uf_resources) tooltips.set_tip(resource_prio_label_eventbox, uf_resources)
tip = gtk.Tooltips() self.fill_status_label()
status_label_eventbox = self.xml.get_widget('status_label_eventbox')
tip.set_tip(status_label_eventbox, stats)
status_label = self.xml.get_widget('status_label')
status_label.set_max_width_chars(15)
status_label.set_text(stats)
gajim.connections[self.account].request_vcard(self.contact.jid) gajim.connections[self.account].request_vcard(self.contact.jid)