Merge PEP refactorings back to the default branch.

This commit is contained in:
Stephan Erb 2009-11-16 20:05:09 +01:00
commit 5c32304740
14 changed files with 516 additions and 949 deletions

View File

@ -1279,14 +1279,12 @@ class ChatControl(ChatControlBase):
self.video_state = self.JINGLE_STATE_NOT_AVAILABLE
self.update_toolbar()
self._mood_image = self.xml.get_widget('mood_image')
self._activity_image = self.xml.get_widget('activity_image')
self._tune_image = self.xml.get_widget('tune_image')
self.update_mood()
self.update_activity()
self.update_tune()
self._pep_images = {}
self._pep_images['mood'] = self.xml.get_widget('mood_image')
self._pep_images['activity'] = self.xml.get_widget('activity_image')
self._pep_images['tune'] = self.xml.get_widget('tune_image')
self.update_all_pep_types()
# keep timeout id and window obj for possible big avatar
# 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)
else:
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):
mood = None
text = None
def update_pep(self, pep_type):
if isinstance(self.contact, GC_Contact):
return
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):
if pep_type not in self._pep_images:
return
if 'activity' in self.contact.activity:
activity = self.contact.activity['activity'].strip()
if 'subactivity' in self.contact.activity:
subactivity = self.contact.activity['subactivity'].strip()
if 'text' in self.contact.activity:
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()
pep = self.contact.pep
img = self._pep_images[pep_type]
if pep_type in pep:
img.set_from_pixbuf(pep[pep_type].asPixbufIcon())
img.set_tooltip_markup(pep[pep_type].asMarkupText())
img.show()
else:
self._activity_image.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()
img.hide()
def _update_jingle(self, jingle_type):
if jingle_type not in ('audio', 'video'):

View File

@ -168,9 +168,7 @@ class Connection(ConnectionHandlers):
self.pubsub_supported = False
self.pubsub_publish_options_supported = False
self.pep_supported = False
self.mood = {}
self.tune = {}
self.activity = {}
self.pep = {}
# Do we continue connection when we get roster (send presence,get vcard..)
self.continue_connect_info = None
# Do we auto accept insecure connection

View File

@ -46,11 +46,10 @@ import common.xmpp
from common import helpers
from common import gajim
from common import atom
from common import pep
from common import exceptions
from common.commands import ConnectionCommands
from common.pubsub import ConnectionPubSub
from common.pep import ConnectionPEP
from common.caps import ConnectionCaps
if gajim.HAVE_FARSIGHT:
from common.jingle import ConnectionJingle
@ -1453,7 +1452,7 @@ sent a message to.'''
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):
ConnectionVcard.__init__(self)
ConnectionBytestream.__init__(self)
@ -1874,15 +1873,7 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco,
def _messageCB(self, con, msg):
'''Called when we receive a message'''
log.debug('MessageCB')
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)
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,
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):
'''Called when we receive a presence'''
ptype = prs.getType()
@ -2751,6 +2706,8 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco,
con.RegisterHandler('message', self._messageCB)
con.RegisterHandler('presence', self._presenceCB)
con.RegisterHandler('presence', self._capsPresenceCB)
con.RegisterHandler('message', self._pubsubEventCB,
ns=common.xmpp.NS_PUBSUB_EVENT)
con.RegisterHandler('iq', self._vCardCB, 'result',
common.xmpp.NS_VCARD)
con.RegisterHandler('iq', self._rosterSetCB, 'set',

View File

@ -94,7 +94,7 @@ class Contact(CommonContact):
def __init__(self, jid, account, name='', groups=[], show='', status='', sub='',
ask='', resource='', priority=0, keyID='', client_caps=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,
our_chatstate, composing_xep, chatstate, client_caps=client_caps)
@ -110,9 +110,7 @@ class Contact(CommonContact):
self.msg_id = msg_id
self.last_status_time = last_status_time
self.mood = mood.copy()
self.tune = tune.copy()
self.activity = activity.copy()
self.pep = {}
def get_full_jid(self):
if self.resource:
@ -229,23 +227,25 @@ class Contacts:
def create_contact(self, jid, account, name='', groups=[], show='', status='',
sub='', ask='', resource='', priority=0, keyID='', client_caps=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
return Contact(jid=jid, account=account, name=name, groups=groups,
show=show, status=status, sub=sub, ask=ask, resource=resource, priority=priority,
keyID=keyID, client_caps=client_caps, our_chatstate=our_chatstate,
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]
nick = common.gajim.nicks[account]
nick = name or common.gajim.nicks[account]
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,
sub='both', ask='none', priority=priority, keyID=keyID,
resource=resource, mood=conn.mood, tune=conn.tune,
activity=conn.activity)
resource=resource)
self_contact.pep = conn.pep
return self_contact
def create_not_in_roster_contact(self, jid, account, resource='', name='', keyID=''):
account = self._accounts.get(account, account) # Use Account object if available

View File

@ -569,8 +569,6 @@ def datetime_tuple(timestamp):
# import gajim only when needed (after decode_string is defined) see #4764
import gajim
import pep
def convert_bytes(string):
suffix = ''
@ -777,53 +775,6 @@ def get_global_status():
status = gajim.connections[account].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():
'''testing if all statuses are the same.'''

View File

@ -192,390 +192,371 @@ ACTIVITIES = {
'studying': _('Studying'),
'writing': _('Writing')}}
def user_mood(items, name, jid):
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
TUNE_DATA = ['artist', 'title', 'source', 'track', 'length']
if jid == common.gajim.get_jid_from_account(name):
acc = common.gajim.connections[name]
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']
import logging
log = logging.getLogger('gajim.c.pep')
(user, resource) = common.gajim.get_room_and_nick_from_fjid(jid)
for contact in common.gajim.contacts.get_contacts(name, user):
if has_child:
if 'mood' in contact.mood:
del contact.mood['mood']
if 'text' in contact.mood:
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']
import helpers
import atom
import gtkgui_helpers
import gobject
import gajim
import gtk
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):
has_child = False
retract = False
artist = None
title = None
source = None
track = None
length = None
def translate_mood(mood):
if mood in MOODS:
return MOODS[mood]
else:
return mood
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):
acc = common.gajim.connections[name]
if has_child:
if 'artist' in acc.tune:
del acc.tune['artist']
if 'title' in acc.tune:
del acc.tune['title']
if 'source' in acc.tune:
del acc.tune['source']
if 'track' in acc.tune:
del acc.tune['track']
if 'length' in acc.tune:
del acc.tune['length']
if artist is not None:
acc.tune['artist'] = artist
if title is not None:
acc.tune['title'] = title
if source is not None:
acc.tune['source'] = source
if track is not None:
acc.tune['track'] = track
if length is not None:
acc.tune['length'] = length
elif retract:
if 'artist' in acc.tune:
del acc.tune['artist']
if 'title' in acc.tune:
del acc.tune['title']
if 'source' in acc.tune:
del acc.tune['source']
if 'track' in acc.tune:
del acc.tune['track']
if 'length' in acc.tune:
del acc.tune['length']
class AbstractPEP(object):
type = ''
namespace = ''
@classmethod
def get_tag_as_PEP(cls, jid, account, event_tag):
items = event_tag.getTag('items', {'node': cls.namespace})
if items:
log.debug("Received PEP 'user %s' from %s" % (cls.type, jid))
return cls(jid, account, items)
else:
return None
def __init__(self, jid, account, items):
self._pep_specific_data, self._retracted = self._extract_info(items)
self._update_contacts(jid, account)
if jid == common.gajim.get_jid_from_account(account):
self._update_account(account)
def _extract_info(self, items):
'''To be implemented by subclasses'''
raise NotImplementedError
def _update_contacts(self, jid, account):
for contact in common.gajim.contacts.get_contacts(account, jid):
if self._retracted:
if self.type in contact.pep:
del contact.pep[self.type]
else:
contact.pep[self.type] = self
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):
common.gajim.interface.roster.draw_account(name)
common.gajim.interface.roster.draw_tune(user, name)
ctrl = common.gajim.interface.msg_win_mgr.get_control(user, name)
if ctrl:
ctrl.update_tune()
class UserTunePEP(AbstractPEP):
'''XEP-0118: User Tune'''
type = 'tune'
namespace = common.xmpp.NS_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):
pass
artist = tune.get('artist', _('Unknown Artist'))
artist = gobject.markup_escape_text(artist)
title = tune.get('title', _('Unknown Title'))
title = gobject.markup_escape_text(title)
def user_activity(items, name, jid):
has_child = False
retract = False
activity = None
subactivity = None
text = None
source = tune.get('source', _('Unknown Source'))
source = gobject.markup_escape_text(source)
for item in items.getTags('item'):
child = item.getTag('activity')
if child is not None:
has_child = True
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
tune_string = _('<b>"%(title)s"</b> by <i>%(artist)s</i>\n'
'from <i>%(source)s</i>') % {'title': title,
'artist': artist, 'source': source}
return tune_string
if jid == common.gajim.get_jid_from_account(name):
acc = common.gajim.connections[name]
if has_child:
if 'activity' in acc.activity:
del acc.activity['activity']
if 'subactivity' in acc.activity:
del acc.activity['subactivity']
if 'text' in acc.activity:
del acc.activity['text']
if activity is not None:
acc.activity['activity'] = activity
if subactivity is not None and subactivity != 'other':
acc.activity['subactivity'] = subactivity
if text is not None:
acc.activity['text'] = text
elif retract:
if 'activity' in acc.activity:
del acc.activity['activity']
if 'subactivity' in acc.activity:
del acc.activity['subactivity']
if 'text' in acc.activity:
del acc.activity['text']
class UserActivityPEP(AbstractPEP):
'''XEP-0108: User Activity'''
type = 'activity'
namespace = common.xmpp.NS_ACTIVITY
def _extract_info(self, items):
activity_dict = {}
for item in items.getTags('item'):
activity_tag = item.getTag('activity')
if activity_tag:
for child in activity_tag.getChildren():
name = child.getName().strip()
data = child.getData().strip()
if name == 'text':
activity_dict['text'] = data
else:
activity_dict['activity'] = name
for subactivity in child.getChildren():
subactivity_name = subactivity.getName().strip()
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]
for contact in common.gajim.contacts.get_contacts(name, user):
if has_child:
if 'activity' in contact.activity:
del contact.activity['activity']
if 'subactivity' in contact.activity:
del contact.activity['subactivity']
if 'text' in contact.activity:
del contact.activity['text']
if activity is not None:
contact.activity['activity'] = activity
if subactivity is not None and subactivity != 'other':
contact.activity['subactivity'] = subactivity
if text is not None:
contact.activity['text'] = text
elif retract:
if 'activity' in contact.activity:
del contact.activity['activity']
if 'subactivity' in contact.activity:
del contact.activity['subactivity']
if 'text' in contact.activity:
del contact.activity['text']
if activity in ACTIVITIES:
# Translate standard activities
if subactivity in ACTIVITIES[activity]:
subactivity = ACTIVITIES[activity][subactivity]
activity = ACTIVITIES[activity]['category']
markuptext = '<b>' + gobject.markup_escape_text(activity)
if subactivity:
markuptext += ': ' + gobject.markup_escape_text(subactivity)
markuptext += '</b>'
if text:
markuptext += ' (%s)' % gobject.markup_escape_text(text)
return markuptext
class UserNicknamePEP(AbstractPEP):
'''XEP-0172: User Nickname'''
type = 'nickname'
namespace = common.xmpp.NS_NICK
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)
common.gajim.interface.roster.draw_activity(user, name)
ctrl = common.gajim.interface.msg_win_mgr.get_control(user, name)
if ctrl:
ctrl.update_activity()
SUPPORTED_PERSONAL_USER_EVENTS = [UserMoodPEP, UserTunePEP, UserActivityPEP,
UserNicknamePEP]
def user_nickname(items, name, jid):
has_child = False
retract = False
nick = None
class ConnectionPEP(object):
def _pubsubEventCB(self, xmpp_dispatcher, msg):
''' 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'):
child = item.getTag('nick')
if child is not None:
has_child = True
nick = child.getData()
break
for pep_class in SUPPORTED_PERSONAL_USER_EVENTS:
pep = pep_class.get_tag_as_PEP(jid, self.name, event_tag)
if pep:
self.dispatch('PEP_RECEIVED', (jid, pep.type))
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:
retract = True
def send_mood(self, mood, message=None):
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):
if has_child:
common.gajim.nicks[name] = nick
if retract:
common.gajim.nicks[name] = common.gajim.config.get_per('accounts',
name, 'name')
def retract_tune(self):
if not self.pep_supported:
return
# not all server support retract, so send empty pep first
self.send_tune(None)
self.send_pb_retract('', xmpp.NS_TUNE, '0')
user = common.gajim.get_room_and_nick_from_fjid(jid)[0]
if has_child:
if nick is not None:
for contact in common.gajim.contacts.get_contacts(name, user):
contact.contact_name = nick
common.gajim.interface.roster.draw_contact(user, name)
def send_nickname(self, nick):
if not self.pep_supported:
return
item = xmpp.Node('nick', {'xmlns': xmpp.NS_NICK})
item.addData(nick)
self.send_pb_publish('', xmpp.NS_NICK, item, '0')
ctrl = common.gajim.interface.msg_win_mgr.get_control(user, name)
if ctrl:
ctrl.update_ui()
win = ctrl.parent_win
win.redraw_tab(ctrl)
win.show_title()
elif retract:
contact.contact_name = ''
def retract_nickname(self):
if not self.pep_supported:
return
# not all server support retract, so send empty pep first
self.send_tune(None)
self.send_pb_retract('', xmpp.NS_NICK, '0')
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:

View File

@ -247,25 +247,23 @@ class XMPPDispatcher(PlugIn):
'''
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.
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
importantly library from returning stanza to sender with error set.
to prevent other callbacks to be called with the same stanza as argument
_and_, more importantly library from returning stanza to sender with error set.
:param name: name of stanza. F.e. "iq".
:param handler: user callback.
:param typ: value of stanza's "type" attribute. If not specified any
value will match
: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 instea
:param makefirst: insert handler in the beginning of handlers list instead
of adding it to the end. Note that more common handlers i.e. w/o "typ"
and " will be called first nevertheless.
:param system: call handler even if NodeProcessed Exception were raised
already.
'''
# FIXME: What does chain mean and where is it handled?
if not xmlns:
xmlns=self._owner.defaultNamespace
log.debug('Registering handler %s for "%s" type->%s ns->%s(%s)' %

View File

@ -88,6 +88,7 @@ NS_PRIVACY ='jabber:iq:privacy'
NS_PRIVATE ='jabber:iq:private'
NS_PROFILE ='http://jabber.org/protocol/profile' # XEP-0154
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_OWNER ='http://jabber.org/protocol/pubsub#owner' # JEP-0060
NS_REGISTER ='jabber:iq:register'

View File

@ -88,9 +88,7 @@ class ConnectionZeroconf(ConnectionHandlersZeroconf):
self.no_log_for = False
self.pep_supported = False
self.mood = {}
self.tune = {}
self.activity = {}
self.pep = {}
# Do we continue connection when we get roster (send presence,get vcard...)
self.continue_connect_info = None
if gajim.HAVE_GPG:

View File

@ -1989,6 +1989,27 @@ class Interface:
_('PEP node %(node)s was not removed: %(message)s') % {
'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):
if event not in self.handlers:
self.handlers[event] = []
@ -2088,6 +2109,7 @@ class Interface:
'JINGLE_CONNECTED': [self.handle_event_jingle_connected],
'JINGLE_DISCONNECTED': [self.handle_event_jingle_disconnected],
'JINGLE_ERROR': [self.handle_event_jingle_error],
'PEP_RECEIVED': [self.handle_event_pep_received]
}
def dispatch(self, event, account, data):
@ -2774,33 +2796,27 @@ class Interface:
listener.disconnect(self.music_track_changed_signal)
self.music_track_changed_signal = None
def music_track_changed(self, unused_listener, music_track_info, account=''):
if account == '':
def music_track_changed(self, unused_listener, music_track_info, account=None):
if not account:
accounts = gajim.connections.keys()
else:
accounts = [account]
if music_track_info is None:
artist = ''
title = ''
source = ''
elif hasattr(music_track_info, 'paused') and music_track_info.paused == 0:
artist = ''
title = ''
source = ''
is_paused = hasattr(music_track_info, 'paused') and music_track_info.paused == 0
if not music_track_info or is_paused:
artist = title = source = ''
else:
artist = music_track_info.artist
title = music_track_info.title
source = music_track_info.album
for acct in accounts:
if acct not in gajim.connections:
continue
if not gajim.account_is_connected(acct):
continue
if not gajim.connections[acct].pep_supported:
if not gajim.config.get_per('accounts', acct, 'publish_tune'):
continue
if gajim.connections[acct].music_track_info == music_track_info:
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
def get_bg_fg_colors(self):

View File

@ -322,8 +322,7 @@ class ProfileWindow:
nick = ''
if 'NICKNAME' in vcard_:
nick = vcard_['NICKNAME']
from common import pep
pep.user_send_nickname(self.account, nick)
gajim.connections[self.account].send_nickname(self.account, nick)
if nick == '':
nick = gajim.config.get_per('accounts', self.account, 'name')
gajim.nicks[self.account] = nick

View File

@ -1022,55 +1022,21 @@ class RosterWindow:
self.model[child_iter][C_NAME] = account_name
if gajim.config.get('show_mood_in_roster') \
and 'mood' in gajim.connections[account].mood \
and gajim.connections[account].mood['mood'].strip() in MOODS:
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()
pep = gajim.connections[account].pep
if gajim.config.get('show_mood_in_roster') and 'mood' in pep:
self.model[child_iter][C_MOOD_PIXBUF] = pep['mood'].asPixbufIcon()
else:
self.model[child_iter][C_MOOD_PIXBUF] = None
if gajim.config.get('show_activity_in_roster') \
and 'activity' in gajim.connections[account].activity \
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()
if gajim.config.get('show_activity_in_roster') and 'activity' in pep:
self.model[child_iter][C_ACTIVITY_PIXBUF] = pep['activity'].asPixbufIcon()
else:
self.model[child_iter][C_ACTIVITY_PIXBUF] = None
if gajim.config.get('show_tunes_in_roster') \
and ('artist' in gajim.connections[account].tune \
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)
if gajim.config.get('show_tunes_in_roster') and 'tune' in pep:
self.model[child_iter][C_TUNE_PIXBUF] = pep['tune'].asPixbufIcon()
else:
self.model[child_iter][C_TUNE_PIXBUF] = None
return False
def draw_group(self, group, account):
@ -1276,71 +1242,39 @@ class RosterWindow:
return False
def draw_mood(self, jid, account):
def _is_pep_shown_in_roster(self, pep_type):
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)
if not iters or not gajim.config.get('show_mood_in_roster'):
if not iters:
return
jid = self.model[iters[0]][C_JID]
jid = jid.decode('utf-8')
contact = gajim.contacts.get_contact(account, jid)
if 'mood' in contact.mood and contact.mood['mood'].strip() in MOODS:
pixbuf = gtkgui_helpers.load_mood_icon(
contact.mood['mood'].strip()).get_pixbuf()
elif 'mood' in contact.mood:
pixbuf = gtkgui_helpers.load_mood_icon(
'unknown').get_pixbuf()
if pep_type in contact.pep:
pixbuf = contact.pep[pep_type].asPixbufIcon()
else:
pixbuf = None
for child_iter in iters:
self.model[child_iter][C_MOOD_PIXBUF] = 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
self.model[child_iter][model_column] = pixbuf
def draw_avatar(self, jid, account):
iters = self._get_contact_iter(jid, account, model=self.model)
@ -1359,9 +1293,7 @@ class RosterWindow:
def draw_completely(self, jid, account):
self.draw_contact(jid, account)
self.draw_mood(jid, account)
self.draw_activity(jid, account)
self.draw_tune(jid, account)
self.draw_all_pep_types(jid, account)
self.draw_avatar(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)
def send_pep(self, account, pep_dict=None):
'''Sends pep information (activity, mood)'''
if not pep_dict:
return
# activity
if 'activity' in pep_dict and pep_dict['activity'] in pep.ACTIVITIES:
def send_pep(self, account, pep_dict):
connection = gajim.connections[account]
if 'activity' in pep_dict:
activity = pep_dict['activity']
if 'subactivity' in pep_dict and \
pep_dict['subactivity'] in pep.ACTIVITIES[activity]:
subactivity = pep_dict['subactivity']
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)
subactivity = pep_dict.get('subactivity', None)
activity_text = pep_dict.get('activity_text', None)
connection.send_activity(activity, subactivity, activity_text)
else:
pep.user_send_activity(account, '')
connection.retract_activity()
# mood
if 'mood' in pep_dict and pep_dict['mood'] in pep.MOODS:
if 'mood' in pep_dict:
mood = pep_dict['mood']
if 'mood_text' in pep_dict:
mood_text = pep_dict['mood_text']
else:
mood_text = ''
pep.user_send_mood(account, mood, mood_text)
mood_text = pep_dict.get('mood_text', None)
connection.send_mood(mood, mood_text)
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):
if gajim.account_is_connected(account) and not to:
@ -2008,8 +1940,7 @@ class RosterWindow:
gajim.connections[account].send_custom_status(status, txt, to)
else:
if status in ('invisible', 'offline'):
pep.delete_pep(gajim.get_jid_from_account(account), \
account)
self.delete_pep(gajim.get_jid_from_account(account), account)
was_invisible = gajim.connections[account].connected == \
gajim.SHOW_LIST.index('invisible')
gajim.connections[account].change_status(status, txt, auto)
@ -2087,7 +2018,7 @@ class RosterWindow:
contact_instances)
if not keep_pep and contact.jid != gajim.get_jid_from_account(account) \
and not contact.is_groupchat():
pep.delete_pep(contact.jid, account)
self.delete_pep(contact.jid, account)
# Redraw everything and select the sender
self.adjust_and_draw_contact_context(contact.jid, account)
@ -2501,11 +2432,10 @@ class RosterWindow:
account_name = account
if gajim.account_is_connected(account):
account_name += ' (%s/%s)' % (repr(nbr_on), repr(nbr_total))
contact = gajim.contacts.create_contact(jid=jid, account=account, name=account_name,
show=connection.get_status(), sub='', status=connection.status,
resource=connection.server_resource,
priority=connection.priority, mood=connection.mood,
tune=connection.tune, activity=connection.activity)
contact = gajim.contacts.create_self_contact(jid=jid, account=account,
name=account_name, show=connection.get_status(),
status=connection.status, resource=connection.server_resource,
priority=connection.priority)
if gajim.connections[account].gpg:
contact.keyID = gajim.config.get_per('accounts', connection.name,
'keyid')
@ -3388,23 +3318,19 @@ class RosterWindow:
gajim.interface.instances['preferences'] = config.PreferencesWindow()
def on_publish_tune_toggled(self, widget, account):
act = widget.get_active()
gajim.config.set_per('accounts', account, 'publish_tune', act)
if act:
active = widget.get_active()
gajim.config.set_per('accounts', account, 'publish_tune', active)
if active:
gajim.interface.enable_music_listener()
else:
# disable it only if no other account use it
for acct in gajim.connections:
if gajim.config.get_per('accounts', acct, 'publish_tune'):
gajim.connections[account].retract_tune()
# disable music listener only if no other account uses it
for acc in gajim.connections:
if gajim.config.get_per('accounts', acc, 'publish_tune'):
break
else:
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)
def on_pep_services_menuitem_activate(self, widget, account):
@ -4481,9 +4407,9 @@ class RosterWindow:
renderer.set_property('xpad', 8)
def _fill_mood_pixbuf_renderer(self, column, renderer, model, titer,
data = None):
'''When a row is added, set properties for avatar renderer'''
def _fill_pep_pixbuf_renderer(self, column, renderer, model, titer,
data=None):
'''When a row is added, draw the respective pep icon'''
theme = gajim.config.get('roster_theme')
type_ = model[titer][C_TYPE]
if type_ == 'group':
@ -4491,155 +4417,37 @@ class RosterWindow:
return
# allocate space for the icon only if needed
if model[titer][C_MOOD_PIXBUF]:
if model[titer][data]:
renderer.set_property('visible', True)
else:
renderer.set_property('visible', False)
if type_ == 'account':
color = gajim.config.get_per('themes', theme,
'accountbgcolor')
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)
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]:
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(
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(
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)
color = gajim.config.get_per('themes', theme, 'contactbgcolor')
renderer.set_property('cell-background', color if color else None)
# align pixbuf to the right
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,
data = None):
'''When a row is added, set properties for avatar renderer'''
@ -5933,19 +5741,23 @@ class RosterWindow:
col.pack_start(render_pixbuf, expand=False)
col.add_attribute(render_pixbuf, 'pixbuf', C_MOOD_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()
col.pack_start(render_pixbuf, expand=False)
col.add_attribute(render_pixbuf, 'pixbuf', C_ACTIVITY_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()
col.pack_start(render_pixbuf, expand=False)
col.add_attribute(render_pixbuf, 'pixbuf', C_TUNE_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':
add_avatar_renderer()

View File

@ -579,65 +579,19 @@ class RosterTooltip(NotificationAreaTooltip):
Append Tune, Mood, Activity information of the specified contact
to the given property list.
'''
if 'mood' in contact.mood:
mood = contact.mood['mood'].strip()
mood = MOODS.get(mood, 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
if 'mood' in contact.pep:
mood = contact.pep['mood'].asMarkupText()
mood_string = _('Mood:') + ' %s' % mood
properties.append((mood_string, None))
if 'activity' in contact.activity:
activity = act_plain = \
contact.activity['activity'].strip()
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
if 'activity' in contact.pep:
activity = contact.pep['activity'].asMarkupText()
activity_string = _('Activity:') + ' %s' % activity
properties.append((activity_string, None))
if 'artist' in contact.tune \
or 'title' in contact.tune:
if 'artist' in contact.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}
if 'tune' in contact.pep:
tune = contact.pep['tune'].asMarkupText()
tune_string = _('Tune:') + ' %s' % tune
properties.append((tune_string, None))

View File

@ -14,9 +14,7 @@ class MockConnection(Mock, ConnectionHandlersBase):
self.name = account
self.connected = 2
self.mood = {}
self.activity = {}
self.tune = {}
self.pep = {}
self.blocked_contacts = {}
self.blocked_groups = {}
self.sessions = {}