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:
parent
acdb712838
commit
0b2f9d4617
|
@ -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
|
||||||
|
|
|
@ -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 ?
|
||||||
|
|
23
src/gajim.py
23
src/gajim.py
|
@ -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,
|
||||||
|
|
|
@ -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_)
|
||||||
|
|
60
src/vcard.py
60
src/vcard.py
|
@ -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)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue