Merge PEP refactorings back to the default branch.
This commit is contained in:
commit
5c32304740
|
@ -1279,14 +1279,12 @@ class ChatControl(ChatControlBase):
|
||||||
self.video_state = self.JINGLE_STATE_NOT_AVAILABLE
|
self.video_state = self.JINGLE_STATE_NOT_AVAILABLE
|
||||||
|
|
||||||
self.update_toolbar()
|
self.update_toolbar()
|
||||||
|
|
||||||
self._mood_image = self.xml.get_widget('mood_image')
|
self._pep_images = {}
|
||||||
self._activity_image = self.xml.get_widget('activity_image')
|
self._pep_images['mood'] = self.xml.get_widget('mood_image')
|
||||||
self._tune_image = self.xml.get_widget('tune_image')
|
self._pep_images['activity'] = self.xml.get_widget('activity_image')
|
||||||
|
self._pep_images['tune'] = self.xml.get_widget('tune_image')
|
||||||
self.update_mood()
|
self.update_all_pep_types()
|
||||||
self.update_activity()
|
|
||||||
self.update_tune()
|
|
||||||
|
|
||||||
# keep timeout id and window obj for possible big avatar
|
# keep timeout id and window obj for possible big avatar
|
||||||
# it is on enter-notify and leave-notify so no need to be
|
# it is on enter-notify and leave-notify so no need to be
|
||||||
|
@ -1430,118 +1428,24 @@ class ChatControl(ChatControlBase):
|
||||||
self._convert_to_gc_button.set_sensitive(True)
|
self._convert_to_gc_button.set_sensitive(True)
|
||||||
else:
|
else:
|
||||||
self._convert_to_gc_button.set_sensitive(False)
|
self._convert_to_gc_button.set_sensitive(False)
|
||||||
|
|
||||||
|
def update_all_pep_types(self):
|
||||||
|
for pep_type in self._pep_images:
|
||||||
|
self.update_pep(pep_type)
|
||||||
|
|
||||||
def update_mood(self):
|
def update_pep(self, pep_type):
|
||||||
mood = None
|
|
||||||
text = None
|
|
||||||
|
|
||||||
if isinstance(self.contact, GC_Contact):
|
if isinstance(self.contact, GC_Contact):
|
||||||
return
|
return
|
||||||
|
if pep_type not in self._pep_images:
|
||||||
if 'mood' in self.contact.mood:
|
|
||||||
mood = self.contact.mood['mood'].strip()
|
|
||||||
if 'text' in self.contact.mood:
|
|
||||||
text = self.contact.mood['text'].strip()
|
|
||||||
|
|
||||||
if mood is not None:
|
|
||||||
if mood in MOODS:
|
|
||||||
self._mood_image.set_from_pixbuf(gtkgui_helpers.load_mood_icon(
|
|
||||||
mood).get_pixbuf())
|
|
||||||
# Translate standard moods
|
|
||||||
mood = MOODS[mood]
|
|
||||||
else:
|
|
||||||
self._mood_image.set_from_pixbuf(gtkgui_helpers.load_mood_icon(
|
|
||||||
'unknown').get_pixbuf())
|
|
||||||
|
|
||||||
mood = gobject.markup_escape_text(mood)
|
|
||||||
|
|
||||||
tooltip = '<b>%s</b>' % mood
|
|
||||||
if text:
|
|
||||||
text = gobject.markup_escape_text(text)
|
|
||||||
tooltip += '\n' + text
|
|
||||||
self._mood_image.set_tooltip_markup(tooltip)
|
|
||||||
self._mood_image.show()
|
|
||||||
else:
|
|
||||||
self._mood_image.hide()
|
|
||||||
|
|
||||||
def update_activity(self):
|
|
||||||
activity = None
|
|
||||||
subactivity = None
|
|
||||||
text = None
|
|
||||||
|
|
||||||
if isinstance(self.contact, GC_Contact):
|
|
||||||
return
|
return
|
||||||
|
pep = self.contact.pep
|
||||||
if 'activity' in self.contact.activity:
|
img = self._pep_images[pep_type]
|
||||||
activity = self.contact.activity['activity'].strip()
|
if pep_type in pep:
|
||||||
if 'subactivity' in self.contact.activity:
|
img.set_from_pixbuf(pep[pep_type].asPixbufIcon())
|
||||||
subactivity = self.contact.activity['subactivity'].strip()
|
img.set_tooltip_markup(pep[pep_type].asMarkupText())
|
||||||
if 'text' in self.contact.activity:
|
img.show()
|
||||||
text = self.contact.activity['text'].strip()
|
|
||||||
|
|
||||||
if activity is not None:
|
|
||||||
if activity in ACTIVITIES:
|
|
||||||
# Translate standard activities
|
|
||||||
if subactivity in ACTIVITIES[activity]:
|
|
||||||
self._activity_image.set_from_pixbuf(
|
|
||||||
gtkgui_helpers.load_activity_icon(activity, subactivity). \
|
|
||||||
get_pixbuf())
|
|
||||||
subactivity = ACTIVITIES[activity][subactivity]
|
|
||||||
else:
|
|
||||||
self._activity_image.set_from_pixbuf(
|
|
||||||
gtkgui_helpers.load_activity_icon(activity).get_pixbuf())
|
|
||||||
activity = ACTIVITIES[activity]['category']
|
|
||||||
else:
|
|
||||||
self._activity_image.set_from_pixbuf(
|
|
||||||
gtkgui_helpers.load_activity_icon('unknown').get_pixbuf())
|
|
||||||
|
|
||||||
# Translate standard subactivities
|
|
||||||
|
|
||||||
tooltip = '<b>' + gobject.markup_escape_text(activity)
|
|
||||||
if subactivity:
|
|
||||||
tooltip += ': ' + gobject.markup_escape_text(subactivity)
|
|
||||||
tooltip += '</b>'
|
|
||||||
if text:
|
|
||||||
tooltip += '\n' + gobject.markup_escape_text(text)
|
|
||||||
self._activity_image.set_tooltip_markup(tooltip)
|
|
||||||
|
|
||||||
self._activity_image.show()
|
|
||||||
else:
|
else:
|
||||||
self._activity_image.hide()
|
img.hide()
|
||||||
|
|
||||||
def update_tune(self):
|
|
||||||
artist = None
|
|
||||||
title = None
|
|
||||||
source = None
|
|
||||||
|
|
||||||
if isinstance(self.contact, GC_Contact):
|
|
||||||
return
|
|
||||||
|
|
||||||
if 'artist' in self.contact.tune:
|
|
||||||
artist = self.contact.tune['artist'].strip()
|
|
||||||
artist = gobject.markup_escape_text(artist)
|
|
||||||
if 'title' in self.contact.tune:
|
|
||||||
title = self.contact.tune['title'].strip()
|
|
||||||
title = gobject.markup_escape_text(title)
|
|
||||||
if 'source' in self.contact.tune:
|
|
||||||
source = self.contact.tune['source'].strip()
|
|
||||||
source = gobject.markup_escape_text(source)
|
|
||||||
|
|
||||||
if artist or title:
|
|
||||||
if not artist:
|
|
||||||
artist = _('Unknown Artist')
|
|
||||||
if not title:
|
|
||||||
title = _('Unknown Title')
|
|
||||||
if not source:
|
|
||||||
source = _('Unknown Source')
|
|
||||||
|
|
||||||
self._tune_image.set_tooltip_markup(
|
|
||||||
_('<b>"%(title)s"</b> by <i>%(artist)s</i>\n'
|
|
||||||
'from <i>%(source)s</i>') % {'title': title, 'artist': artist,
|
|
||||||
'source': source})
|
|
||||||
self._tune_image.show()
|
|
||||||
else:
|
|
||||||
self._tune_image.hide()
|
|
||||||
|
|
||||||
def _update_jingle(self, jingle_type):
|
def _update_jingle(self, jingle_type):
|
||||||
if jingle_type not in ('audio', 'video'):
|
if jingle_type not in ('audio', 'video'):
|
||||||
|
|
|
@ -168,9 +168,7 @@ class Connection(ConnectionHandlers):
|
||||||
self.pubsub_supported = False
|
self.pubsub_supported = False
|
||||||
self.pubsub_publish_options_supported = False
|
self.pubsub_publish_options_supported = False
|
||||||
self.pep_supported = False
|
self.pep_supported = False
|
||||||
self.mood = {}
|
self.pep = {}
|
||||||
self.tune = {}
|
|
||||||
self.activity = {}
|
|
||||||
# Do we continue connection when we get roster (send presence,get vcard..)
|
# Do we continue connection when we get roster (send presence,get vcard..)
|
||||||
self.continue_connect_info = None
|
self.continue_connect_info = None
|
||||||
# Do we auto accept insecure connection
|
# Do we auto accept insecure connection
|
||||||
|
|
|
@ -46,11 +46,10 @@ import common.xmpp
|
||||||
|
|
||||||
from common import helpers
|
from common import helpers
|
||||||
from common import gajim
|
from common import gajim
|
||||||
from common import atom
|
|
||||||
from common import pep
|
|
||||||
from common import exceptions
|
from common import exceptions
|
||||||
from common.commands import ConnectionCommands
|
from common.commands import ConnectionCommands
|
||||||
from common.pubsub import ConnectionPubSub
|
from common.pubsub import ConnectionPubSub
|
||||||
|
from common.pep import ConnectionPEP
|
||||||
from common.caps import ConnectionCaps
|
from common.caps import ConnectionCaps
|
||||||
if gajim.HAVE_FARSIGHT:
|
if gajim.HAVE_FARSIGHT:
|
||||||
from common.jingle import ConnectionJingle
|
from common.jingle import ConnectionJingle
|
||||||
|
@ -1453,7 +1452,7 @@ sent a message to.'''
|
||||||
|
|
||||||
return sess
|
return sess
|
||||||
|
|
||||||
class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco, ConnectionCommands, ConnectionPubSub, ConnectionCaps, ConnectionHandlersBase, ConnectionJingle):
|
class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco, ConnectionCommands, ConnectionPubSub, ConnectionPEP, ConnectionCaps, ConnectionHandlersBase, ConnectionJingle):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
ConnectionVcard.__init__(self)
|
ConnectionVcard.__init__(self)
|
||||||
ConnectionBytestream.__init__(self)
|
ConnectionBytestream.__init__(self)
|
||||||
|
@ -1874,15 +1873,7 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco,
|
||||||
def _messageCB(self, con, msg):
|
def _messageCB(self, con, msg):
|
||||||
'''Called when we receive a message'''
|
'''Called when we receive a message'''
|
||||||
log.debug('MessageCB')
|
log.debug('MessageCB')
|
||||||
|
|
||||||
mtype = msg.getType()
|
mtype = msg.getType()
|
||||||
# check if the message is pubsub#event
|
|
||||||
if msg.getTag('event') is not None:
|
|
||||||
if mtype == 'groupchat':
|
|
||||||
return
|
|
||||||
if msg.getTag('error') is None:
|
|
||||||
self._pubsubEventCB(con, msg)
|
|
||||||
return
|
|
||||||
|
|
||||||
# check if the message is a roster item exchange (XEP-0144)
|
# check if the message is a roster item exchange (XEP-0144)
|
||||||
if msg.getTag('x', namespace=common.xmpp.NS_ROSTERX):
|
if msg.getTag('x', namespace=common.xmpp.NS_ROSTERX):
|
||||||
|
@ -2148,42 +2139,6 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco,
|
||||||
self.dispatch('GC_INVITATION',(frm, jid_from, reason, password,
|
self.dispatch('GC_INVITATION',(frm, jid_from, reason, password,
|
||||||
is_continued))
|
is_continued))
|
||||||
|
|
||||||
def _pubsubEventCB(self, con, msg):
|
|
||||||
''' Called when we receive <message/> with pubsub event. '''
|
|
||||||
# TODO: Logging? (actually services where logging would be useful, should
|
|
||||||
# TODO: allow to access archives remotely...)
|
|
||||||
jid = helpers.get_full_jid_from_iq(msg)
|
|
||||||
event = msg.getTag('event')
|
|
||||||
|
|
||||||
# XEP-0107: User Mood
|
|
||||||
items = event.getTag('items', {'node': common.xmpp.NS_MOOD})
|
|
||||||
if items: pep.user_mood(items, self.name, jid)
|
|
||||||
# XEP-0118: User Tune
|
|
||||||
items = event.getTag('items', {'node': common.xmpp.NS_TUNE})
|
|
||||||
if items: pep.user_tune(items, self.name, jid)
|
|
||||||
# XEP-0080: User Geolocation
|
|
||||||
items = event.getTag('items', {'node': common.xmpp.NS_GEOLOC})
|
|
||||||
if items: pep.user_geoloc(items, self.name, jid)
|
|
||||||
# XEP-0108: User Activity
|
|
||||||
items = event.getTag('items', {'node': common.xmpp.NS_ACTIVITY})
|
|
||||||
if items: pep.user_activity(items, self.name, jid)
|
|
||||||
# XEP-0172: User Nickname
|
|
||||||
items = event.getTag('items', {'node': common.xmpp.NS_NICK})
|
|
||||||
if items: pep.user_nickname(items, self.name, jid)
|
|
||||||
|
|
||||||
items = event.getTag('items')
|
|
||||||
if items is None: return
|
|
||||||
|
|
||||||
for item in items.getTags('item'):
|
|
||||||
entry = item.getTag('entry')
|
|
||||||
if entry is not None:
|
|
||||||
# for each entry in feed (there shouldn't be more than one,
|
|
||||||
# but to be sure...
|
|
||||||
self.dispatch('ATOM_ENTRY', (atom.OldEntry(node=entry),))
|
|
||||||
continue
|
|
||||||
# unknown type... probably user has another client who understands that event
|
|
||||||
raise common.xmpp.NodeProcessed
|
|
||||||
|
|
||||||
def _presenceCB(self, con, prs):
|
def _presenceCB(self, con, prs):
|
||||||
'''Called when we receive a presence'''
|
'''Called when we receive a presence'''
|
||||||
ptype = prs.getType()
|
ptype = prs.getType()
|
||||||
|
@ -2751,6 +2706,8 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco,
|
||||||
con.RegisterHandler('message', self._messageCB)
|
con.RegisterHandler('message', self._messageCB)
|
||||||
con.RegisterHandler('presence', self._presenceCB)
|
con.RegisterHandler('presence', self._presenceCB)
|
||||||
con.RegisterHandler('presence', self._capsPresenceCB)
|
con.RegisterHandler('presence', self._capsPresenceCB)
|
||||||
|
con.RegisterHandler('message', self._pubsubEventCB,
|
||||||
|
ns=common.xmpp.NS_PUBSUB_EVENT)
|
||||||
con.RegisterHandler('iq', self._vCardCB, 'result',
|
con.RegisterHandler('iq', self._vCardCB, 'result',
|
||||||
common.xmpp.NS_VCARD)
|
common.xmpp.NS_VCARD)
|
||||||
con.RegisterHandler('iq', self._rosterSetCB, 'set',
|
con.RegisterHandler('iq', self._rosterSetCB, 'set',
|
||||||
|
|
|
@ -94,7 +94,7 @@ class Contact(CommonContact):
|
||||||
def __init__(self, jid, account, name='', groups=[], show='', status='', sub='',
|
def __init__(self, jid, account, name='', groups=[], show='', status='', sub='',
|
||||||
ask='', resource='', priority=0, keyID='', client_caps=None,
|
ask='', resource='', priority=0, keyID='', client_caps=None,
|
||||||
our_chatstate=None, chatstate=None, last_status_time=None, msg_id = None,
|
our_chatstate=None, chatstate=None, last_status_time=None, msg_id = None,
|
||||||
composing_xep=None, mood={}, tune={}, activity={}):
|
composing_xep=None):
|
||||||
|
|
||||||
CommonContact.__init__(self, jid, account, resource, show, status, name,
|
CommonContact.__init__(self, jid, account, resource, show, status, name,
|
||||||
our_chatstate, composing_xep, chatstate, client_caps=client_caps)
|
our_chatstate, composing_xep, chatstate, client_caps=client_caps)
|
||||||
|
@ -110,9 +110,7 @@ class Contact(CommonContact):
|
||||||
self.msg_id = msg_id
|
self.msg_id = msg_id
|
||||||
self.last_status_time = last_status_time
|
self.last_status_time = last_status_time
|
||||||
|
|
||||||
self.mood = mood.copy()
|
self.pep = {}
|
||||||
self.tune = tune.copy()
|
|
||||||
self.activity = activity.copy()
|
|
||||||
|
|
||||||
def get_full_jid(self):
|
def get_full_jid(self):
|
||||||
if self.resource:
|
if self.resource:
|
||||||
|
@ -229,23 +227,25 @@ class Contacts:
|
||||||
def create_contact(self, jid, account, name='', groups=[], show='', status='',
|
def create_contact(self, jid, account, name='', groups=[], show='', status='',
|
||||||
sub='', ask='', resource='', priority=0, keyID='', client_caps=None,
|
sub='', ask='', resource='', priority=0, keyID='', client_caps=None,
|
||||||
our_chatstate=None, chatstate=None, last_status_time=None,
|
our_chatstate=None, chatstate=None, last_status_time=None,
|
||||||
composing_xep=None, mood={}, tune={}, activity={}):
|
composing_xep=None):
|
||||||
account = self._accounts.get(account, account) # Use Account object if available
|
account = self._accounts.get(account, account) # Use Account object if available
|
||||||
return Contact(jid=jid, account=account, name=name, groups=groups,
|
return Contact(jid=jid, account=account, name=name, groups=groups,
|
||||||
show=show, status=status, sub=sub, ask=ask, resource=resource, priority=priority,
|
show=show, status=status, sub=sub, ask=ask, resource=resource, priority=priority,
|
||||||
keyID=keyID, client_caps=client_caps, our_chatstate=our_chatstate,
|
keyID=keyID, client_caps=client_caps, our_chatstate=our_chatstate,
|
||||||
chatstate=chatstate, last_status_time=last_status_time,
|
chatstate=chatstate, last_status_time=last_status_time,
|
||||||
composing_xep=composing_xep, mood=mood, tune=tune, activity=activity)
|
composing_xep=composing_xep)
|
||||||
|
|
||||||
def create_self_contact(self, jid, account, resource, show, status, priority, keyID=''):
|
def create_self_contact(self, jid, account, resource, show, status, priority,
|
||||||
|
name='', keyID=''):
|
||||||
conn = common.gajim.connections[account]
|
conn = common.gajim.connections[account]
|
||||||
nick = common.gajim.nicks[account]
|
nick = name or common.gajim.nicks[account]
|
||||||
account = self._accounts.get(account, account) # Use Account object if available
|
account = self._accounts.get(account, account) # Use Account object if available
|
||||||
return self.create_contact(jid=jid, account=account,
|
self_contact = self.create_contact(jid=jid, account=account,
|
||||||
name=nick, groups=['self_contact'], show=show, status=status,
|
name=nick, groups=['self_contact'], show=show, status=status,
|
||||||
sub='both', ask='none', priority=priority, keyID=keyID,
|
sub='both', ask='none', priority=priority, keyID=keyID,
|
||||||
resource=resource, mood=conn.mood, tune=conn.tune,
|
resource=resource)
|
||||||
activity=conn.activity)
|
self_contact.pep = conn.pep
|
||||||
|
return self_contact
|
||||||
|
|
||||||
def create_not_in_roster_contact(self, jid, account, resource='', name='', keyID=''):
|
def create_not_in_roster_contact(self, jid, account, resource='', name='', keyID=''):
|
||||||
account = self._accounts.get(account, account) # Use Account object if available
|
account = self._accounts.get(account, account) # Use Account object if available
|
||||||
|
|
|
@ -569,8 +569,6 @@ def datetime_tuple(timestamp):
|
||||||
# import gajim only when needed (after decode_string is defined) see #4764
|
# import gajim only when needed (after decode_string is defined) see #4764
|
||||||
|
|
||||||
import gajim
|
import gajim
|
||||||
import pep
|
|
||||||
|
|
||||||
|
|
||||||
def convert_bytes(string):
|
def convert_bytes(string):
|
||||||
suffix = ''
|
suffix = ''
|
||||||
|
@ -777,53 +775,6 @@ def get_global_status():
|
||||||
status = gajim.connections[account].status
|
status = gajim.connections[account].status
|
||||||
return status
|
return status
|
||||||
|
|
||||||
def get_pep_dict(account):
|
|
||||||
pep_dict = {}
|
|
||||||
con = gajim.connections[account]
|
|
||||||
# activity
|
|
||||||
if 'activity' in con.activity and con.activity['activity'] in pep.ACTIVITIES:
|
|
||||||
activity = con.activity['activity']
|
|
||||||
if 'subactivity' in con.activity and con.activity['subactivity'] in \
|
|
||||||
pep.ACTIVITIES[activity]:
|
|
||||||
subactivity = con.activity['subactivity']
|
|
||||||
else:
|
|
||||||
subactivity = 'other'
|
|
||||||
else:
|
|
||||||
activity = ''
|
|
||||||
subactivity = ''
|
|
||||||
if 'text' in con.activity:
|
|
||||||
text = con.activity['text']
|
|
||||||
else:
|
|
||||||
text = ''
|
|
||||||
pep_dict['activity'] = activity
|
|
||||||
pep_dict['subactivity'] = subactivity
|
|
||||||
pep_dict['activity_text'] = text
|
|
||||||
|
|
||||||
# mood
|
|
||||||
if 'mood' in con.mood and con.mood['mood'] in pep.MOODS:
|
|
||||||
mood = con.mood['mood']
|
|
||||||
else:
|
|
||||||
mood = ''
|
|
||||||
if 'text' in con.mood:
|
|
||||||
text = con.mood['text']
|
|
||||||
else:
|
|
||||||
text = ''
|
|
||||||
pep_dict['mood'] = mood
|
|
||||||
pep_dict['mood_text'] = text
|
|
||||||
return pep_dict
|
|
||||||
|
|
||||||
def get_global_pep():
|
|
||||||
maxi = 0
|
|
||||||
pep_dict = {'activity': '', 'mood': ''}
|
|
||||||
for account in gajim.connections:
|
|
||||||
if not gajim.config.get_per('accounts', account,
|
|
||||||
'sync_with_global_status'):
|
|
||||||
continue
|
|
||||||
connected = gajim.connections[account].connected
|
|
||||||
if connected > maxi:
|
|
||||||
maxi = connected
|
|
||||||
pep_dict = get_pep_dict(account)
|
|
||||||
return pep_dict
|
|
||||||
|
|
||||||
def statuses_unified():
|
def statuses_unified():
|
||||||
'''testing if all statuses are the same.'''
|
'''testing if all statuses are the same.'''
|
||||||
|
|
|
@ -192,390 +192,371 @@ ACTIVITIES = {
|
||||||
'studying': _('Studying'),
|
'studying': _('Studying'),
|
||||||
'writing': _('Writing')}}
|
'writing': _('Writing')}}
|
||||||
|
|
||||||
def user_mood(items, name, jid):
|
TUNE_DATA = ['artist', 'title', 'source', 'track', 'length']
|
||||||
has_child = False
|
|
||||||
retract = False
|
|
||||||
mood = None
|
|
||||||
text = None
|
|
||||||
for item in items.getTags('item'):
|
|
||||||
child = item.getTag('mood')
|
|
||||||
if child is not None:
|
|
||||||
has_child = True
|
|
||||||
for ch in child.getChildren():
|
|
||||||
if ch.getName() != 'text':
|
|
||||||
mood = ch.getName()
|
|
||||||
else:
|
|
||||||
text = ch.getData()
|
|
||||||
if items.getTag('retract') is not None:
|
|
||||||
retract = True
|
|
||||||
|
|
||||||
if jid == common.gajim.get_jid_from_account(name):
|
import logging
|
||||||
acc = common.gajim.connections[name]
|
log = logging.getLogger('gajim.c.pep')
|
||||||
if has_child:
|
|
||||||
if 'mood' in acc.mood:
|
|
||||||
del acc.mood['mood']
|
|
||||||
if 'text' in acc.mood:
|
|
||||||
del acc.mood['text']
|
|
||||||
if mood is not None:
|
|
||||||
acc.mood['mood'] = mood
|
|
||||||
if text is not None:
|
|
||||||
acc.mood['text'] = text
|
|
||||||
elif retract:
|
|
||||||
if 'mood' in acc.mood:
|
|
||||||
del acc.mood['mood']
|
|
||||||
if 'text' in acc.mood:
|
|
||||||
del acc.mood['text']
|
|
||||||
|
|
||||||
(user, resource) = common.gajim.get_room_and_nick_from_fjid(jid)
|
import helpers
|
||||||
for contact in common.gajim.contacts.get_contacts(name, user):
|
import atom
|
||||||
if has_child:
|
import gtkgui_helpers
|
||||||
if 'mood' in contact.mood:
|
import gobject
|
||||||
del contact.mood['mood']
|
import gajim
|
||||||
if 'text' in contact.mood:
|
import gtk
|
||||||
del contact.mood['text']
|
|
||||||
if mood is not None:
|
|
||||||
contact.mood['mood'] = mood
|
|
||||||
if text is not None:
|
|
||||||
contact.mood['text'] = text
|
|
||||||
elif retract:
|
|
||||||
if 'mood' in contact.mood:
|
|
||||||
del contact.mood['mood']
|
|
||||||
if 'text' in contact.mood:
|
|
||||||
del contact.mood['text']
|
|
||||||
|
|
||||||
if jid == common.gajim.get_jid_from_account(name):
|
|
||||||
common.gajim.interface.roster.draw_account(name)
|
|
||||||
common.gajim.interface.roster.draw_mood(user, name)
|
|
||||||
ctrl = common.gajim.interface.msg_win_mgr.get_control(user, name)
|
|
||||||
if ctrl:
|
|
||||||
ctrl.update_mood()
|
|
||||||
|
|
||||||
def user_tune(items, name, jid):
|
def translate_mood(mood):
|
||||||
has_child = False
|
if mood in MOODS:
|
||||||
retract = False
|
return MOODS[mood]
|
||||||
artist = None
|
else:
|
||||||
title = None
|
return mood
|
||||||
source = None
|
|
||||||
track = None
|
|
||||||
length = None
|
|
||||||
|
|
||||||
for item in items.getTags('item'):
|
|
||||||
child = item.getTag('tune')
|
|
||||||
if child is not None:
|
|
||||||
has_child = True
|
|
||||||
for ch in child.getChildren():
|
|
||||||
if ch.getName() == 'artist':
|
|
||||||
artist = ch.getData()
|
|
||||||
elif ch.getName() == 'title':
|
|
||||||
title = ch.getData()
|
|
||||||
elif ch.getName() == 'source':
|
|
||||||
source = ch.getData()
|
|
||||||
elif ch.getName() == 'track':
|
|
||||||
track = ch.getData()
|
|
||||||
elif ch.getName() == 'length':
|
|
||||||
length = ch.getData()
|
|
||||||
if items.getTag('retract') is not None:
|
|
||||||
retract = True
|
|
||||||
|
|
||||||
if jid == common.gajim.get_jid_from_account(name):
|
class AbstractPEP(object):
|
||||||
acc = common.gajim.connections[name]
|
|
||||||
if has_child:
|
type = ''
|
||||||
if 'artist' in acc.tune:
|
namespace = ''
|
||||||
del acc.tune['artist']
|
|
||||||
if 'title' in acc.tune:
|
@classmethod
|
||||||
del acc.tune['title']
|
def get_tag_as_PEP(cls, jid, account, event_tag):
|
||||||
if 'source' in acc.tune:
|
items = event_tag.getTag('items', {'node': cls.namespace})
|
||||||
del acc.tune['source']
|
if items:
|
||||||
if 'track' in acc.tune:
|
log.debug("Received PEP 'user %s' from %s" % (cls.type, jid))
|
||||||
del acc.tune['track']
|
return cls(jid, account, items)
|
||||||
if 'length' in acc.tune:
|
else:
|
||||||
del acc.tune['length']
|
return None
|
||||||
if artist is not None:
|
|
||||||
acc.tune['artist'] = artist
|
def __init__(self, jid, account, items):
|
||||||
if title is not None:
|
self._pep_specific_data, self._retracted = self._extract_info(items)
|
||||||
acc.tune['title'] = title
|
|
||||||
if source is not None:
|
self._update_contacts(jid, account)
|
||||||
acc.tune['source'] = source
|
if jid == common.gajim.get_jid_from_account(account):
|
||||||
if track is not None:
|
self._update_account(account)
|
||||||
acc.tune['track'] = track
|
|
||||||
if length is not None:
|
def _extract_info(self, items):
|
||||||
acc.tune['length'] = length
|
'''To be implemented by subclasses'''
|
||||||
elif retract:
|
raise NotImplementedError
|
||||||
if 'artist' in acc.tune:
|
|
||||||
del acc.tune['artist']
|
def _update_contacts(self, jid, account):
|
||||||
if 'title' in acc.tune:
|
for contact in common.gajim.contacts.get_contacts(account, jid):
|
||||||
del acc.tune['title']
|
if self._retracted:
|
||||||
if 'source' in acc.tune:
|
if self.type in contact.pep:
|
||||||
del acc.tune['source']
|
del contact.pep[self.type]
|
||||||
if 'track' in acc.tune:
|
else:
|
||||||
del acc.tune['track']
|
contact.pep[self.type] = self
|
||||||
if 'length' in acc.tune:
|
|
||||||
del acc.tune['length']
|
def _update_account(self, account):
|
||||||
|
acc = common.gajim.connections[account]
|
||||||
|
if self._retracted:
|
||||||
|
if self.type in acc.pep:
|
||||||
|
del acc.pep[self.type]
|
||||||
|
else:
|
||||||
|
acc.pep[self.type] = self
|
||||||
|
|
||||||
|
def asPixbufIcon(self):
|
||||||
|
'''To be implemented by subclasses'''
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def asMarkupText(self):
|
||||||
|
'''To be implemented by subclasses'''
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
|
class UserMoodPEP(AbstractPEP):
|
||||||
|
'''XEP-0107: User Mood'''
|
||||||
|
|
||||||
|
type = 'mood'
|
||||||
|
namespace = common.xmpp.NS_MOOD
|
||||||
|
|
||||||
|
def _extract_info(self, items):
|
||||||
|
mood_dict = {}
|
||||||
|
|
||||||
|
for item in items.getTags('item'):
|
||||||
|
mood_tag = item.getTag('mood')
|
||||||
|
if mood_tag:
|
||||||
|
for child in mood_tag.getChildren():
|
||||||
|
name = child.getName().strip()
|
||||||
|
if name == 'text':
|
||||||
|
mood_dict['text'] = child.getData()
|
||||||
|
else:
|
||||||
|
mood_dict['mood'] = name
|
||||||
|
|
||||||
|
retracted = items.getTag('retract') or not 'mood' in mood_dict
|
||||||
|
return (mood_dict, retracted)
|
||||||
|
|
||||||
|
def asPixbufIcon(self):
|
||||||
|
assert not self._retracted
|
||||||
|
received_mood = self._pep_specific_data['mood']
|
||||||
|
mood = received_mood if received_mood in MOODS else 'unknown'
|
||||||
|
pixbuf = gtkgui_helpers.load_mood_icon(mood).get_pixbuf()
|
||||||
|
return pixbuf
|
||||||
|
|
||||||
|
def asMarkupText(self):
|
||||||
|
assert not self._retracted
|
||||||
|
untranslated_mood = self._pep_specific_data['mood']
|
||||||
|
mood = translate_mood(untranslated_mood)
|
||||||
|
markuptext = '<b>%s</b>' % gobject.markup_escape_text(mood)
|
||||||
|
if 'text' in self._pep_specific_data:
|
||||||
|
text = self._pep_specific_data['text']
|
||||||
|
markuptext += ' (%s)' % gobject.markup_escape_text(text)
|
||||||
|
return markuptext
|
||||||
|
|
||||||
user = common.gajim.get_room_and_nick_from_fjid(jid)[0]
|
|
||||||
for contact in common.gajim.contacts.get_contacts(name, user):
|
|
||||||
if has_child:
|
|
||||||
if 'artist' in contact.tune:
|
|
||||||
del contact.tune['artist']
|
|
||||||
if 'title' in contact.tune:
|
|
||||||
del contact.tune['title']
|
|
||||||
if 'source' in contact.tune:
|
|
||||||
del contact.tune['source']
|
|
||||||
if 'track' in contact.tune:
|
|
||||||
del contact.tune['track']
|
|
||||||
if 'length' in contact.tune:
|
|
||||||
del contact.tune['length']
|
|
||||||
if artist is not None:
|
|
||||||
contact.tune['artist'] = artist
|
|
||||||
if title is not None:
|
|
||||||
contact.tune['title'] = title
|
|
||||||
if source is not None:
|
|
||||||
contact.tune['source'] = source
|
|
||||||
if track is not None:
|
|
||||||
contact.tune['track'] = track
|
|
||||||
if length is not None:
|
|
||||||
contact.tune['length'] = length
|
|
||||||
elif retract:
|
|
||||||
if 'artist' in contact.tune:
|
|
||||||
del contact.tune['artist']
|
|
||||||
if 'title' in contact.tune:
|
|
||||||
del contact.tune['title']
|
|
||||||
if 'source' in contact.tune:
|
|
||||||
del contact.tune['source']
|
|
||||||
if 'track' in contact.tune:
|
|
||||||
del contact.tune['track']
|
|
||||||
if 'length' in contact.tune:
|
|
||||||
del contact.tune['length']
|
|
||||||
|
|
||||||
if jid == common.gajim.get_jid_from_account(name):
|
class UserTunePEP(AbstractPEP):
|
||||||
common.gajim.interface.roster.draw_account(name)
|
'''XEP-0118: User Tune'''
|
||||||
common.gajim.interface.roster.draw_tune(user, name)
|
|
||||||
ctrl = common.gajim.interface.msg_win_mgr.get_control(user, name)
|
type = 'tune'
|
||||||
if ctrl:
|
namespace = common.xmpp.NS_TUNE
|
||||||
ctrl.update_tune()
|
|
||||||
|
def _extract_info(self, items):
|
||||||
|
tune_dict = {}
|
||||||
|
|
||||||
|
for item in items.getTags('item'):
|
||||||
|
tune_tag = item.getTag('tune')
|
||||||
|
if tune_tag:
|
||||||
|
for child in tune_tag.getChildren():
|
||||||
|
name = child.getName().strip()
|
||||||
|
data = child.getData().strip()
|
||||||
|
if child.getName() in TUNE_DATA:
|
||||||
|
tune_dict[name] = data
|
||||||
|
|
||||||
|
retracted = items.getTag('retract') or not ('artist' in tune_dict or
|
||||||
|
'title' in tune_dict)
|
||||||
|
return (tune_dict, retracted)
|
||||||
|
|
||||||
|
def asPixbufIcon(self):
|
||||||
|
import os
|
||||||
|
path = os.path.join(gajim.DATA_DIR, 'emoticons', 'static', 'music.png')
|
||||||
|
return gtk.gdk.pixbuf_new_from_file(path)
|
||||||
|
|
||||||
|
def asMarkupText(self):
|
||||||
|
assert not self._retracted
|
||||||
|
tune = self._pep_specific_data
|
||||||
|
|
||||||
def user_geoloc(items, name, jid):
|
artist = tune.get('artist', _('Unknown Artist'))
|
||||||
pass
|
artist = gobject.markup_escape_text(artist)
|
||||||
|
|
||||||
|
title = tune.get('title', _('Unknown Title'))
|
||||||
|
title = gobject.markup_escape_text(title)
|
||||||
|
|
||||||
def user_activity(items, name, jid):
|
source = tune.get('source', _('Unknown Source'))
|
||||||
has_child = False
|
source = gobject.markup_escape_text(source)
|
||||||
retract = False
|
|
||||||
activity = None
|
|
||||||
subactivity = None
|
|
||||||
text = None
|
|
||||||
|
|
||||||
for item in items.getTags('item'):
|
tune_string = _('<b>"%(title)s"</b> by <i>%(artist)s</i>\n'
|
||||||
child = item.getTag('activity')
|
'from <i>%(source)s</i>') % {'title': title,
|
||||||
if child is not None:
|
'artist': artist, 'source': source}
|
||||||
has_child = True
|
return tune_string
|
||||||
for ch in child.getChildren():
|
|
||||||
if ch.getName() != 'text':
|
|
||||||
activity = ch.getName()
|
|
||||||
for chi in ch.getChildren():
|
|
||||||
subactivity = chi.getName()
|
|
||||||
else:
|
|
||||||
text = ch.getData()
|
|
||||||
if items.getTag('retract') is not None:
|
|
||||||
retract = True
|
|
||||||
|
|
||||||
if jid == common.gajim.get_jid_from_account(name):
|
class UserActivityPEP(AbstractPEP):
|
||||||
acc = common.gajim.connections[name]
|
'''XEP-0108: User Activity'''
|
||||||
if has_child:
|
|
||||||
if 'activity' in acc.activity:
|
type = 'activity'
|
||||||
del acc.activity['activity']
|
namespace = common.xmpp.NS_ACTIVITY
|
||||||
if 'subactivity' in acc.activity:
|
|
||||||
del acc.activity['subactivity']
|
def _extract_info(self, items):
|
||||||
if 'text' in acc.activity:
|
activity_dict = {}
|
||||||
del acc.activity['text']
|
|
||||||
if activity is not None:
|
for item in items.getTags('item'):
|
||||||
acc.activity['activity'] = activity
|
activity_tag = item.getTag('activity')
|
||||||
if subactivity is not None and subactivity != 'other':
|
if activity_tag:
|
||||||
acc.activity['subactivity'] = subactivity
|
for child in activity_tag.getChildren():
|
||||||
if text is not None:
|
name = child.getName().strip()
|
||||||
acc.activity['text'] = text
|
data = child.getData().strip()
|
||||||
elif retract:
|
if name == 'text':
|
||||||
if 'activity' in acc.activity:
|
activity_dict['text'] = data
|
||||||
del acc.activity['activity']
|
else:
|
||||||
if 'subactivity' in acc.activity:
|
activity_dict['activity'] = name
|
||||||
del acc.activity['subactivity']
|
for subactivity in child.getChildren():
|
||||||
if 'text' in acc.activity:
|
subactivity_name = subactivity.getName().strip()
|
||||||
del acc.activity['text']
|
activity_dict['subactivity'] = subactivity_name
|
||||||
|
|
||||||
|
retracted = items.getTag('retract') or not 'activity' in activity_dict
|
||||||
|
return (activity_dict, retracted)
|
||||||
|
|
||||||
|
def asPixbufIcon(self):
|
||||||
|
assert not self._retracted
|
||||||
|
pep = self._pep_specific_data
|
||||||
|
activity = pep['activity']
|
||||||
|
|
||||||
|
has_known_activity = activity in ACTIVITIES
|
||||||
|
has_known_subactivity = (has_known_activity and ('subactivity' in pep)
|
||||||
|
and (pep['subactivity'] in ACTIVITIES[activity]))
|
||||||
|
|
||||||
|
if has_known_activity:
|
||||||
|
if has_known_subactivity:
|
||||||
|
subactivity = pep['subactivity']
|
||||||
|
return gtkgui_helpers.load_activity_icon(activity, subactivity).get_pixbuf()
|
||||||
|
else:
|
||||||
|
return gtkgui_helpers.load_activity_icon(activity).get_pixbuf()
|
||||||
|
else:
|
||||||
|
return gtkgui_helpers.load_activity_icon('unknown').get_pixbuf()
|
||||||
|
|
||||||
|
def asMarkupText(self):
|
||||||
|
assert not self._retracted
|
||||||
|
pep = self._pep_specific_data
|
||||||
|
activity = pep['activity']
|
||||||
|
subactivity = pep['subactivity'] if 'subactivity' in pep else None
|
||||||
|
text = pep['text'] if 'text' in pep else None
|
||||||
|
|
||||||
user = common.gajim.get_room_and_nick_from_fjid(jid)[0]
|
if activity in ACTIVITIES:
|
||||||
for contact in common.gajim.contacts.get_contacts(name, user):
|
# Translate standard activities
|
||||||
if has_child:
|
if subactivity in ACTIVITIES[activity]:
|
||||||
if 'activity' in contact.activity:
|
subactivity = ACTIVITIES[activity][subactivity]
|
||||||
del contact.activity['activity']
|
activity = ACTIVITIES[activity]['category']
|
||||||
if 'subactivity' in contact.activity:
|
|
||||||
del contact.activity['subactivity']
|
markuptext = '<b>' + gobject.markup_escape_text(activity)
|
||||||
if 'text' in contact.activity:
|
if subactivity:
|
||||||
del contact.activity['text']
|
markuptext += ': ' + gobject.markup_escape_text(subactivity)
|
||||||
if activity is not None:
|
markuptext += '</b>'
|
||||||
contact.activity['activity'] = activity
|
if text:
|
||||||
if subactivity is not None and subactivity != 'other':
|
markuptext += ' (%s)' % gobject.markup_escape_text(text)
|
||||||
contact.activity['subactivity'] = subactivity
|
return markuptext
|
||||||
if text is not None:
|
|
||||||
contact.activity['text'] = text
|
|
||||||
elif retract:
|
class UserNicknamePEP(AbstractPEP):
|
||||||
if 'activity' in contact.activity:
|
'''XEP-0172: User Nickname'''
|
||||||
del contact.activity['activity']
|
|
||||||
if 'subactivity' in contact.activity:
|
type = 'nickname'
|
||||||
del contact.activity['subactivity']
|
namespace = common.xmpp.NS_NICK
|
||||||
if 'text' in contact.activity:
|
|
||||||
del contact.activity['text']
|
def _extract_info(self, items):
|
||||||
|
nick = ''
|
||||||
|
for item in items.getTags('item'):
|
||||||
|
child = item.getTag('nick')
|
||||||
|
if child:
|
||||||
|
nick = child.getData()
|
||||||
|
break
|
||||||
|
|
||||||
|
retracted = items.getTag('retract') or not nick
|
||||||
|
return (nick, retracted)
|
||||||
|
|
||||||
|
def _update_contacts(self, jid, account):
|
||||||
|
# TODO: use dict instead
|
||||||
|
nick = '' if self._retracted else self._pep_specific_data
|
||||||
|
for contact in common.gajim.contacts.get_contacts(account, jid):
|
||||||
|
contact.contact_name = nick
|
||||||
|
|
||||||
|
def _update_account(self, account):
|
||||||
|
# TODO: use dict instead
|
||||||
|
if self._retracted:
|
||||||
|
common.gajim.nicks[account] = common.gajim.config.get_per('accounts',
|
||||||
|
account, 'name')
|
||||||
|
else:
|
||||||
|
common.gajim.nicks[account] = self._pep_specific_data
|
||||||
|
|
||||||
if jid == common.gajim.get_jid_from_account(name):
|
|
||||||
common.gajim.interface.roster.draw_account(name)
|
SUPPORTED_PERSONAL_USER_EVENTS = [UserMoodPEP, UserTunePEP, UserActivityPEP,
|
||||||
common.gajim.interface.roster.draw_activity(user, name)
|
UserNicknamePEP]
|
||||||
ctrl = common.gajim.interface.msg_win_mgr.get_control(user, name)
|
|
||||||
if ctrl:
|
|
||||||
ctrl.update_activity()
|
|
||||||
|
|
||||||
def user_nickname(items, name, jid):
|
class ConnectionPEP(object):
|
||||||
has_child = False
|
|
||||||
retract = False
|
def _pubsubEventCB(self, xmpp_dispatcher, msg):
|
||||||
nick = None
|
''' Called when we receive <message /> with pubsub event. '''
|
||||||
|
if msg.getTag('error'):
|
||||||
|
log.warning('PubsubEventCB received error stanza')
|
||||||
|
return
|
||||||
|
|
||||||
|
jid = helpers.get_full_jid_from_iq(msg)
|
||||||
|
event_tag = msg.getTag('event')
|
||||||
|
|
||||||
for item in items.getTags('item'):
|
for pep_class in SUPPORTED_PERSONAL_USER_EVENTS:
|
||||||
child = item.getTag('nick')
|
pep = pep_class.get_tag_as_PEP(jid, self.name, event_tag)
|
||||||
if child is not None:
|
if pep:
|
||||||
has_child = True
|
self.dispatch('PEP_RECEIVED', (jid, pep.type))
|
||||||
nick = child.getData()
|
|
||||||
break
|
items = event_tag.getTag('items')
|
||||||
|
if items:
|
||||||
|
for item in items.getTags('item'):
|
||||||
|
entry = item.getTag('entry')
|
||||||
|
if entry:
|
||||||
|
# for each entry in feed (there shouldn't be more than one,
|
||||||
|
# but to be sure...
|
||||||
|
self.dispatch('ATOM_ENTRY', (atom.OldEntry(node=entry),))
|
||||||
|
|
||||||
|
raise common.xmpp.NodeProcessed
|
||||||
|
|
||||||
|
def send_activity(self, activity, subactivity=None, message=None):
|
||||||
|
if not self.pep_supported:
|
||||||
|
return
|
||||||
|
item = xmpp.Node('activity', {'xmlns': xmpp.NS_ACTIVITY})
|
||||||
|
if activity:
|
||||||
|
i = item.addChild(activity)
|
||||||
|
if subactivity:
|
||||||
|
i.addChild(subactivity)
|
||||||
|
if message:
|
||||||
|
i = item.addChild('text')
|
||||||
|
i.addData(message)
|
||||||
|
self.send_pb_publish('', xmpp.NS_ACTIVITY, item, '0')
|
||||||
|
|
||||||
|
def retract_activity(self):
|
||||||
|
if not self.pep_supported:
|
||||||
|
return
|
||||||
|
# not all server support retract, so send empty pep first
|
||||||
|
self.send_activity(None)
|
||||||
|
self.send_pb_retract('', xmpp.NS_ACTIVITY, '0')
|
||||||
|
|
||||||
if items.getTag('retract') is not None:
|
def send_mood(self, mood, message=None):
|
||||||
retract = True
|
if not self.pep_supported:
|
||||||
|
return
|
||||||
|
item = xmpp.Node('mood', {'xmlns': xmpp.NS_MOOD})
|
||||||
|
if mood:
|
||||||
|
item.addChild(mood)
|
||||||
|
if message:
|
||||||
|
i = item.addChild('text')
|
||||||
|
i.addData(message)
|
||||||
|
self.send_pb_publish('', xmpp.NS_MOOD, item, '0')
|
||||||
|
|
||||||
|
def retract_mood(self):
|
||||||
|
if not self.pep_supported:
|
||||||
|
return
|
||||||
|
self.send_mood(None)
|
||||||
|
self.send_pb_retract('', xmpp.NS_MOOD, '0')
|
||||||
|
|
||||||
|
def send_tune(self, artist='', title='', source='', track=0, length=0,
|
||||||
|
items=None):
|
||||||
|
if not self.pep_supported:
|
||||||
|
return
|
||||||
|
item = xmpp.Node('tune', {'xmlns': xmpp.NS_TUNE})
|
||||||
|
if artist:
|
||||||
|
i = item.addChild('artist')
|
||||||
|
i.addData(artist)
|
||||||
|
if title:
|
||||||
|
i = item.addChild('title')
|
||||||
|
i.addData(title)
|
||||||
|
if source:
|
||||||
|
i = item.addChild('source')
|
||||||
|
i.addData(source)
|
||||||
|
if track:
|
||||||
|
i = item.addChild('track')
|
||||||
|
i.addData(track)
|
||||||
|
if length:
|
||||||
|
i = item.addChild('length')
|
||||||
|
i.addData(length)
|
||||||
|
if items:
|
||||||
|
item.addChild(payload=items)
|
||||||
|
self.send_pb_publish('', xmpp.NS_TUNE, item, '0')
|
||||||
|
|
||||||
if jid == common.gajim.get_jid_from_account(name):
|
def retract_tune(self):
|
||||||
if has_child:
|
if not self.pep_supported:
|
||||||
common.gajim.nicks[name] = nick
|
return
|
||||||
if retract:
|
# not all server support retract, so send empty pep first
|
||||||
common.gajim.nicks[name] = common.gajim.config.get_per('accounts',
|
self.send_tune(None)
|
||||||
name, 'name')
|
self.send_pb_retract('', xmpp.NS_TUNE, '0')
|
||||||
|
|
||||||
user = common.gajim.get_room_and_nick_from_fjid(jid)[0]
|
def send_nickname(self, nick):
|
||||||
if has_child:
|
if not self.pep_supported:
|
||||||
if nick is not None:
|
return
|
||||||
for contact in common.gajim.contacts.get_contacts(name, user):
|
item = xmpp.Node('nick', {'xmlns': xmpp.NS_NICK})
|
||||||
contact.contact_name = nick
|
item.addData(nick)
|
||||||
common.gajim.interface.roster.draw_contact(user, name)
|
self.send_pb_publish('', xmpp.NS_NICK, item, '0')
|
||||||
|
|
||||||
ctrl = common.gajim.interface.msg_win_mgr.get_control(user, name)
|
def retract_nickname(self):
|
||||||
if ctrl:
|
if not self.pep_supported:
|
||||||
ctrl.update_ui()
|
return
|
||||||
win = ctrl.parent_win
|
# not all server support retract, so send empty pep first
|
||||||
win.redraw_tab(ctrl)
|
self.send_tune(None)
|
||||||
win.show_title()
|
self.send_pb_retract('', xmpp.NS_NICK, '0')
|
||||||
elif retract:
|
|
||||||
contact.contact_name = ''
|
|
||||||
|
|
||||||
def user_send_mood(account, mood, message=''):
|
|
||||||
if not common.gajim.connections[account].pep_supported:
|
|
||||||
return
|
|
||||||
item = xmpp.Node('mood', {'xmlns': xmpp.NS_MOOD})
|
|
||||||
if mood != '':
|
|
||||||
item.addChild(mood)
|
|
||||||
if message != '':
|
|
||||||
i = item.addChild('text')
|
|
||||||
i.addData(message)
|
|
||||||
|
|
||||||
common.gajim.connections[account].send_pb_publish('', xmpp.NS_MOOD, item,
|
|
||||||
'0')
|
|
||||||
|
|
||||||
def user_send_activity(account, activity, subactivity='', message=''):
|
|
||||||
if not common.gajim.connections[account].pep_supported:
|
|
||||||
return
|
|
||||||
item = xmpp.Node('activity', {'xmlns': xmpp.NS_ACTIVITY})
|
|
||||||
if activity != '':
|
|
||||||
i = item.addChild(activity)
|
|
||||||
if subactivity != '':
|
|
||||||
i.addChild(subactivity)
|
|
||||||
if message != '':
|
|
||||||
i = item.addChild('text')
|
|
||||||
i.addData(message)
|
|
||||||
|
|
||||||
common.gajim.connections[account].send_pb_publish('', xmpp.NS_ACTIVITY, item,
|
|
||||||
'0')
|
|
||||||
|
|
||||||
def user_send_tune(account, artist='', title='', source='', track=0, length=0,
|
|
||||||
items=None):
|
|
||||||
if not (common.gajim.config.get_per('accounts', account, 'publish_tune') and\
|
|
||||||
common.gajim.connections[account].pep_supported):
|
|
||||||
return
|
|
||||||
item = xmpp.Node('tune', {'xmlns': xmpp.NS_TUNE})
|
|
||||||
if artist != '':
|
|
||||||
i = item.addChild('artist')
|
|
||||||
i.addData(artist)
|
|
||||||
if title != '':
|
|
||||||
i = item.addChild('title')
|
|
||||||
i.addData(title)
|
|
||||||
if source != '':
|
|
||||||
i = item.addChild('source')
|
|
||||||
i.addData(source)
|
|
||||||
if track != 0:
|
|
||||||
i = item.addChild('track')
|
|
||||||
i.addData(track)
|
|
||||||
if length != 0:
|
|
||||||
i = item.addChild('length')
|
|
||||||
i.addData(length)
|
|
||||||
if items is not None:
|
|
||||||
item.addChild(payload=items)
|
|
||||||
|
|
||||||
common.gajim.connections[account].send_pb_publish('', xmpp.NS_TUNE, item,
|
|
||||||
'0')
|
|
||||||
|
|
||||||
def user_send_nickname(account, nick):
|
|
||||||
if not common.gajim.connections[account].pep_supported:
|
|
||||||
return
|
|
||||||
item = xmpp.Node('nick', {'xmlns': xmpp.NS_NICK})
|
|
||||||
item.addData(nick)
|
|
||||||
|
|
||||||
common.gajim.connections[account].send_pb_publish('', xmpp.NS_NICK, item,
|
|
||||||
'0')
|
|
||||||
|
|
||||||
def user_retract_mood(account):
|
|
||||||
common.gajim.connections[account].send_pb_retract('', xmpp.NS_MOOD, '0')
|
|
||||||
|
|
||||||
def user_retract_activity(account):
|
|
||||||
common.gajim.connections[account].send_pb_retract('', xmpp.NS_ACTIVITY, '0')
|
|
||||||
|
|
||||||
def user_retract_tune(account):
|
|
||||||
common.gajim.connections[account].send_pb_retract('', xmpp.NS_TUNE, '0')
|
|
||||||
|
|
||||||
def user_retract_nickname(account):
|
|
||||||
common.gajim.connections[account].send_pb_retract('', xmpp.NS_NICK, '0')
|
|
||||||
|
|
||||||
def delete_pep(jid, name):
|
|
||||||
user = common.gajim.get_room_and_nick_from_fjid(jid)[0]
|
|
||||||
|
|
||||||
if jid == common.gajim.get_jid_from_account(name):
|
|
||||||
acc = common.gajim.connections[name]
|
|
||||||
del acc.activity
|
|
||||||
acc.activity = {}
|
|
||||||
user_send_tune(name)
|
|
||||||
del acc.tune
|
|
||||||
acc.tune = {}
|
|
||||||
del acc.mood
|
|
||||||
acc.mood = {}
|
|
||||||
|
|
||||||
for contact in common.gajim.contacts.get_contacts(name, user):
|
|
||||||
del contact.activity
|
|
||||||
contact.activity = {}
|
|
||||||
del contact.tune
|
|
||||||
contact.tune = {}
|
|
||||||
del contact.mood
|
|
||||||
contact.mood = {}
|
|
||||||
|
|
||||||
if jid == common.gajim.get_jid_from_account(name):
|
|
||||||
common.gajim.interface.roster.draw_account(name)
|
|
||||||
|
|
||||||
common.gajim.interface.roster.draw_activity(user, name)
|
|
||||||
common.gajim.interface.roster.draw_tune(user, name)
|
|
||||||
common.gajim.interface.roster.draw_mood(user, name)
|
|
||||||
ctrl = common.gajim.interface.msg_win_mgr.get_control(user, name)
|
|
||||||
if ctrl:
|
|
||||||
ctrl.update_activity()
|
|
||||||
ctrl.update_tune()
|
|
||||||
ctrl.update_mood()
|
|
||||||
|
|
||||||
# vim: se ts=3:
|
# vim: se ts=3:
|
||||||
|
|
|
@ -247,25 +247,23 @@ class XMPPDispatcher(PlugIn):
|
||||||
'''
|
'''
|
||||||
Register user callback as stanzas handler of declared type.
|
Register user callback as stanzas handler of declared type.
|
||||||
|
|
||||||
Callback must take (if chained, see later) arguments:
|
Callback arguments:
|
||||||
dispatcher instance (for replying), incoming return of previous handlers.
|
dispatcher instance (for replying), incoming return of previous handlers.
|
||||||
The callback must raise xmpp.NodeProcessed just before return if it wants
|
The callback must raise xmpp.NodeProcessed just before return if it wants
|
||||||
other callbacks to be called with the same stanza as argument _and_, more
|
to prevent other callbacks to be called with the same stanza as argument
|
||||||
importantly library from returning stanza to sender with error set.
|
_and_, more importantly library from returning stanza to sender with error set.
|
||||||
|
|
||||||
:param name: name of stanza. F.e. "iq".
|
:param name: name of stanza. F.e. "iq".
|
||||||
:param handler: user callback.
|
:param handler: user callback.
|
||||||
:param typ: value of stanza's "type" attribute. If not specified any
|
:param typ: value of stanza's "type" attribute. If not specified any
|
||||||
value will match
|
value will match
|
||||||
:param ns: namespace of child that stanza must contain.
|
:param ns: namespace of child that stanza must contain.
|
||||||
:param chained: chain together output of several handlers.
|
:param makefirst: insert handler in the beginning of handlers list instead
|
||||||
:param makefirst: insert handler in the beginning of handlers list instea
|
|
||||||
of adding it to the end. Note that more common handlers i.e. w/o "typ"
|
of adding it to the end. Note that more common handlers i.e. w/o "typ"
|
||||||
and " will be called first nevertheless.
|
and " will be called first nevertheless.
|
||||||
:param system: call handler even if NodeProcessed Exception were raised
|
:param system: call handler even if NodeProcessed Exception were raised
|
||||||
already.
|
already.
|
||||||
'''
|
'''
|
||||||
# FIXME: What does chain mean and where is it handled?
|
|
||||||
if not xmlns:
|
if not xmlns:
|
||||||
xmlns=self._owner.defaultNamespace
|
xmlns=self._owner.defaultNamespace
|
||||||
log.debug('Registering handler %s for "%s" type->%s ns->%s(%s)' %
|
log.debug('Registering handler %s for "%s" type->%s ns->%s(%s)' %
|
||||||
|
|
|
@ -88,6 +88,7 @@ NS_PRIVACY ='jabber:iq:privacy'
|
||||||
NS_PRIVATE ='jabber:iq:private'
|
NS_PRIVATE ='jabber:iq:private'
|
||||||
NS_PROFILE ='http://jabber.org/protocol/profile' # XEP-0154
|
NS_PROFILE ='http://jabber.org/protocol/profile' # XEP-0154
|
||||||
NS_PUBSUB ='http://jabber.org/protocol/pubsub' # XEP-0060
|
NS_PUBSUB ='http://jabber.org/protocol/pubsub' # XEP-0060
|
||||||
|
NS_PUBSUB_EVENT = 'http://jabber.org/protocol/pubsub#event'
|
||||||
NS_PUBSUB_PUBLISH_OPTIONS = NS_PUBSUB + '#publish-options' # XEP-0060
|
NS_PUBSUB_PUBLISH_OPTIONS = NS_PUBSUB + '#publish-options' # XEP-0060
|
||||||
NS_PUBSUB_OWNER ='http://jabber.org/protocol/pubsub#owner' # JEP-0060
|
NS_PUBSUB_OWNER ='http://jabber.org/protocol/pubsub#owner' # JEP-0060
|
||||||
NS_REGISTER ='jabber:iq:register'
|
NS_REGISTER ='jabber:iq:register'
|
||||||
|
|
|
@ -88,9 +88,7 @@ class ConnectionZeroconf(ConnectionHandlersZeroconf):
|
||||||
self.no_log_for = False
|
self.no_log_for = False
|
||||||
|
|
||||||
self.pep_supported = False
|
self.pep_supported = False
|
||||||
self.mood = {}
|
self.pep = {}
|
||||||
self.tune = {}
|
|
||||||
self.activity = {}
|
|
||||||
# Do we continue connection when we get roster (send presence,get vcard...)
|
# Do we continue connection when we get roster (send presence,get vcard...)
|
||||||
self.continue_connect_info = None
|
self.continue_connect_info = None
|
||||||
if gajim.HAVE_GPG:
|
if gajim.HAVE_GPG:
|
||||||
|
|
|
@ -1989,6 +1989,27 @@ class Interface:
|
||||||
_('PEP node %(node)s was not removed: %(message)s') % {
|
_('PEP node %(node)s was not removed: %(message)s') % {
|
||||||
'node': data[1], 'message': data[2]})
|
'node': data[1], 'message': data[2]})
|
||||||
|
|
||||||
|
def handle_event_pep_received(self, account, data):
|
||||||
|
# ('PEP_RECEIVED', account, (jid, pep_type))
|
||||||
|
jid = data[0]
|
||||||
|
pep_type = data[1]
|
||||||
|
ctrl = common.gajim.interface.msg_win_mgr.get_control(jid, account)
|
||||||
|
|
||||||
|
if jid == common.gajim.get_jid_from_account(account):
|
||||||
|
self.roster.draw_account(account)
|
||||||
|
|
||||||
|
if pep_type == 'nickname':
|
||||||
|
self.roster.draw_contact(jid, account)
|
||||||
|
if ctrl:
|
||||||
|
ctrl.update_ui()
|
||||||
|
win = ctrl.parent_win
|
||||||
|
win.redraw_tab(ctrl)
|
||||||
|
win.show_title()
|
||||||
|
else:
|
||||||
|
self.roster.draw_pep(jid, account, pep_type)
|
||||||
|
if ctrl:
|
||||||
|
ctrl.update_pep(pep_type)
|
||||||
|
|
||||||
def register_handler(self, event, handler):
|
def register_handler(self, event, handler):
|
||||||
if event not in self.handlers:
|
if event not in self.handlers:
|
||||||
self.handlers[event] = []
|
self.handlers[event] = []
|
||||||
|
@ -2088,6 +2109,7 @@ class Interface:
|
||||||
'JINGLE_CONNECTED': [self.handle_event_jingle_connected],
|
'JINGLE_CONNECTED': [self.handle_event_jingle_connected],
|
||||||
'JINGLE_DISCONNECTED': [self.handle_event_jingle_disconnected],
|
'JINGLE_DISCONNECTED': [self.handle_event_jingle_disconnected],
|
||||||
'JINGLE_ERROR': [self.handle_event_jingle_error],
|
'JINGLE_ERROR': [self.handle_event_jingle_error],
|
||||||
|
'PEP_RECEIVED': [self.handle_event_pep_received]
|
||||||
}
|
}
|
||||||
|
|
||||||
def dispatch(self, event, account, data):
|
def dispatch(self, event, account, data):
|
||||||
|
@ -2774,33 +2796,27 @@ class Interface:
|
||||||
listener.disconnect(self.music_track_changed_signal)
|
listener.disconnect(self.music_track_changed_signal)
|
||||||
self.music_track_changed_signal = None
|
self.music_track_changed_signal = None
|
||||||
|
|
||||||
def music_track_changed(self, unused_listener, music_track_info, account=''):
|
def music_track_changed(self, unused_listener, music_track_info, account=None):
|
||||||
if account == '':
|
if not account:
|
||||||
accounts = gajim.connections.keys()
|
accounts = gajim.connections.keys()
|
||||||
else:
|
else:
|
||||||
accounts = [account]
|
accounts = [account]
|
||||||
if music_track_info is None:
|
|
||||||
artist = ''
|
is_paused = hasattr(music_track_info, 'paused') and music_track_info.paused == 0
|
||||||
title = ''
|
if not music_track_info or is_paused:
|
||||||
source = ''
|
artist = title = source = ''
|
||||||
elif hasattr(music_track_info, 'paused') and music_track_info.paused == 0:
|
|
||||||
artist = ''
|
|
||||||
title = ''
|
|
||||||
source = ''
|
|
||||||
else:
|
else:
|
||||||
artist = music_track_info.artist
|
artist = music_track_info.artist
|
||||||
title = music_track_info.title
|
title = music_track_info.title
|
||||||
source = music_track_info.album
|
source = music_track_info.album
|
||||||
for acct in accounts:
|
for acct in accounts:
|
||||||
if acct not in gajim.connections:
|
|
||||||
continue
|
|
||||||
if not gajim.account_is_connected(acct):
|
if not gajim.account_is_connected(acct):
|
||||||
continue
|
continue
|
||||||
if not gajim.connections[acct].pep_supported:
|
if not gajim.config.get_per('accounts', acct, 'publish_tune'):
|
||||||
continue
|
continue
|
||||||
if gajim.connections[acct].music_track_info == music_track_info:
|
if gajim.connections[acct].music_track_info == music_track_info:
|
||||||
continue
|
continue
|
||||||
pep.user_send_tune(acct, artist, title, source)
|
gajim.connections[acct].send_tune(artist, title, source)
|
||||||
gajim.connections[acct].music_track_info = music_track_info
|
gajim.connections[acct].music_track_info = music_track_info
|
||||||
|
|
||||||
def get_bg_fg_colors(self):
|
def get_bg_fg_colors(self):
|
||||||
|
|
|
@ -322,8 +322,7 @@ class ProfileWindow:
|
||||||
nick = ''
|
nick = ''
|
||||||
if 'NICKNAME' in vcard_:
|
if 'NICKNAME' in vcard_:
|
||||||
nick = vcard_['NICKNAME']
|
nick = vcard_['NICKNAME']
|
||||||
from common import pep
|
gajim.connections[self.account].send_nickname(self.account, nick)
|
||||||
pep.user_send_nickname(self.account, nick)
|
|
||||||
if nick == '':
|
if nick == '':
|
||||||
nick = gajim.config.get_per('accounts', self.account, 'name')
|
nick = gajim.config.get_per('accounts', self.account, 'name')
|
||||||
gajim.nicks[self.account] = nick
|
gajim.nicks[self.account] = nick
|
||||||
|
|
|
@ -1022,55 +1022,21 @@ class RosterWindow:
|
||||||
|
|
||||||
self.model[child_iter][C_NAME] = account_name
|
self.model[child_iter][C_NAME] = account_name
|
||||||
|
|
||||||
if gajim.config.get('show_mood_in_roster') \
|
pep = gajim.connections[account].pep
|
||||||
and 'mood' in gajim.connections[account].mood \
|
if gajim.config.get('show_mood_in_roster') and 'mood' in pep:
|
||||||
and gajim.connections[account].mood['mood'].strip() in MOODS:
|
self.model[child_iter][C_MOOD_PIXBUF] = pep['mood'].asPixbufIcon()
|
||||||
|
|
||||||
self.model[child_iter][C_MOOD_PIXBUF] = gtkgui_helpers.load_mood_icon(
|
|
||||||
gajim.connections[account].mood['mood'].strip()).get_pixbuf()
|
|
||||||
|
|
||||||
elif gajim.config.get('show_mood_in_roster') \
|
|
||||||
and 'mood' in gajim.connections[account].mood:
|
|
||||||
self.model[child_iter][C_MOOD_PIXBUF] = \
|
|
||||||
gtkgui_helpers.load_mood_icon('unknown'). \
|
|
||||||
get_pixbuf()
|
|
||||||
else:
|
else:
|
||||||
self.model[child_iter][C_MOOD_PIXBUF] = None
|
self.model[child_iter][C_MOOD_PIXBUF] = None
|
||||||
|
|
||||||
if gajim.config.get('show_activity_in_roster') \
|
if gajim.config.get('show_activity_in_roster') and 'activity' in pep:
|
||||||
and 'activity' in gajim.connections[account].activity \
|
self.model[child_iter][C_ACTIVITY_PIXBUF] = pep['activity'].asPixbufIcon()
|
||||||
and gajim.connections[account].activity['activity'].strip() \
|
|
||||||
in ACTIVITIES:
|
|
||||||
if 'subactivity' in gajim.connections[account].activity \
|
|
||||||
and gajim.connections[account].activity['subactivity'].strip() \
|
|
||||||
in ACTIVITIES[gajim.connections[account].activity['activity'].strip()]:
|
|
||||||
self.model[child_iter][C_ACTIVITY_PIXBUF] = \
|
|
||||||
gtkgui_helpers.load_activity_icon(
|
|
||||||
gajim.connections[account].activity['activity'].strip(),
|
|
||||||
gajim.connections[account].activity['subactivity'].strip()). \
|
|
||||||
get_pixbuf()
|
|
||||||
else:
|
|
||||||
self.model[child_iter][C_ACTIVITY_PIXBUF] = \
|
|
||||||
gtkgui_helpers.load_activity_icon(
|
|
||||||
gajim.connections[account].activity['activity'].strip()). \
|
|
||||||
get_pixbuf()
|
|
||||||
elif gajim.config.get('show_activity_in_roster') \
|
|
||||||
and 'activity' in gajim.connections[account].activity:
|
|
||||||
self.model[child_iter][C_ACTIVITY_PIXBUF] = \
|
|
||||||
gtkgui_helpers.load_activity_icon('unknown'). \
|
|
||||||
get_pixbuf()
|
|
||||||
else:
|
else:
|
||||||
self.model[child_iter][C_ACTIVITY_PIXBUF] = None
|
self.model[child_iter][C_ACTIVITY_PIXBUF] = None
|
||||||
|
|
||||||
if gajim.config.get('show_tunes_in_roster') \
|
if gajim.config.get('show_tunes_in_roster') and 'tune' in pep:
|
||||||
and ('artist' in gajim.connections[account].tune \
|
self.model[child_iter][C_TUNE_PIXBUF] = pep['tune'].asPixbufIcon()
|
||||||
or 'title' in gajim.connections[account].tune):
|
|
||||||
path = os.path.join(gajim.DATA_DIR, 'emoticons', 'static', 'music.png')
|
|
||||||
self.model[child_iter][C_TUNE_PIXBUF] = \
|
|
||||||
gtk.gdk.pixbuf_new_from_file(path)
|
|
||||||
else:
|
else:
|
||||||
self.model[child_iter][C_TUNE_PIXBUF] = None
|
self.model[child_iter][C_TUNE_PIXBUF] = None
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def draw_group(self, group, account):
|
def draw_group(self, group, account):
|
||||||
|
@ -1276,71 +1242,39 @@ class RosterWindow:
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def _is_pep_shown_in_roster(self, pep_type):
|
||||||
def draw_mood(self, jid, account):
|
if pep_type == 'mood':
|
||||||
|
return gajim.config.get('show_mood_in_roster')
|
||||||
|
elif pep_type == 'activity':
|
||||||
|
return gajim.config.get('show_activity_in_roster')
|
||||||
|
elif pep_type == 'tune':
|
||||||
|
return gajim.config.get('show_tunes_in_roster')
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def draw_all_pep_types(self, jid, account):
|
||||||
|
for pep_type in self._pep_type_to_model_column:
|
||||||
|
self.draw_pep(jid, account, pep_type)
|
||||||
|
|
||||||
|
def draw_pep(self, jid, account, pep_type):
|
||||||
|
if pep_type not in self._pep_type_to_model_column:
|
||||||
|
return
|
||||||
|
if not self._is_pep_shown_in_roster(pep_type):
|
||||||
|
return
|
||||||
|
|
||||||
|
model_column = self._pep_type_to_model_column[pep_type]
|
||||||
iters = self._get_contact_iter(jid, account, model=self.model)
|
iters = self._get_contact_iter(jid, account, model=self.model)
|
||||||
if not iters or not gajim.config.get('show_mood_in_roster'):
|
if not iters:
|
||||||
return
|
return
|
||||||
jid = self.model[iters[0]][C_JID]
|
jid = self.model[iters[0]][C_JID]
|
||||||
jid = jid.decode('utf-8')
|
jid = jid.decode('utf-8')
|
||||||
contact = gajim.contacts.get_contact(account, jid)
|
contact = gajim.contacts.get_contact(account, jid)
|
||||||
if 'mood' in contact.mood and contact.mood['mood'].strip() in MOODS:
|
if pep_type in contact.pep:
|
||||||
pixbuf = gtkgui_helpers.load_mood_icon(
|
pixbuf = contact.pep[pep_type].asPixbufIcon()
|
||||||
contact.mood['mood'].strip()).get_pixbuf()
|
|
||||||
elif 'mood' in contact.mood:
|
|
||||||
pixbuf = gtkgui_helpers.load_mood_icon(
|
|
||||||
'unknown').get_pixbuf()
|
|
||||||
else:
|
else:
|
||||||
pixbuf = None
|
pixbuf = None
|
||||||
for child_iter in iters:
|
for child_iter in iters:
|
||||||
self.model[child_iter][C_MOOD_PIXBUF] = pixbuf
|
self.model[child_iter][model_column] = pixbuf
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def draw_activity(self, jid, account):
|
|
||||||
iters = self._get_contact_iter(jid, account, model=self.model)
|
|
||||||
if not iters or not gajim.config.get('show_activity_in_roster'):
|
|
||||||
return
|
|
||||||
jid = self.model[iters[0]][C_JID]
|
|
||||||
jid = jid.decode('utf-8')
|
|
||||||
contact = gajim.contacts.get_contact(account, jid)
|
|
||||||
if 'activity' in contact.activity \
|
|
||||||
and contact.activity['activity'].strip() in ACTIVITIES:
|
|
||||||
if 'subactivity' in contact.activity \
|
|
||||||
and contact.activity['subactivity'].strip() in \
|
|
||||||
ACTIVITIES[contact.activity['activity'].strip()]:
|
|
||||||
pixbuf = gtkgui_helpers.load_activity_icon(
|
|
||||||
contact.activity['activity'].strip(),
|
|
||||||
contact.activity['subactivity'].strip()).get_pixbuf()
|
|
||||||
else:
|
|
||||||
pixbuf = gtkgui_helpers.load_activity_icon(
|
|
||||||
contact.activity['activity'].strip()).get_pixbuf()
|
|
||||||
elif 'activity' in contact.activity:
|
|
||||||
pixbuf = gtkgui_helpers.load_activity_icon(
|
|
||||||
'unknown').get_pixbuf()
|
|
||||||
else:
|
|
||||||
pixbuf = None
|
|
||||||
for child_iter in iters:
|
|
||||||
self.model[child_iter][C_ACTIVITY_PIXBUF] = pixbuf
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def draw_tune(self, jid, account):
|
|
||||||
iters = self._get_contact_iter(jid, account, model=self.model)
|
|
||||||
if not iters or not gajim.config.get('show_tunes_in_roster'):
|
|
||||||
return
|
|
||||||
jid = self.model[iters[0]][C_JID]
|
|
||||||
jid = jid.decode('utf-8')
|
|
||||||
contact = gajim.contacts.get_contact(account, jid)
|
|
||||||
if 'artist' in contact.tune or 'title' in contact.tune:
|
|
||||||
path = os.path.join(gajim.DATA_DIR, 'emoticons', 'static', 'music.png')
|
|
||||||
pixbuf = gtk.gdk.pixbuf_new_from_file(path)
|
|
||||||
else:
|
|
||||||
pixbuf = None
|
|
||||||
for child_iter in iters:
|
|
||||||
self.model[child_iter][C_TUNE_PIXBUF] = pixbuf
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def draw_avatar(self, jid, account):
|
def draw_avatar(self, jid, account):
|
||||||
iters = self._get_contact_iter(jid, account, model=self.model)
|
iters = self._get_contact_iter(jid, account, model=self.model)
|
||||||
|
@ -1359,9 +1293,7 @@ class RosterWindow:
|
||||||
|
|
||||||
def draw_completely(self, jid, account):
|
def draw_completely(self, jid, account):
|
||||||
self.draw_contact(jid, account)
|
self.draw_contact(jid, account)
|
||||||
self.draw_mood(jid, account)
|
self.draw_all_pep_types(jid, account)
|
||||||
self.draw_activity(jid, account)
|
|
||||||
self.draw_tune(jid, account)
|
|
||||||
self.draw_avatar(jid, account)
|
self.draw_avatar(jid, account)
|
||||||
|
|
||||||
def adjust_and_draw_contact_context(self, jid, account):
|
def adjust_and_draw_contact_context(self, jid, account):
|
||||||
|
@ -1964,36 +1896,36 @@ class RosterWindow:
|
||||||
|
|
||||||
self.send_status_continue(account, status, txt, auto, to)
|
self.send_status_continue(account, status, txt, auto, to)
|
||||||
|
|
||||||
def send_pep(self, account, pep_dict=None):
|
def send_pep(self, account, pep_dict):
|
||||||
'''Sends pep information (activity, mood)'''
|
connection = gajim.connections[account]
|
||||||
if not pep_dict:
|
|
||||||
return
|
if 'activity' in pep_dict:
|
||||||
# activity
|
|
||||||
if 'activity' in pep_dict and pep_dict['activity'] in pep.ACTIVITIES:
|
|
||||||
activity = pep_dict['activity']
|
activity = pep_dict['activity']
|
||||||
if 'subactivity' in pep_dict and \
|
subactivity = pep_dict.get('subactivity', None)
|
||||||
pep_dict['subactivity'] in pep.ACTIVITIES[activity]:
|
activity_text = pep_dict.get('activity_text', None)
|
||||||
subactivity = pep_dict['subactivity']
|
connection.send_activity(activity, subactivity, activity_text)
|
||||||
else:
|
|
||||||
subactivity = 'other'
|
|
||||||
if 'activity_text' in pep_dict:
|
|
||||||
activity_text = pep_dict['activity_text']
|
|
||||||
else:
|
|
||||||
activity_text = ''
|
|
||||||
pep.user_send_activity(account, activity, subactivity, activity_text)
|
|
||||||
else:
|
else:
|
||||||
pep.user_send_activity(account, '')
|
connection.retract_activity()
|
||||||
|
|
||||||
# mood
|
if 'mood' in pep_dict:
|
||||||
if 'mood' in pep_dict and pep_dict['mood'] in pep.MOODS:
|
|
||||||
mood = pep_dict['mood']
|
mood = pep_dict['mood']
|
||||||
if 'mood_text' in pep_dict:
|
mood_text = pep_dict.get('mood_text', None)
|
||||||
mood_text = pep_dict['mood_text']
|
connection.send_mood(mood, mood_text)
|
||||||
else:
|
|
||||||
mood_text = ''
|
|
||||||
pep.user_send_mood(account, mood, mood_text)
|
|
||||||
else:
|
else:
|
||||||
pep.user_send_mood(account, '')
|
connection.retract_mood()
|
||||||
|
|
||||||
|
def delete_pep(self, jid, account):
|
||||||
|
if jid == gajim.get_jid_from_account(account):
|
||||||
|
gajim.connections[account].pep = {}
|
||||||
|
self.draw_account(account)
|
||||||
|
|
||||||
|
for contact in gajim.contacts.get_contacts(account, jid):
|
||||||
|
contact.pep = {}
|
||||||
|
|
||||||
|
self.draw_all_pep_types(jid, account)
|
||||||
|
ctrl = gajim.interface.msg_win_mgr.get_control(jid, account)
|
||||||
|
if ctrl:
|
||||||
|
ctrl.update_all_pep_types()
|
||||||
|
|
||||||
def send_status_continue(self, account, status, txt, auto, to):
|
def send_status_continue(self, account, status, txt, auto, to):
|
||||||
if gajim.account_is_connected(account) and not to:
|
if gajim.account_is_connected(account) and not to:
|
||||||
|
@ -2008,8 +1940,7 @@ class RosterWindow:
|
||||||
gajim.connections[account].send_custom_status(status, txt, to)
|
gajim.connections[account].send_custom_status(status, txt, to)
|
||||||
else:
|
else:
|
||||||
if status in ('invisible', 'offline'):
|
if status in ('invisible', 'offline'):
|
||||||
pep.delete_pep(gajim.get_jid_from_account(account), \
|
self.delete_pep(gajim.get_jid_from_account(account), account)
|
||||||
account)
|
|
||||||
was_invisible = gajim.connections[account].connected == \
|
was_invisible = gajim.connections[account].connected == \
|
||||||
gajim.SHOW_LIST.index('invisible')
|
gajim.SHOW_LIST.index('invisible')
|
||||||
gajim.connections[account].change_status(status, txt, auto)
|
gajim.connections[account].change_status(status, txt, auto)
|
||||||
|
@ -2087,7 +2018,7 @@ class RosterWindow:
|
||||||
contact_instances)
|
contact_instances)
|
||||||
if not keep_pep and contact.jid != gajim.get_jid_from_account(account) \
|
if not keep_pep and contact.jid != gajim.get_jid_from_account(account) \
|
||||||
and not contact.is_groupchat():
|
and not contact.is_groupchat():
|
||||||
pep.delete_pep(contact.jid, account)
|
self.delete_pep(contact.jid, account)
|
||||||
|
|
||||||
# Redraw everything and select the sender
|
# Redraw everything and select the sender
|
||||||
self.adjust_and_draw_contact_context(contact.jid, account)
|
self.adjust_and_draw_contact_context(contact.jid, account)
|
||||||
|
@ -2501,11 +2432,10 @@ class RosterWindow:
|
||||||
account_name = account
|
account_name = account
|
||||||
if gajim.account_is_connected(account):
|
if gajim.account_is_connected(account):
|
||||||
account_name += ' (%s/%s)' % (repr(nbr_on), repr(nbr_total))
|
account_name += ' (%s/%s)' % (repr(nbr_on), repr(nbr_total))
|
||||||
contact = gajim.contacts.create_contact(jid=jid, account=account, name=account_name,
|
contact = gajim.contacts.create_self_contact(jid=jid, account=account,
|
||||||
show=connection.get_status(), sub='', status=connection.status,
|
name=account_name, show=connection.get_status(),
|
||||||
resource=connection.server_resource,
|
status=connection.status, resource=connection.server_resource,
|
||||||
priority=connection.priority, mood=connection.mood,
|
priority=connection.priority)
|
||||||
tune=connection.tune, activity=connection.activity)
|
|
||||||
if gajim.connections[account].gpg:
|
if gajim.connections[account].gpg:
|
||||||
contact.keyID = gajim.config.get_per('accounts', connection.name,
|
contact.keyID = gajim.config.get_per('accounts', connection.name,
|
||||||
'keyid')
|
'keyid')
|
||||||
|
@ -3388,23 +3318,19 @@ class RosterWindow:
|
||||||
gajim.interface.instances['preferences'] = config.PreferencesWindow()
|
gajim.interface.instances['preferences'] = config.PreferencesWindow()
|
||||||
|
|
||||||
def on_publish_tune_toggled(self, widget, account):
|
def on_publish_tune_toggled(self, widget, account):
|
||||||
act = widget.get_active()
|
active = widget.get_active()
|
||||||
gajim.config.set_per('accounts', account, 'publish_tune', act)
|
gajim.config.set_per('accounts', account, 'publish_tune', active)
|
||||||
if act:
|
if active:
|
||||||
gajim.interface.enable_music_listener()
|
gajim.interface.enable_music_listener()
|
||||||
else:
|
else:
|
||||||
# disable it only if no other account use it
|
gajim.connections[account].retract_tune()
|
||||||
for acct in gajim.connections:
|
# disable music listener only if no other account uses it
|
||||||
if gajim.config.get_per('accounts', acct, 'publish_tune'):
|
for acc in gajim.connections:
|
||||||
|
if gajim.config.get_per('accounts', acc, 'publish_tune'):
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
gajim.interface.disable_music_listener()
|
gajim.interface.disable_music_listener()
|
||||||
|
|
||||||
if gajim.connections[account].pep_supported:
|
|
||||||
# As many implementations don't support retracting items, we send a
|
|
||||||
# "Stopped" event first
|
|
||||||
pep.user_send_tune(account, '')
|
|
||||||
pep.user_retract_tune(account)
|
|
||||||
helpers.update_optional_features(account)
|
helpers.update_optional_features(account)
|
||||||
|
|
||||||
def on_pep_services_menuitem_activate(self, widget, account):
|
def on_pep_services_menuitem_activate(self, widget, account):
|
||||||
|
@ -4481,9 +4407,9 @@ class RosterWindow:
|
||||||
renderer.set_property('xpad', 8)
|
renderer.set_property('xpad', 8)
|
||||||
|
|
||||||
|
|
||||||
def _fill_mood_pixbuf_renderer(self, column, renderer, model, titer,
|
def _fill_pep_pixbuf_renderer(self, column, renderer, model, titer,
|
||||||
data = None):
|
data=None):
|
||||||
'''When a row is added, set properties for avatar renderer'''
|
'''When a row is added, draw the respective pep icon'''
|
||||||
theme = gajim.config.get('roster_theme')
|
theme = gajim.config.get('roster_theme')
|
||||||
type_ = model[titer][C_TYPE]
|
type_ = model[titer][C_TYPE]
|
||||||
if type_ == 'group':
|
if type_ == 'group':
|
||||||
|
@ -4491,155 +4417,37 @@ class RosterWindow:
|
||||||
return
|
return
|
||||||
|
|
||||||
# allocate space for the icon only if needed
|
# allocate space for the icon only if needed
|
||||||
if model[titer][C_MOOD_PIXBUF]:
|
if model[titer][data]:
|
||||||
renderer.set_property('visible', True)
|
renderer.set_property('visible', True)
|
||||||
else:
|
else:
|
||||||
renderer.set_property('visible', False)
|
renderer.set_property('visible', False)
|
||||||
if type_ == 'account':
|
if type_ == 'account':
|
||||||
color = gajim.config.get_per('themes', theme,
|
color = gajim.config.get_per('themes', theme, 'accountbgcolor')
|
||||||
'accountbgcolor')
|
|
||||||
if color:
|
if color:
|
||||||
renderer.set_property('cell-background', color)
|
renderer.set_property('cell-background', color)
|
||||||
else:
|
else:
|
||||||
self.set_renderer_color(renderer,
|
self.set_renderer_color(renderer, gtk.STATE_ACTIVE)
|
||||||
gtk.STATE_ACTIVE)
|
|
||||||
# align pixbuf to the right)
|
# align pixbuf to the right)
|
||||||
renderer.set_property('xalign', 1)
|
renderer.set_property('xalign', 1)
|
||||||
# prevent type_ = None, see http://trac.gajim.org/ticket/2534
|
# prevent type_ = None, see http://trac.gajim.org/ticket/2534
|
||||||
elif type_:
|
elif type_:
|
||||||
if not model[titer][C_JID] \
|
if not model[titer][C_JID] or not model[titer][C_ACCOUNT]:
|
||||||
or not model[titer][C_ACCOUNT]:
|
|
||||||
# This can append at the moment we add the row
|
# This can append at the moment we add the row
|
||||||
return
|
return
|
||||||
jid = model[titer][C_JID].decode('utf-8')
|
jid = model[titer][C_JID].decode('utf-8')
|
||||||
account = model[titer][C_ACCOUNT].decode('utf-8')
|
account = model[titer][C_ACCOUNT].decode('utf-8')
|
||||||
if jid in gajim.newly_added[account]:
|
if jid in gajim.newly_added[account]:
|
||||||
renderer.set_property('cell-background',
|
renderer.set_property('cell-background', gajim.config.get(
|
||||||
gajim.config.get(
|
|
||||||
'just_connected_bg_color'))
|
'just_connected_bg_color'))
|
||||||
elif jid in gajim.to_be_removed[account]:
|
elif jid in gajim.to_be_removed[account]:
|
||||||
renderer.set_property('cell-background',
|
renderer.set_property('cell-background', gajim.config.get(
|
||||||
gajim.config.get(
|
|
||||||
'just_disconnected_bg_color'))
|
'just_disconnected_bg_color'))
|
||||||
else:
|
else:
|
||||||
color = gajim.config.get_per('themes',
|
color = gajim.config.get_per('themes', theme, 'contactbgcolor')
|
||||||
theme, 'contactbgcolor')
|
renderer.set_property('cell-background', color if color else None)
|
||||||
if color:
|
|
||||||
renderer.set_property(
|
|
||||||
'cell-background', color)
|
|
||||||
else:
|
|
||||||
renderer.set_property(
|
|
||||||
'cell-background', None)
|
|
||||||
# align pixbuf to the right
|
# align pixbuf to the right
|
||||||
renderer.set_property('xalign', 1)
|
renderer.set_property('xalign', 1)
|
||||||
|
|
||||||
|
|
||||||
def _fill_activity_pixbuf_renderer(self, column, renderer, model, titer,
|
|
||||||
data = None):
|
|
||||||
'''When a row is added, set properties for avatar renderer'''
|
|
||||||
theme = gajim.config.get('roster_theme')
|
|
||||||
type_ = model[titer][C_TYPE]
|
|
||||||
if type_ == 'group':
|
|
||||||
renderer.set_property('visible', False)
|
|
||||||
return
|
|
||||||
|
|
||||||
# allocate space for the icon only if needed
|
|
||||||
if model[titer][C_ACTIVITY_PIXBUF]:
|
|
||||||
renderer.set_property('visible', True)
|
|
||||||
else:
|
|
||||||
renderer.set_property('visible', False)
|
|
||||||
if type_ == 'account':
|
|
||||||
color = gajim.config.get_per('themes', theme,
|
|
||||||
'accountbgcolor')
|
|
||||||
if color:
|
|
||||||
renderer.set_property('cell-background', color)
|
|
||||||
else:
|
|
||||||
self.set_renderer_color(renderer,
|
|
||||||
gtk.STATE_ACTIVE)
|
|
||||||
# align pixbuf to the right)
|
|
||||||
renderer.set_property('xalign', 1)
|
|
||||||
# prevent type_ = None, see http://trac.gajim.org/ticket/2534
|
|
||||||
elif type_:
|
|
||||||
if not model[titer][C_JID] \
|
|
||||||
or not model[titer][C_ACCOUNT]:
|
|
||||||
# This can append at the moment we add the row
|
|
||||||
return
|
|
||||||
jid = model[titer][C_JID].decode('utf-8')
|
|
||||||
account = model[titer][C_ACCOUNT].decode('utf-8')
|
|
||||||
if jid in gajim.newly_added[account]:
|
|
||||||
renderer.set_property('cell-background',
|
|
||||||
gajim.config.get(
|
|
||||||
'just_connected_bg_color'))
|
|
||||||
elif jid in gajim.to_be_removed[account]:
|
|
||||||
renderer.set_property('cell-background',
|
|
||||||
gajim.config.get(
|
|
||||||
'just_disconnected_bg_color'))
|
|
||||||
else:
|
|
||||||
color = gajim.config.get_per('themes',
|
|
||||||
theme, 'contactbgcolor')
|
|
||||||
if color:
|
|
||||||
renderer.set_property(
|
|
||||||
'cell-background', color)
|
|
||||||
else:
|
|
||||||
renderer.set_property(
|
|
||||||
'cell-background', None)
|
|
||||||
# align pixbuf to the right
|
|
||||||
renderer.set_property('xalign', 1)
|
|
||||||
|
|
||||||
|
|
||||||
def _fill_tune_pixbuf_renderer(self, column, renderer, model, titer,
|
|
||||||
data = None):
|
|
||||||
'''When a row is added, set properties for avatar renderer'''
|
|
||||||
theme = gajim.config.get('roster_theme')
|
|
||||||
type_ = model[titer][C_TYPE]
|
|
||||||
if type_ == 'group':
|
|
||||||
renderer.set_property('visible', False)
|
|
||||||
return
|
|
||||||
|
|
||||||
# allocate space for the icon only if needed
|
|
||||||
if model[titer][C_TUNE_PIXBUF]:
|
|
||||||
renderer.set_property('visible', True)
|
|
||||||
else:
|
|
||||||
renderer.set_property('visible', False)
|
|
||||||
if type_ == 'account':
|
|
||||||
color = gajim.config.get_per('themes', theme,
|
|
||||||
'accountbgcolor')
|
|
||||||
if color:
|
|
||||||
renderer.set_property('cell-background', color)
|
|
||||||
else:
|
|
||||||
self.set_renderer_color(renderer,
|
|
||||||
gtk.STATE_ACTIVE)
|
|
||||||
# align pixbuf to the right)
|
|
||||||
renderer.set_property('xalign', 1)
|
|
||||||
# prevent type_ = None, see http://trac.gajim.org/ticket/2534
|
|
||||||
elif type_:
|
|
||||||
if not model[titer][C_JID] \
|
|
||||||
or not model[titer][C_ACCOUNT]:
|
|
||||||
# This can append at the moment we add the row
|
|
||||||
return
|
|
||||||
jid = model[titer][C_JID].decode('utf-8')
|
|
||||||
account = model[titer][C_ACCOUNT].decode('utf-8')
|
|
||||||
if jid in gajim.newly_added[account]:
|
|
||||||
renderer.set_property('cell-background',
|
|
||||||
gajim.config.get(
|
|
||||||
'just_connected_bg_color'))
|
|
||||||
elif jid in gajim.to_be_removed[account]:
|
|
||||||
renderer.set_property('cell-background',
|
|
||||||
gajim.config.get(
|
|
||||||
'just_disconnected_bg_color'))
|
|
||||||
else:
|
|
||||||
color = gajim.config.get_per('themes',
|
|
||||||
theme, 'contactbgcolor')
|
|
||||||
if color:
|
|
||||||
renderer.set_property(
|
|
||||||
'cell-background', color)
|
|
||||||
else:
|
|
||||||
renderer.set_property(
|
|
||||||
'cell-background', None)
|
|
||||||
# align pixbuf to the right
|
|
||||||
renderer.set_property('xalign', 1)
|
|
||||||
|
|
||||||
|
|
||||||
def _fill_avatar_pixbuf_renderer(self, column, renderer, model, titer,
|
def _fill_avatar_pixbuf_renderer(self, column, renderer, model, titer,
|
||||||
data = None):
|
data = None):
|
||||||
'''When a row is added, set properties for avatar renderer'''
|
'''When a row is added, set properties for avatar renderer'''
|
||||||
|
@ -5933,19 +5741,23 @@ class RosterWindow:
|
||||||
col.pack_start(render_pixbuf, expand=False)
|
col.pack_start(render_pixbuf, expand=False)
|
||||||
col.add_attribute(render_pixbuf, 'pixbuf', C_MOOD_PIXBUF)
|
col.add_attribute(render_pixbuf, 'pixbuf', C_MOOD_PIXBUF)
|
||||||
col.set_cell_data_func(render_pixbuf,
|
col.set_cell_data_func(render_pixbuf,
|
||||||
self._fill_mood_pixbuf_renderer, None)
|
self._fill_pep_pixbuf_renderer, C_MOOD_PIXBUF)
|
||||||
|
|
||||||
render_pixbuf = gtk.CellRendererPixbuf()
|
render_pixbuf = gtk.CellRendererPixbuf()
|
||||||
col.pack_start(render_pixbuf, expand=False)
|
col.pack_start(render_pixbuf, expand=False)
|
||||||
col.add_attribute(render_pixbuf, 'pixbuf', C_ACTIVITY_PIXBUF)
|
col.add_attribute(render_pixbuf, 'pixbuf', C_ACTIVITY_PIXBUF)
|
||||||
col.set_cell_data_func(render_pixbuf,
|
col.set_cell_data_func(render_pixbuf,
|
||||||
self._fill_activity_pixbuf_renderer, None)
|
self._fill_pep_pixbuf_renderer, C_ACTIVITY_PIXBUF)
|
||||||
|
|
||||||
render_pixbuf = gtk.CellRendererPixbuf()
|
render_pixbuf = gtk.CellRendererPixbuf()
|
||||||
col.pack_start(render_pixbuf, expand=False)
|
col.pack_start(render_pixbuf, expand=False)
|
||||||
col.add_attribute(render_pixbuf, 'pixbuf', C_TUNE_PIXBUF)
|
col.add_attribute(render_pixbuf, 'pixbuf', C_TUNE_PIXBUF)
|
||||||
col.set_cell_data_func(render_pixbuf,
|
col.set_cell_data_func(render_pixbuf,
|
||||||
self._fill_tune_pixbuf_renderer, None)
|
self._fill_pep_pixbuf_renderer, C_TUNE_PIXBUF)
|
||||||
|
|
||||||
|
self._pep_type_to_model_column = {'mood': C_MOOD_PIXBUF,
|
||||||
|
'activity': C_ACTIVITY_PIXBUF,
|
||||||
|
'tune': C_TUNE_PIXBUF}
|
||||||
|
|
||||||
if gajim.config.get('avatar_position_in_roster') == 'right':
|
if gajim.config.get('avatar_position_in_roster') == 'right':
|
||||||
add_avatar_renderer()
|
add_avatar_renderer()
|
||||||
|
|
|
@ -579,65 +579,19 @@ class RosterTooltip(NotificationAreaTooltip):
|
||||||
Append Tune, Mood, Activity information of the specified contact
|
Append Tune, Mood, Activity information of the specified contact
|
||||||
to the given property list.
|
to the given property list.
|
||||||
'''
|
'''
|
||||||
if 'mood' in contact.mood:
|
if 'mood' in contact.pep:
|
||||||
mood = contact.mood['mood'].strip()
|
mood = contact.pep['mood'].asMarkupText()
|
||||||
mood = MOODS.get(mood, mood)
|
mood_string = _('Mood:') + ' %s' % mood
|
||||||
mood = gobject.markup_escape_text(mood)
|
|
||||||
mood_string = _('Mood:') + ' <b>%s</b>' % mood
|
|
||||||
if 'text' in contact.mood \
|
|
||||||
and contact.mood['text'] != '':
|
|
||||||
mood_text = contact.mood['text'].strip()
|
|
||||||
mood_text = \
|
|
||||||
gobject.markup_escape_text(mood_text)
|
|
||||||
mood_string += ' (%s)' % mood_text
|
|
||||||
properties.append((mood_string, None))
|
properties.append((mood_string, None))
|
||||||
|
|
||||||
if 'activity' in contact.activity:
|
if 'activity' in contact.pep:
|
||||||
activity = act_plain = \
|
activity = contact.pep['activity'].asMarkupText()
|
||||||
contact.activity['activity'].strip()
|
activity_string = _('Activity:') + ' %s' % activity
|
||||||
activity = gobject.markup_escape_text(activity)
|
|
||||||
if act_plain in ACTIVITIES:
|
|
||||||
activity = ACTIVITIES[activity]['category']
|
|
||||||
activity_string = _('Activity:') + ' <b>%s' % activity
|
|
||||||
if 'subactivity' in contact.activity:
|
|
||||||
activity_sub = \
|
|
||||||
contact.activity['subactivity'].strip()
|
|
||||||
if act_plain in ACTIVITIES and activity_sub in \
|
|
||||||
ACTIVITIES[act_plain]:
|
|
||||||
activity_sub = ACTIVITIES[act_plain][activity_sub]
|
|
||||||
activity_sub = \
|
|
||||||
gobject.markup_escape_text(activity_sub)
|
|
||||||
activity_string += ': %s</b>' % activity_sub
|
|
||||||
else:
|
|
||||||
activity_string += '</b>'
|
|
||||||
if 'text' in contact.activity:
|
|
||||||
activity_text = contact.activity['text'].strip()
|
|
||||||
activity_text = gobject.markup_escape_text(
|
|
||||||
activity_text)
|
|
||||||
activity_string += ' (%s)' % activity_text
|
|
||||||
properties.append((activity_string, None))
|
properties.append((activity_string, None))
|
||||||
|
|
||||||
if 'artist' in contact.tune \
|
if 'tune' in contact.pep:
|
||||||
or 'title' in contact.tune:
|
tune = contact.pep['tune'].asMarkupText()
|
||||||
if 'artist' in contact.tune:
|
tune_string = _('Tune:') + ' %s' % tune
|
||||||
artist = contact.tune['artist'].strip()
|
|
||||||
artist = gobject.markup_escape_text(artist)
|
|
||||||
else:
|
|
||||||
artist = _('Unknown Artist')
|
|
||||||
if 'title' in contact.tune:
|
|
||||||
title = contact.tune['title'].strip()
|
|
||||||
title = gobject.markup_escape_text(title)
|
|
||||||
else:
|
|
||||||
title = _('Unknown Title')
|
|
||||||
if 'source' in contact.tune:
|
|
||||||
source = contact.tune['source'].strip()
|
|
||||||
source = gobject.markup_escape_text(source)
|
|
||||||
else:
|
|
||||||
source = _('Unknown Source')
|
|
||||||
tune_string = _('Tune:') + ' ' + \
|
|
||||||
_('<b>"%(title)s"</b> by <i>%(artist)s</i>\n'
|
|
||||||
'from <i>%(source)s</i>') % {'title': title,
|
|
||||||
'artist': artist, 'source': source}
|
|
||||||
properties.append((tune_string, None))
|
properties.append((tune_string, None))
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -14,9 +14,7 @@ class MockConnection(Mock, ConnectionHandlersBase):
|
||||||
|
|
||||||
self.name = account
|
self.name = account
|
||||||
self.connected = 2
|
self.connected = 2
|
||||||
self.mood = {}
|
self.pep = {}
|
||||||
self.activity = {}
|
|
||||||
self.tune = {}
|
|
||||||
self.blocked_contacts = {}
|
self.blocked_contacts = {}
|
||||||
self.blocked_groups = {}
|
self.blocked_groups = {}
|
||||||
self.sessions = {}
|
self.sessions = {}
|
||||||
|
|
Loading…
Reference in New Issue