Merge branch 'master' of git+ssh://dev.laptop.org/git/sugar
This commit is contained in:
commit
d0a564e035
@ -69,15 +69,15 @@ class BundleRegistry(gobject.GObject):
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
gobject.GObject.__init__(self)
|
gobject.GObject.__init__(self)
|
||||||
|
|
||||||
self._bundles = {}
|
self._bundles = []
|
||||||
self._search_path = []
|
self._search_path = []
|
||||||
self._service_manager = _ServiceManager()
|
self._service_manager = _ServiceManager()
|
||||||
|
|
||||||
def get_bundle(self, service_name):
|
def get_bundle(self, service_name):
|
||||||
"""Returns an bundle given his service name"""
|
"""Returns an bundle given his service name"""
|
||||||
if self._bundles.has_key(service_name):
|
for bundle in self._bundles:
|
||||||
return self._bundles[service_name]
|
if bundle.get_service_name() == service_name:
|
||||||
else:
|
return bundle
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def add_search_path(self, path):
|
def add_search_path(self, path):
|
||||||
@ -86,20 +86,30 @@ class BundleRegistry(gobject.GObject):
|
|||||||
self._scan_directory(path)
|
self._scan_directory(path)
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
return self._bundles.values().__iter__()
|
return self._bundles.__iter__()
|
||||||
|
|
||||||
def _scan_directory(self, path):
|
def _scan_directory(self, path):
|
||||||
if os.path.isdir(path):
|
if not os.path.isdir(path):
|
||||||
|
return
|
||||||
|
|
||||||
|
# Sort by mtime to ensure a stable activity order
|
||||||
|
bundles = {}
|
||||||
for f in os.listdir(path):
|
for f in os.listdir(path):
|
||||||
|
if not f.endswith('.activity'):
|
||||||
|
continue
|
||||||
bundle_dir = os.path.join(path, f)
|
bundle_dir = os.path.join(path, f)
|
||||||
if os.path.isdir(bundle_dir) and \
|
if os.path.isdir(bundle_dir):
|
||||||
bundle_dir.endswith('.activity'):
|
bundles[bundle_dir] = os.stat(bundle_dir).st_mtime
|
||||||
self.add_bundle(bundle_dir)
|
|
||||||
|
bundle_dirs = bundles.keys()
|
||||||
|
bundle_dirs.sort(lambda d1,d2: cmp(bundles[d1], bundles[d2]))
|
||||||
|
for dir in bundle_dirs:
|
||||||
|
self.add_bundle(dir)
|
||||||
|
|
||||||
def add_bundle(self, bundle_path):
|
def add_bundle(self, bundle_path):
|
||||||
bundle = Bundle(bundle_path)
|
bundle = Bundle(bundle_path)
|
||||||
if bundle.is_valid():
|
if bundle.is_valid():
|
||||||
self._bundles[bundle.get_service_name()] = bundle
|
self._bundles.append(bundle)
|
||||||
self._service_manager.add(bundle)
|
self._service_manager.add(bundle)
|
||||||
self.emit('bundle-added', bundle)
|
self.emit('bundle-added', bundle)
|
||||||
return True
|
return True
|
||||||
@ -108,7 +118,7 @@ class BundleRegistry(gobject.GObject):
|
|||||||
|
|
||||||
def get_activities_for_type(self, mime_type):
|
def get_activities_for_type(self, mime_type):
|
||||||
result = []
|
result = []
|
||||||
for bundle in self._bundles.values():
|
for bundle in self._bundles:
|
||||||
if bundle.get_mime_types() and mime_type in bundle.get_mime_types():
|
if bundle.get_mime_types() and mime_type in bundle.get_mime_types():
|
||||||
result.append(bundle)
|
result.append(bundle)
|
||||||
return result
|
return result
|
||||||
|
@ -3,5 +3,6 @@ sugar_PYTHON = \
|
|||||||
__init__.py \
|
__init__.py \
|
||||||
activity.py \
|
activity.py \
|
||||||
buddy.py \
|
buddy.py \
|
||||||
|
tubeconn.py \
|
||||||
presenceservice.py
|
presenceservice.py
|
||||||
|
|
||||||
|
107
sugar/presence/tubeconn.py
Normal file
107
sugar/presence/tubeconn.py
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
# This should eventually land in telepathy-python, so has the same license:
|
||||||
|
|
||||||
|
# Copyright (C) 2007 Collabora Ltd. <http://www.collabora.co.uk/>
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License as published
|
||||||
|
# by the Free Software Foundation; either version 2.1 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = ('TubeConnection',)
|
||||||
|
__docformat__ = 'reStructuredText'
|
||||||
|
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from dbus.connection import Connection
|
||||||
|
|
||||||
|
|
||||||
|
logger = logging.getLogger('telepathy.tubeconn')
|
||||||
|
|
||||||
|
|
||||||
|
class TubeConnection(Connection):
|
||||||
|
|
||||||
|
def __new__(cls, conn, tubes_iface, tube_id, address=None,
|
||||||
|
group_iface=None, mainloop=None):
|
||||||
|
if address is None:
|
||||||
|
address = tubes_iface.GetDBusServerAddress(tube_id)
|
||||||
|
self = super(TubeConnection, cls).__new__(cls, address,
|
||||||
|
mainloop=mainloop)
|
||||||
|
|
||||||
|
self._tubes_iface = tubes_iface
|
||||||
|
self.tube_id = tube_id
|
||||||
|
self.participants = {}
|
||||||
|
self.bus_name_to_handle = {}
|
||||||
|
self._mapping_watches = []
|
||||||
|
|
||||||
|
if group_iface is None:
|
||||||
|
method = conn.GetSelfHandle
|
||||||
|
else:
|
||||||
|
method = group_iface.GetSelfHandle
|
||||||
|
method(reply_handler=self._on_get_self_handle_reply,
|
||||||
|
error_handler=self._on_get_self_handle_error)
|
||||||
|
|
||||||
|
return self
|
||||||
|
|
||||||
|
def _on_get_self_handle_reply(self, handle):
|
||||||
|
self.self_handle = handle
|
||||||
|
match = self._tubes_iface.connect_to_signal('DBusNamesChanged',
|
||||||
|
self._on_dbus_names_changed)
|
||||||
|
self._tubes_iface.GetDBusNames(self.tube_id,
|
||||||
|
reply_handler=self._on_get_dbus_names_reply,
|
||||||
|
error_handler=self._on_get_dbus_names_error)
|
||||||
|
self._dbus_names_changed_match = match
|
||||||
|
|
||||||
|
def _on_get_self_handle_error(self, e):
|
||||||
|
logging.basicConfig()
|
||||||
|
logger.error('GetSelfHandle failed: %s', e)
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
self._dbus_names_changed_match.remove()
|
||||||
|
self._on_dbus_names_changed(self.tube_id, (), self.participants.keys())
|
||||||
|
super(TubeConnection, self).close()
|
||||||
|
|
||||||
|
def _on_get_dbus_names_reply(self, names):
|
||||||
|
self._on_dbus_names_changed(self.tube_id, names, ())
|
||||||
|
|
||||||
|
def _on_get_dbus_names_error(self, e):
|
||||||
|
logging.basicConfig()
|
||||||
|
logger.error('GetDBusNames failed: %s', e)
|
||||||
|
|
||||||
|
def _on_dbus_names_changed(self, tube_id, added, removed):
|
||||||
|
if tube_id == self.tube_id:
|
||||||
|
for handle, bus_name in added:
|
||||||
|
if handle == self.self_handle:
|
||||||
|
# I've just joined - set my unique name
|
||||||
|
self.set_unique_name(bus_name)
|
||||||
|
self.participants[handle] = bus_name
|
||||||
|
self.bus_name_to_handle[bus_name] = handle
|
||||||
|
|
||||||
|
# call the callback while the removed people are still in
|
||||||
|
# participants, so their bus names are available
|
||||||
|
for callback in self._mapping_watches:
|
||||||
|
callback(added, removed)
|
||||||
|
|
||||||
|
for handle in removed:
|
||||||
|
bus_name = self.participants.pop(handle, None)
|
||||||
|
self.bus_name_to_handle.pop(bus_name, None)
|
||||||
|
|
||||||
|
def watch_participants(self, callback):
|
||||||
|
self._mapping_watches.append(callback)
|
||||||
|
if self.participants:
|
||||||
|
# GetDBusNames already returned: fake a participant add event
|
||||||
|
# immediately
|
||||||
|
added = []
|
||||||
|
for k, v in self.participants.iteritems():
|
||||||
|
added.append((k, v))
|
||||||
|
callback(added, [])
|
Loading…
Reference in New Issue
Block a user