Listen for and respond to Owner property changes

Pass the PS's owner object to each plugin.  Make the server plugin
listen to property changes and push those changes to the Jabber
server when they occur.
This commit is contained in:
Dan Williams 2007-03-09 16:29:49 -05:00
parent d299cd4032
commit 9d837710f5
3 changed files with 47 additions and 33 deletions

View File

@ -18,9 +18,10 @@
import gobject import gobject
class LinkLocalPlugin(gobject.GObject): class LinkLocalPlugin(gobject.GObject):
def __init__(self, registry): def __init__(self, registry, owner):
gobject.GObject.__init__(self) gobject.GObject.__init__(self)
self._registry = registry self._registry = registry
self._owner = owner
def cleanup(self): def cleanup(self):
pass pass

View File

@ -58,7 +58,7 @@ class PresenceService(dbus.service.Object):
self._registry.LoadManagers() self._registry.LoadManagers()
# Set up the server connection # Set up the server connection
self._server_plugin = ServerPlugin(self._registry) self._server_plugin = ServerPlugin(self._registry, self._owner)
self._handles_buddies[self._server_plugin] = {} self._handles_buddies[self._server_plugin] = {}
self._server_plugin.connect('status', self._server_status_cb) self._server_plugin.connect('status', self._server_status_cb)
@ -72,7 +72,7 @@ class PresenceService(dbus.service.Object):
self._server_plugin.start() self._server_plugin.start()
# Set up the link local connection # Set up the link local connection
self._ll_plugin = LinkLocalPlugin(self._registry) self._ll_plugin = LinkLocalPlugin(self._registry, self._owner)
self._handles_buddies[self._ll_plugin] = {} self._handles_buddies[self._ll_plugin] = {}
dbus.service.Object.__init__(self, self._bus_name, _PRESENCE_PATH) dbus.service.Object.__init__(self, self._bus_name, _PRESENCE_PATH)

View File

@ -43,31 +43,36 @@ _PROTOCOL = "jabber"
class InvalidBuddyError(Exception): class InvalidBuddyError(Exception):
pass pass
def _get_buddy_icon_at_size(maxw, maxh, maxsize): def _buddy_icon_save_cb(buf, data):
icon = os.path.join(env.get_profile_path(), "buddy-icon.jpg") data[0] += buf
pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(icon, maxw, maxh) return True
obj = {} def _get_buddy_icon_at_size(icon, maxw, maxh, maxsize):
obj['data'] = "" loader = gtk.gdk.PixbufLoader()
loader.write(icon)
loader.close()
unscaled_pixbuf = loader.get_pixbuf()
del loader
pixbuf = unscaled_pixbuf.scale_simple(maxw, maxh, gtk.gdk.INTERP_BILINEAR)
del unscaled_pixbuf
data = [""]
quality = 90 quality = 90
img_size = maxsize + 1 img_size = maxsize + 1
while img_size > maxsize: while img_size > maxsize:
del obj['data'] del data
obj['data'] = "" data = [""]
pixbuf.save_to_callback(_buddy_icon_save_cb, "jpeg", {"quality":"%d" % quality}, obj) pixbuf.save_to_callback(_buddy_icon_save_cb, "jpeg", {"quality":"%d" % quality}, data)
quality -= 10 quality -= 10
img_size = len(obj['data']) img_size = len(data[0])
del pixbuf del pixbuf
if img_size > maxsize: if img_size > maxsize:
del obj['data'] del data
raise RuntimeError("could not size image less than %d bytes" % maxsize) raise RuntimeError("could not size image less than %d bytes" % maxsize)
return obj['data'] return str(data[0])
def _buddy_icon_save_cb(buf, obj):
obj['data'] += buf
return True
class ServerPlugin(gobject.GObject): class ServerPlugin(gobject.GObject):
@ -90,7 +95,7 @@ class ServerPlugin(gobject.GObject):
([gobject.TYPE_PYOBJECT])) ([gobject.TYPE_PYOBJECT]))
} }
def __init__(self, registry): def __init__(self, registry, owner):
gobject.GObject.__init__(self) gobject.GObject.__init__(self)
self._icon_cache = BuddyIconCache() self._icon_cache = BuddyIconCache()
@ -100,16 +105,29 @@ class ServerPlugin(gobject.GObject):
self._activities = {} # activity id -> handle self._activities = {} # activity id -> handle
self._joined_activities = [] # (activity_id, handle of the activity channel) self._joined_activities = [] # (activity_id, handle of the activity channel)
self._owner = owner
self._owner.connect("property-changed", self._owner_property_changed_cb)
self._owner.connect("icon-changed", self._owner_icon_changed_cb)
self._account = self._get_account_info() self._account = self._get_account_info()
self._conn = self._init_connection() self._conn = self._init_connection()
self._reconnect_id = 0 self._reconnect_id = 0
def _owner_property_changed_cb(self, owner, properties):
print "Owner properties changed: %s" % properties
self._set_self_buddy_info()
def _owner_icon_changed_cb(self, owner, icon):
print "Owner icon changed to size %d" % len(str(icon))
self._upload_avatar()
def _get_account_info(self): def _get_account_info(self):
account_info = {} account_info = {}
pubkey = profile.get_pubkey() pubkey = self._owner.props.key
server = profile.get_server() server = profile.get_server()
if not server: if not server:
@ -231,12 +249,10 @@ class ServerPlugin(gobject.GObject):
self._conn[CONN_INTERFACE_PRESENCE].GetPresence(subscribe_handles) self._conn[CONN_INTERFACE_PRESENCE].GetPresence(subscribe_handles)
def _upload_avatar(self): def _upload_avatar(self):
icon = os.path.join(env.get_profile_path(), "buddy-icon.jpg") icon_data = self._owner.props.icon
if not os.path.exists(icon):
return
md5 = hashlib.md5() md5 = hashlib.md5()
md5.update(open(icon).read()) md5.update(icon_data)
hash = md5.hexdigest() hash = md5.hexdigest()
self_handle = self._conn[CONN_INTERFACE].GetSelfHandle() self_handle = self._conn[CONN_INTERFACE].GetSelfHandle()
@ -251,12 +267,9 @@ class ServerPlugin(gobject.GObject):
print "server does not accept JPEG format avatars." print "server does not accept JPEG format avatars."
return return
try: img_data = _get_buddy_icon_at_size(icon_data, min(maxw, 96), min(maxh, 96), maxsize)
img_data = _get_buddy_icon_at_size(min(maxw, 96), min(maxh, 96), maxsize) token = self._conn[CONN_INTERFACE_AVATARS].SetAvatar(img_data, "image/jpeg")
token = self._conn[CONN_INTERFACE_AVATARS].SetAvatar(img_data, "image/jpeg") self._icon_cache.set_avatar(hash, token)
self._icon_cache.set_avatar(hash, token)
except RuntimeError, e:
pass
def join_activity(self, act): def join_activity(self, act):
handle = self._activities.get(act) handle = self._activities.get(act)
@ -282,15 +295,15 @@ class ServerPlugin(gobject.GObject):
def _set_self_buddy_info(self): def _set_self_buddy_info(self):
# Set our OLPC buddy properties # Set our OLPC buddy properties
props = {} props = {}
props['color'] = profile.get_color().to_string() props['color'] = self._owner.props.color
props['key'] = profile.get_pubkey() props['key'] = self._owner.props.key
try: try:
self._conn[CONN_INTERFACE_BUDDY_INFO].SetProperties(props) self._conn[CONN_INTERFACE_BUDDY_INFO].SetProperties(props)
except dbus.DBusException, e: except dbus.DBusException, e:
if str(e).find("Server does not support PEP") >= 0: if str(e).find("Server does not support PEP") >= 0:
raise RuntimeError("Server does not support PEP") raise RuntimeError("Server does not support PEP")
name = profile.get_nick_name() name = self._owner.props.nick
self_handle = self._conn[CONN_INTERFACE].GetSelfHandle() self_handle = self._conn[CONN_INTERFACE].GetSelfHandle()
self._conn[CONN_INTERFACE_ALIASING].SetAliases( {self_handle : name} ) self._conn[CONN_INTERFACE_ALIASING].SetAliases( {self_handle : name} )