Changed all tabs to 4 spaces for python style

This commit is contained in:
Justin Gallardo
2006-12-04 11:12:24 -08:00
parent f5ae066248
commit b9f9ef0fe9
110 changed files with 9987 additions and 9987 deletions
+25 -25
View File
@@ -22,33 +22,33 @@ import signal
haveThreadframe = True
try:
import threadframe
import threadframe
except ImportError:
haveThreadframe = False
haveThreadframe = False
class TracebackHelper(object):
def __init__(self):
fname = "%s-%d" % (os.path.basename(sys.argv[0]), os.getpid())
self._fpath = os.path.join("/tmp", fname)
print "Tracebacks will be written to %s on SIGUSR1" % self._fpath
signal.signal(signal.SIGUSR1, self._handler)
def __init__(self):
fname = "%s-%d" % (os.path.basename(sys.argv[0]), os.getpid())
self._fpath = os.path.join("/tmp", fname)
print "Tracebacks will be written to %s on SIGUSR1" % self._fpath
signal.signal(signal.SIGUSR1, self._handler)
def __del__(self):
try:
os.remove(self._fpath)
except OSError:
pass
def __del__(self):
try:
os.remove(self._fpath)
except OSError:
pass
def _handler(self, signum, pframe):
f = open(self._fpath, "a")
if not haveThreadframe:
f.write("Threadframe not installed. No traceback available.\n")
else:
frames = threadframe.dict()
for thread_id, frame in frames.iteritems():
f.write(('-' * 79) + '\n')
f.write('[Thread %s] %d' % (thread_id, sys.getrefcount(frame)) + '\n')
traceback.print_stack(frame, limit=None, file=f)
f.write("\n")
f.write('\n')
f.close()
def _handler(self, signum, pframe):
f = open(self._fpath, "a")
if not haveThreadframe:
f.write("Threadframe not installed. No traceback available.\n")
else:
frames = threadframe.dict()
for thread_id, frame in frames.iteritems():
f.write(('-' * 79) + '\n')
f.write('[Thread %s] %d' % (thread_id, sys.getrefcount(frame)) + '\n')
traceback.print_stack(frame, limit=None, file=f)
f.write("\n")
f.write('\n')
f.close()
+100 -100
View File
@@ -32,133 +32,133 @@ ACTIVITY_SERVICE_PATH = "/org/laptop/Activity"
ACTIVITY_INTERFACE = "org.laptop.Activity"
def get_service_name(xid):
return ACTIVITY_SERVICE_NAME + '%d' % xid
return ACTIVITY_SERVICE_NAME + '%d' % xid
def get_object_path(xid):
return ACTIVITY_SERVICE_PATH + "/%s" % xid
return ACTIVITY_SERVICE_PATH + "/%s" % xid
class ActivityDbusService(dbus.service.Object):
"""Base dbus service object that each Activity uses to export dbus methods.
The dbus service is separate from the actual Activity object so that we can
tightly control what stuff passes through the dbus python bindings."""
"""Base dbus service object that each Activity uses to export dbus methods.
The dbus service is separate from the actual Activity object so that we can
tightly control what stuff passes through the dbus python bindings."""
def start(self, pservice, activity):
self._activity = activity
self._pservice = pservice
def start(self, pservice, activity):
self._activity = activity
self._pservice = pservice
@dbus.service.method(ACTIVITY_INTERFACE)
def share(self):
"""Called by the shell to request the activity to share itself on the network."""
self._activity.share()
@dbus.service.method(ACTIVITY_INTERFACE)
def share(self):
"""Called by the shell to request the activity to share itself on the network."""
self._activity.share()
@dbus.service.method(ACTIVITY_INTERFACE)
def join(self, activity_ps_path):
"""Join the activity specified by its presence service path"""
activity_ps = self._pservice.get(activity_ps_path)
return self._activity.join(activity_ps)
@dbus.service.method(ACTIVITY_INTERFACE)
def join(self, activity_ps_path):
"""Join the activity specified by its presence service path"""
activity_ps = self._pservice.get(activity_ps_path)
return self._activity.join(activity_ps)
@dbus.service.method(ACTIVITY_INTERFACE)
def get_id(self):
"""Get the activity identifier"""
return self._activity.get_id()
@dbus.service.method(ACTIVITY_INTERFACE)
def get_id(self):
"""Get the activity identifier"""
return self._activity.get_id()
@dbus.service.method(ACTIVITY_INTERFACE)
def get_type(self):
"""Get the activity type"""
return self._activity.get_type()
@dbus.service.method(ACTIVITY_INTERFACE)
def get_type(self):
"""Get the activity type"""
return self._activity.get_type()
@dbus.service.method(ACTIVITY_INTERFACE)
def get_shared(self):
"""Returns True if the activity is shared on the mesh."""
return self._activity.get_shared()
@dbus.service.method(ACTIVITY_INTERFACE)
def get_shared(self):
"""Returns True if the activity is shared on the mesh."""
return self._activity.get_shared()
@dbus.service.method(ACTIVITY_INTERFACE,
in_signature="sas", out_signature="")
def execute(self, command, args):
self._activity.execute(command, args)
@dbus.service.method(ACTIVITY_INTERFACE,
in_signature="sas", out_signature="")
def execute(self, command, args):
self._activity.execute(command, args)
class Activity(gtk.Window):
"""Base Activity class that all other Activities derive from."""
"""Base Activity class that all other Activities derive from."""
def __init__(self):
gtk.Window.__init__(self)
def __init__(self):
gtk.Window.__init__(self)
self.connect('destroy', self.__destroy_cb)
self.connect('destroy', self.__destroy_cb)
self._shared = False
self._activity_id = None
self._default_type = None
self._service = None
self._pservice = PresenceService()
self._shared = False
self._activity_id = None
self._default_type = None
self._service = None
self._pservice = PresenceService()
self.present()
group = gtk.Window()
group.realize()
self.window.set_group(group.window)
self.present()
group = gtk.Window()
group.realize()
self.window.set_group(group.window)
bus = dbus.SessionBus()
xid = self.window.xid
bus = dbus.SessionBus()
xid = self.window.xid
bus_name = dbus.service.BusName(get_service_name(xid), bus=bus)
self._bus = ActivityDbusService(bus_name, get_object_path(xid))
self._bus.start(self._pservice, self)
bus_name = dbus.service.BusName(get_service_name(xid), bus=bus)
self._bus = ActivityDbusService(bus_name, get_object_path(xid))
self._bus.start(self._pservice, self)
def set_type(self, activity_type):
"""Sets the activity type."""
self._activity_type = activity_type
self._default_type = activity.get_default_type(activity_type)
def set_type(self, activity_type):
"""Sets the activity type."""
self._activity_type = activity_type
self._default_type = activity.get_default_type(activity_type)
def get_type(self):
"""Gets the activity type."""
return self._activity_type
def get_type(self):
"""Gets the activity type."""
return self._activity_type
def get_default_type(self):
return self._default_type
def get_default_type(self):
return self._default_type
def get_shared(self):
"""Returns TRUE if the activity is shared on the mesh."""
return self._shared
def get_shared(self):
"""Returns TRUE if the activity is shared on the mesh."""
return self._shared
def get_id(self):
"""Get the unique activity identifier."""
if self._activity_id == None:
self._activity_id = sugar.util.unique_id()
return self._activity_id
def get_id(self):
"""Get the unique activity identifier."""
if self._activity_id == None:
self._activity_id = sugar.util.unique_id()
return self._activity_id
def join(self, activity_ps):
"""Join an activity shared on the network."""
self._shared = True
self._activity_id = activity_ps.get_id()
def join(self, activity_ps):
"""Join an activity shared on the network."""
self._shared = True
self._activity_id = activity_ps.get_id()
# Publish the default service, it's a copy of
# one of those we found on the network.
services = activity_ps.get_services_of_type(self._default_type)
if len(services) > 0:
service = services[0]
addr = service.get_address()
port = service.get_port()
properties = service.get_published_values()
self._service = self._pservice.share_activity(
self, self._default_type, properties, addr, port)
else:
logging.error('Cannot join the activity')
# Publish the default service, it's a copy of
# one of those we found on the network.
services = activity_ps.get_services_of_type(self._default_type)
if len(services) > 0:
service = services[0]
addr = service.get_address()
port = service.get_port()
properties = service.get_published_values()
self._service = self._pservice.share_activity(
self, self._default_type, properties, addr, port)
else:
logging.error('Cannot join the activity')
def share(self):
"""Share the activity on the network."""
logging.debug('Share activity %s on the network.' % self.get_id())
def share(self):
"""Share the activity on the network."""
logging.debug('Share activity %s on the network.' % self.get_id())
self._service = self._pservice.share_activity(self, self._default_type)
self._shared = True
self._service = self._pservice.share_activity(self, self._default_type)
self._shared = True
def execute(self, command, args):
"""Execute the given command with args"""
pass
def execute(self, command, args):
"""Execute the given command with args"""
pass
def __destroy_cb(self, window):
if self._bus:
del self._bus
self._bus = None
if self._service:
self._pservice.unregister_service(self._service)
def __destroy_cb(self, window):
if self._bus:
del self._bus
self._bus = None
if self._service:
self._pservice.unregister_service(self._service)
+48 -48
View File
@@ -27,72 +27,72 @@ from sugar.presence.PresenceService import PresenceService
from sugar.activity import Activity
def get_path(activity_name):
"""Returns the activity path"""
return '/' + activity_name.replace('.', '/')
"""Returns the activity path"""
return '/' + activity_name.replace('.', '/')
class ActivityFactory(dbus.service.Object):
"""Dbus service that takes care of creating new instances of an activity"""
"""Dbus service that takes care of creating new instances of an activity"""
def __init__(self, activity_type, activity_class):
self._activity_type = activity_type
self._activities = []
def __init__(self, activity_type, activity_class):
self._activity_type = activity_type
self._activities = []
splitted_module = activity_class.rsplit('.', 1)
module_name = splitted_module[0]
class_name = splitted_module[1]
splitted_module = activity_class.rsplit('.', 1)
module_name = splitted_module[0]
class_name = splitted_module[1]
module = __import__(module_name)
for comp in module_name.split('.')[1:]:
module = getattr(module, comp)
if hasattr(module, 'start'):
module.start()
module = __import__(module_name)
for comp in module_name.split('.')[1:]:
module = getattr(module, comp)
if hasattr(module, 'start'):
module.start()
self._module = module
self._constructor = getattr(module, class_name)
bus = dbus.SessionBus()
factory = activity_type
bus_name = dbus.service.BusName(factory, bus = bus)
dbus.service.Object.__init__(self, bus_name, get_path(factory))
self._module = module
self._constructor = getattr(module, class_name)
bus = dbus.SessionBus()
factory = activity_type
bus_name = dbus.service.BusName(factory, bus = bus)
dbus.service.Object.__init__(self, bus_name, get_path(factory))
@dbus.service.method("com.redhat.Sugar.ActivityFactory")
def create(self):
activity = self._constructor()
activity.set_type(self._activity_type)
@dbus.service.method("com.redhat.Sugar.ActivityFactory")
def create(self):
activity = self._constructor()
activity.set_type(self._activity_type)
self._activities.append(activity)
activity.connect('destroy', self._activity_destroy_cb)
self._activities.append(activity)
activity.connect('destroy', self._activity_destroy_cb)
return activity.window.xid
return activity.window.xid
def _activity_destroy_cb(self, activity):
self._activities.remove(activity)
def _activity_destroy_cb(self, activity):
self._activities.remove(activity)
if hasattr(self._module, 'stop'):
self._module.stop()
if hasattr(self._module, 'stop'):
self._module.stop()
if len(self._activities) == 0:
gtk.main_quit()
if len(self._activities) == 0:
gtk.main_quit()
def create(activity_name):
"""Create a new activity from his name."""
bus = dbus.SessionBus()
"""Create a new activity from his name."""
bus = dbus.SessionBus()
factory_name = activity_name
factory_path = get_path(factory_name)
factory_name = activity_name
factory_path = get_path(factory_name)
proxy_obj = bus.get_object(factory_name, factory_path)
factory = dbus.Interface(proxy_obj, "com.redhat.Sugar.ActivityFactory")
proxy_obj = bus.get_object(factory_name, factory_path)
factory = dbus.Interface(proxy_obj, "com.redhat.Sugar.ActivityFactory")
xid = factory.create()
xid = factory.create()
bus = dbus.SessionBus()
proxy_obj = bus.get_object(Activity.get_service_name(xid),
Activity.get_object_path(xid))
activity = dbus.Interface(proxy_obj, Activity.ACTIVITY_INTERFACE)
bus = dbus.SessionBus()
proxy_obj = bus.get_object(Activity.get_service_name(xid),
Activity.get_object_path(xid))
activity = dbus.Interface(proxy_obj, Activity.ACTIVITY_INTERFACE)
return activity
return activity
def register_factory(name, activity_class):
"""Register the activity factory."""
factory = ActivityFactory(name, activity_class)
"""Register the activity factory."""
factory = ActivityFactory(name, activity_class)
+5 -5
View File
@@ -9,10 +9,10 @@ sizes = 'gtk-large-toolbar=%d, %d' % (grid.dimension(1), grid.dimension(1))
settings.set_string_property('gtk-icon-sizes', sizes, '')
def get_default_type(activity_type):
"""Get the activity default type.
"""Get the activity default type.
It's the type of the main network service which tracks presence
It's the type of the main network service which tracks presence
and provides info about the activity, for example the title."""
splitted_id = activity_type.split('.')
splitted_id.reverse()
return '_' + '_'.join(splitted_id) + '._udp'
splitted_id = activity_type.split('.')
splitted_id.reverse()
return '_' + '_'.join(splitted_id) + '._udp'
+63 -63
View File
@@ -4,83 +4,83 @@ import os
from ConfigParser import ConfigParser
class Bundle:
"""Info about an activity bundle. Wraps the activity.info file."""
def __init__(self, path):
self._name = None
self._icon = None
self._service_name = None
self._show_launcher = True
self._valid = True
self._path = path
self._activity_version = 0
"""Info about an activity bundle. Wraps the activity.info file."""
def __init__(self, path):
self._name = None
self._icon = None
self._service_name = None
self._show_launcher = True
self._valid = True
self._path = path
self._activity_version = 0
info_path = os.path.join(path, 'activity', 'activity.info')
if os.path.isfile(info_path):
self._parse_info(info_path)
else:
self._valid = False
info_path = os.path.join(path, 'activity', 'activity.info')
if os.path.isfile(info_path):
self._parse_info(info_path)
else:
self._valid = False
def _parse_info(self, info_path):
cp = ConfigParser()
cp.read([info_path])
def _parse_info(self, info_path):
cp = ConfigParser()
cp.read([info_path])
section = 'Activity'
section = 'Activity'
if cp.has_option(section, 'service_name'):
self._service_name = cp.get(section, 'service_name')
else:
self._valid = False
logging.error('%s must specify a service name' % self._path)
if cp.has_option(section, 'service_name'):
self._service_name = cp.get(section, 'service_name')
else:
self._valid = False
logging.error('%s must specify a service name' % self._path)
if cp.has_option(section, 'name'):
self._name = cp.get(section, 'name')
else:
self._valid = False
logging.error('%s must specify a name' % self._path)
if cp.has_option(section, 'name'):
self._name = cp.get(section, 'name')
else:
self._valid = False
logging.error('%s must specify a name' % self._path)
if cp.has_option(section, 'exec'):
self._exec = cp.get(section, 'exec')
else:
self._valid = False
logging.error('%s must specify an exec' % self._path)
if cp.has_option(section, 'exec'):
self._exec = cp.get(section, 'exec')
else:
self._valid = False
logging.error('%s must specify an exec' % self._path)
if cp.has_option(section, 'show_launcher'):
if cp.get(section, 'show_launcher') == 'no':
self._show_launcher = False
if cp.has_option(section, 'show_launcher'):
if cp.get(section, 'show_launcher') == 'no':
self._show_launcher = False
if cp.has_option(section, 'icon'):
self._icon = cp.get(section, 'icon')
if cp.has_option(section, 'icon'):
self._icon = cp.get(section, 'icon')
if cp.has_option(section, 'activity_version'):
self._activity_version = int(cp.get(section, 'activity_version'))
if cp.has_option(section, 'activity_version'):
self._activity_version = int(cp.get(section, 'activity_version'))
def is_valid(self):
return self._valid
def is_valid(self):
return self._valid
def get_path(self):
"""Get the activity bundle path."""
return self._path
def get_path(self):
"""Get the activity bundle path."""
return self._path
def get_name(self):
"""Get the activity user visible name."""
return self._name
def get_name(self):
"""Get the activity user visible name."""
return self._name
def get_service_name(self):
"""Get the activity service name"""
return self._service_name
def get_service_name(self):
"""Get the activity service name"""
return self._service_name
def get_icon(self):
"""Get the activity icon name"""
return self._icon
def get_icon(self):
"""Get the activity icon name"""
return self._icon
def get_activity_version(self):
"""Get the activity version"""
return self._activity_version
def get_activity_version(self):
"""Get the activity version"""
return self._activity_version
def get_exec(self):
"""Get the command to execute to launch the activity factory"""
return self._exec
def get_exec(self):
"""Get the command to execute to launch the activity factory"""
return self._exec
def get_show_launcher(self):
"""Get whether there should be a visible launcher for the activity"""
return self._show_launcher
def get_show_launcher(self):
"""Get whether there should be a visible launcher for the activity"""
return self._show_launcher
+86 -86
View File
@@ -25,71 +25,71 @@ import shutil
from sugar.activity.bundle import Bundle
class _SvnFileList(list):
def __init__(self):
f = os.popen('svn list -R')
for line in f.readlines():
filename = line.strip()
if os.path.isfile(filename):
self.append(filename)
f.close()
def __init__(self):
f = os.popen('svn list -R')
for line in f.readlines():
filename = line.strip()
if os.path.isfile(filename):
self.append(filename)
f.close()
class _GitFileList(list):
def __init__(self):
f = os.popen('git-ls-files')
for line in f.readlines():
filename = line.strip()
if not filename.startswith('.'):
self.append(filename)
f.close()
def __init__(self):
f = os.popen('git-ls-files')
for line in f.readlines():
filename = line.strip()
if not filename.startswith('.'):
self.append(filename)
f.close()
def _extract_bundle(source_file, dest_dir):
if not os.path.exists(dest_dir):
os.mkdir(dest_dir)
if not os.path.exists(dest_dir):
os.mkdir(dest_dir)
zf = zipfile.ZipFile(source_file)
zf = zipfile.ZipFile(source_file)
for i, name in enumerate(zf.namelist()):
path = os.path.join(dest_dir, name)
if not os.path.exists(os.path.dirname(path)):
os.makedirs(os.path.dirname(path))
for i, name in enumerate(zf.namelist()):
path = os.path.join(dest_dir, name)
if not os.path.exists(os.path.dirname(path)):
os.makedirs(os.path.dirname(path))
outfile = open(path, 'wb')
outfile.write(zf.read(name))
outfile.flush()
outfile.close()
outfile = open(path, 'wb')
outfile.write(zf.read(name))
outfile.flush()
outfile.close()
def _get_source_path():
return os.getcwd()
return os.getcwd()
def _get_activities_path():
path = os.path.expanduser('~/Activities')
if not os.path.isdir(path):
os.mkdir(path)
return path
path = os.path.expanduser('~/Activities')
if not os.path.isdir(path):
os.mkdir(path)
return path
def _get_bundle_dir():
bundle_name = os.path.basename(_get_source_path())
return bundle_name + '.activity'
bundle_name = os.path.basename(_get_source_path())
return bundle_name + '.activity'
def _get_install_dir(prefix):
return os.path.join(prefix, 'share/activities')
return os.path.join(prefix, 'share/activities')
def _get_bundle_path():
return os.path.join(_get_activities_path(), _get_bundle_dir())
return os.path.join(_get_activities_path(), _get_bundle_dir())
def _get_package_name():
bundle = Bundle(_get_source_path())
zipname = '%s-%d.xo' % (bundle.get_name(), bundle.get_activity_version())
return zipname
bundle = Bundle(_get_source_path())
zipname = '%s-%d.xo' % (bundle.get_name(), bundle.get_activity_version())
return zipname
def _delete_backups(arg, dirname, names):
for name in names:
if name.endswith('~') or name.endswith('pyc'):
os.remove(os.path.join(dirname, name))
for name in names:
if name.endswith('~') or name.endswith('pyc'):
os.remove(os.path.join(dirname, name))
def cmd_help():
print 'Usage: \n\
print 'Usage: \n\
setup.py dev - setup for development \n\
setup.py dist - create a bundle package \n\
setup.py install - install the bundle \n\
@@ -98,59 +98,59 @@ setup.py help - print this message \n\
'
def cmd_dev():
bundle_path = get_bundle_path()
try:
os.symlink(_get_source_path(), bundle_path)
except OSError:
if os.path.islink(bundle_path):
print 'ERROR - The bundle has been already setup for development.'
else:
print 'ERROR - A bundle with the same name is already installed.'
bundle_path = get_bundle_path()
try:
os.symlink(_get_source_path(), bundle_path)
except OSError:
if os.path.islink(bundle_path):
print 'ERROR - The bundle has been already setup for development.'
else:
print 'ERROR - A bundle with the same name is already installed.'
def cmd_dist():
if os.path.isdir('.git'):
file_list = _GitFileList()
elif os.path.isdir('.svn'):
file_list = _SvnFileList()
else:
print 'ERROR - The command works only with git or svn repositories.'
if os.path.isdir('.git'):
file_list = _GitFileList()
elif os.path.isdir('.svn'):
file_list = _SvnFileList()
else:
print 'ERROR - The command works only with git or svn repositories.'
zipname = _get_package_name()
bundle_zip = zipfile.ZipFile(zipname, 'w', zipfile.ZIP_DEFLATED)
for filename in file_list:
arcname = os.path.join(_get_bundle_dir(), filename)
bundle_zip.write(filename, arcname)
zipname = _get_package_name()
bundle_zip = zipfile.ZipFile(zipname, 'w', zipfile.ZIP_DEFLATED)
for filename in file_list:
arcname = os.path.join(_get_bundle_dir(), filename)
bundle_zip.write(filename, arcname)
bundle_zip.close()
bundle_zip.close()
def cmd_install(prefix):
cmd_dist()
cmd_uninstall(prefix)
_extract_bundle(_get_package_name(), _get_install_dir(prefix))
cmd_dist()
cmd_uninstall(prefix)
_extract_bundle(_get_package_name(), _get_install_dir(prefix))
def cmd_uninstall(prefix):
path = os.path.join(_get_install_dir(prefix), _get_bundle_dir())
if os.path.isdir(path):
shutil.rmtree(path)
path = os.path.join(_get_install_dir(prefix), _get_bundle_dir())
if os.path.isdir(path):
shutil.rmtree(path)
def cmd_clean():
os.path.walk('.', delete_backups, None)
os.path.walk('.', delete_backups, None)
def start():
if len(sys.argv) < 2:
cmd_help()
elif sys.argv[1] == 'build':
pass
elif sys.argv[1] == 'dev':
cmd_dev()
elif sys.argv[1] == 'dist':
cmd_dist()
elif sys.argv[1] == 'install' and len(sys.argv) == 3:
cmd_install(sys.argv[2])
elif sys.argv[1] == 'uninstall' and len(sys.argv) == 3:
cmd_uninstall(sys.argv[2])
elif sys.argv[1] == 'clean':
cmd_clean()
else:
cmd_help()
if len(sys.argv) < 2:
cmd_help()
elif sys.argv[1] == 'build':
pass
elif sys.argv[1] == 'dev':
cmd_dev()
elif sys.argv[1] == 'dist':
cmd_dist()
elif sys.argv[1] == 'install' and len(sys.argv) == 3:
cmd_install(sys.argv[2])
elif sys.argv[1] == 'uninstall' and len(sys.argv) == 3:
cmd_uninstall(sys.argv[2])
elif sys.argv[1] == 'clean':
cmd_clean()
else:
cmd_help()
+38 -38
View File
@@ -6,51 +6,51 @@ from sugar import env
from sugar import util
class _ServiceManager(object):
def __init__(self):
self._path = env.get_user_service_dir()
def __init__(self):
self._path = env.get_user_service_dir()
def add(self, bundle):
name = bundle.get_service_name()
def add(self, bundle):
name = bundle.get_service_name()
# FIXME evil hack. Probably need to fix Exec spec
full_exec = env.get_shell_bin_dir() + '/' + bundle.get_exec()
full_exec += ' ' + bundle.get_path()
# FIXME evil hack. Probably need to fix Exec spec
full_exec = env.get_shell_bin_dir() + '/' + bundle.get_exec()
full_exec += ' ' + bundle.get_path()
util.write_service(name, full_exec, self._path)
util.write_service(name, full_exec, self._path)
class BundleRegistry:
"""Service that tracks the available activity bundles"""
"""Service that tracks the available activity bundles"""
def __init__(self):
self._bundles = {}
self._search_path = []
self._service_manager = _ServiceManager()
def __init__(self):
self._bundles = {}
self._search_path = []
self._service_manager = _ServiceManager()
def get_bundle(self, service_name):
"""Returns an bundle given his service name"""
if self._bundles.has_key(service_name):
return self._bundles[service_name]
else:
return None
def get_bundle(self, service_name):
"""Returns an bundle given his service name"""
if self._bundles.has_key(service_name):
return self._bundles[service_name]
else:
return None
def add_search_path(self, path):
"""Add a directory to the bundles search path"""
self._search_path.append(path)
self._scan_directory(path)
def __iter__(self):
return self._bundles.values().__iter__()
def add_search_path(self, path):
"""Add a directory to the bundles search path"""
self._search_path.append(path)
self._scan_directory(path)
def __iter__(self):
return self._bundles.values().__iter__()
def _scan_directory(self, path):
if os.path.isdir(path):
for f in os.listdir(path):
bundle_dir = os.path.join(path, f)
if os.path.isdir(bundle_dir) and \
bundle_dir.endswith('.activity'):
self._add_bundle(bundle_dir)
def _scan_directory(self, path):
if os.path.isdir(path):
for f in os.listdir(path):
bundle_dir = os.path.join(path, f)
if os.path.isdir(bundle_dir) and \
bundle_dir.endswith('.activity'):
self._add_bundle(bundle_dir)
def _add_bundle(self, bundle_path):
bundle = Bundle(bundle_path)
if bundle.is_valid():
self._bundles[bundle.get_service_name()] = bundle
self._service_manager.add(bundle)
def _add_bundle(self, bundle_path):
bundle = Bundle(bundle_path)
if bundle.is_valid():
self._bundles[bundle.get_service_name()] = bundle
self._service_manager.add(bundle)
+37 -37
View File
@@ -20,48 +20,48 @@ import logging
from sugar.chat.GroupChat import GroupChat
class ActivityChat(GroupChat):
SERVICE_TYPE = "_olpc_activity_chat._udp"
SERVICE_TYPE = "_olpc_activity_chat._udp"
def __init__(self, activity):
GroupChat.__init__(self)
self._chat_service = None
def __init__(self, activity):
GroupChat.__init__(self)
self._chat_service = None
self.connect('destroy', self._destroy_cb)
self.connect('destroy', self._destroy_cb)
self._activity = activity
self._pservice.register_service_type(ActivityChat.SERVICE_TYPE)
self._pservice.connect('service-appeared', self._service_appeared_cb)
self._activity = activity
self._pservice.register_service_type(ActivityChat.SERVICE_TYPE)
self._pservice.connect('service-appeared', self._service_appeared_cb)
# Find an existing activity chat to latch onto
ps_activity = self._pservice.get_activity(activity.get_id())
if ps_activity is not None:
services = ps_activity.get_services_of_type(ActivityChat.SERVICE_TYPE)
if len(services) > 0:
self._service_appeared_cb(self._pservice, services[0])
# Find an existing activity chat to latch onto
ps_activity = self._pservice.get_activity(activity.get_id())
if ps_activity is not None:
services = ps_activity.get_services_of_type(ActivityChat.SERVICE_TYPE)
if len(services) > 0:
self._service_appeared_cb(self._pservice, services[0])
def _service_appeared_cb(self, pservice, service):
if service.get_activity_id() != self._activity.get_id():
return
if service.get_type() != ActivityChat.SERVICE_TYPE:
return
if self._chat_service:
return
def _service_appeared_cb(self, pservice, service):
if service.get_activity_id() != self._activity.get_id():
return
if service.get_type() != ActivityChat.SERVICE_TYPE:
return
if self._chat_service:
return
logging.debug('Activity chat service appeared, setup the stream.')
# Ok, there's an existing chat service that we copy
# parameters and such from
addr = service.get_address()
port = service.get_port()
self._chat_service = self._pservice.share_activity(self._activity,
stype=ActivityChat.SERVICE_TYPE, address=addr, port=port)
self._setup_stream(self._chat_service)
logging.debug('Activity chat service appeared, setup the stream.')
# Ok, there's an existing chat service that we copy
# parameters and such from
addr = service.get_address()
port = service.get_port()
self._chat_service = self._pservice.share_activity(self._activity,
stype=ActivityChat.SERVICE_TYPE, address=addr, port=port)
self._setup_stream(self._chat_service)
def share(self):
"""Only called when we share the activity this chat is tied to."""
self._chat_service = self._pservice.share_activity(self._activity,
stype=ActivityChat.SERVICE_TYPE)
self._setup_stream(self._chat_service)
def share(self):
"""Only called when we share the activity this chat is tied to."""
self._chat_service = self._pservice.share_activity(self._activity,
stype=ActivityChat.SERVICE_TYPE)
self._setup_stream(self._chat_service)
def _destroy_cb(self, widget):
if self._chat_service:
self._pservice.unregister_service(self._chat_service)
def _destroy_cb(self, widget):
if self._chat_service:
self._pservice.unregister_service(self._chat_service)
+203 -203
View File
@@ -37,244 +37,244 @@ import richtext
PANGO_SCALE = 1024 # Where is this defined?
class Chat(gtk.VBox):
SERVICE_TYPE = "_olpc_chat._tcp"
SERVICE_PORT = 6100
SERVICE_TYPE = "_olpc_chat._tcp"
SERVICE_PORT = 6100
TEXT_MODE = 0
SKETCH_MODE = 1
TEXT_MODE = 0
SKETCH_MODE = 1
def __init__(self):
gtk.VBox.__init__(self, False, 6)
def __init__(self):
gtk.VBox.__init__(self, False, 6)
self._pservice = PresenceService.get_instance()
self._pservice = PresenceService.get_instance()
self._stream_writer = None
self.set_border_width(12)
self._stream_writer = None
self.set_border_width(12)
chat_vbox = gtk.VBox()
chat_vbox.set_spacing(6)
chat_vbox = gtk.VBox()
chat_vbox.set_spacing(6)
self._chat_sw = gtk.ScrolledWindow()
self._chat_sw.set_shadow_type(gtk.SHADOW_IN)
self._chat_sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_ALWAYS)
self._chat_view = richtext.RichTextView()
self._chat_view.connect("link-clicked", self.__link_clicked_cb)
self._chat_view.set_editable(False)
self._chat_view.set_cursor_visible(False)
self._chat_view.set_pixels_above_lines(7)
self._chat_view.set_left_margin(5)
self._chat_sw.add(self._chat_view)
self._chat_view.show()
chat_vbox.pack_start(self._chat_sw)
self._chat_sw.show()
self.pack_start(chat_vbox)
chat_vbox.show()
self._chat_sw = gtk.ScrolledWindow()
self._chat_sw.set_shadow_type(gtk.SHADOW_IN)
self._chat_sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_ALWAYS)
self._chat_view = richtext.RichTextView()
self._chat_view.connect("link-clicked", self.__link_clicked_cb)
self._chat_view.set_editable(False)
self._chat_view.set_cursor_visible(False)
self._chat_view.set_pixels_above_lines(7)
self._chat_view.set_left_margin(5)
self._chat_sw.add(self._chat_view)
self._chat_view.show()
chat_vbox.pack_start(self._chat_sw)
self._chat_sw.show()
self.pack_start(chat_vbox)
chat_vbox.show()
self._mode = Chat.TEXT_MODE
self._editor = ChatEditor(self, ChatEditor.TEXT_MODE)
self._mode = Chat.TEXT_MODE
self._editor = ChatEditor(self, ChatEditor.TEXT_MODE)
toolbar = ChatToolbar(self._editor)
self.pack_start(toolbar, False)
toolbar.show()
toolbar = ChatToolbar(self._editor)
self.pack_start(toolbar, False)
toolbar.show()
self.pack_start(self._editor, False)
self._editor.show()
self.pack_start(self._editor, False)
self._editor.show()
self.connect("key-press-event", self.__key_press_event_cb)
self.connect("key-press-event", self.__key_press_event_cb)
def __key_press_event_cb(self, window, event):
if event.keyval == gtk.keysyms.s and \
event.state & gtk.gdk.CONTROL_MASK:
if self.get_mode() == Chat.SKETCH_MODE:
self.set_mode(Chat.TEXT_MODE)
elif self.get_mode() == Chat.TEXT_MODE:
self.set_mode(Chat.SKETCH_MODE)
def __key_press_event_cb(self, window, event):
if event.keyval == gtk.keysyms.s and \
event.state & gtk.gdk.CONTROL_MASK:
if self.get_mode() == Chat.SKETCH_MODE:
self.set_mode(Chat.TEXT_MODE)
elif self.get_mode() == Chat.TEXT_MODE:
self.set_mode(Chat.SKETCH_MODE)
def get_mode(self):
return self._mode
def get_mode(self):
return self._mode
def set_mode(self, mode):
self._mode = mode
if self._mode == Chat.TEXT_MODE:
self._editor.set_mode(ChatEditor.TEXT_MODE)
elif self._mode == Chat.SKETCH_MODE:
self._editor.set_mode(ChatEditor.SKETCH_MODE)
def set_mode(self, mode):
self._mode = mode
if self._mode == Chat.TEXT_MODE:
self._editor.set_mode(ChatEditor.TEXT_MODE)
elif self._mode == Chat.SKETCH_MODE:
self._editor.set_mode(ChatEditor.SKETCH_MODE)
def __get_browser_shell(self):
bus = dbus.SessionBus()
proxy_obj = bus.get_object('com.redhat.Sugar.Browser', '/com/redhat/Sugar/Browser')
self._browser_shell = dbus.Interface(proxy_obj, 'com.redhat.Sugar.BrowserShell')
def __get_browser_shell(self):
bus = dbus.SessionBus()
proxy_obj = bus.get_object('com.redhat.Sugar.Browser', '/com/redhat/Sugar/Browser')
self._browser_shell = dbus.Interface(proxy_obj, 'com.redhat.Sugar.BrowserShell')
def __link_clicked_cb(self, view, address):
self.__get_browser_shell().open_browser(address)
def __link_clicked_cb(self, view, address):
self.__get_browser_shell().open_browser(address)
def _scroll_chat_view_to_bottom(self):
# Only scroll to bottom if the view is already close to the bottom
vadj = self._chat_sw.get_vadjustment()
if vadj.value + vadj.page_size > vadj.upper * 0.8:
vadj.value = vadj.upper - vadj.page_size
self._chat_sw.set_vadjustment(vadj)
def _scroll_chat_view_to_bottom(self):
# Only scroll to bottom if the view is already close to the bottom
vadj = self._chat_sw.get_vadjustment()
if vadj.value + vadj.page_size > vadj.upper * 0.8:
vadj.value = vadj.upper - vadj.page_size
self._chat_sw.set_vadjustment(vadj)
def _message_inserted(self):
gobject.idle_add(self._scroll_chat_view_to_bottom)
def _message_inserted(self):
gobject.idle_add(self._scroll_chat_view_to_bottom)
def _insert_buddy(self, buf, buddy):
# Stuff in the buddy icon, if we have one for this buddy
icon = buddy.get_icon_pixbuf()
if icon:
rise = int(icon.get_height() / 4) * -1
def _insert_buddy(self, buf, buddy):
# Stuff in the buddy icon, if we have one for this buddy
icon = buddy.get_icon_pixbuf()
if icon:
rise = int(icon.get_height() / 4) * -1
hash_string = "%s-%s" % (buddy.get_name(), buddy.get_ip4_address())
sha_hash = sha.new()
sha_hash.update(hash_string)
tagname = "buddyicon-%s" % sha_hash.hexdigest()
hash_string = "%s-%s" % (buddy.get_name(), buddy.get_ip4_address())
sha_hash = sha.new()
sha_hash.update(hash_string)
tagname = "buddyicon-%s" % sha_hash.hexdigest()
if not buf.get_tag_table().lookup(tagname):
buf.create_tag(tagname, rise=(rise * PANGO_SCALE))
if not buf.get_tag_table().lookup(tagname):
buf.create_tag(tagname, rise=(rise * PANGO_SCALE))
aniter = buf.get_end_iter()
buf.insert_pixbuf(aniter, icon)
aniter.backward_char()
enditer = buf.get_end_iter()
buf.apply_tag_by_name(tagname, aniter, enditer)
aniter = buf.get_end_iter()
buf.insert_pixbuf(aniter, icon)
aniter.backward_char()
enditer = buf.get_end_iter()
buf.apply_tag_by_name(tagname, aniter, enditer)
# Stick in the buddy's nickname
if not buf.get_tag_table().lookup("nickname"):
buf.create_tag("nickname", weight=pango.WEIGHT_BOLD)
aniter = buf.get_end_iter()
offset = aniter.get_offset()
buf.insert(aniter, " " + buddy.get_name() + ": ")
enditer = buf.get_iter_at_offset(offset)
buf.apply_tag_by_name("nickname", aniter, enditer)
def _insert_rich_message(self, buddy, msg):
msg = Emoticons.get_instance().replace(msg)
# Stick in the buddy's nickname
if not buf.get_tag_table().lookup("nickname"):
buf.create_tag("nickname", weight=pango.WEIGHT_BOLD)
aniter = buf.get_end_iter()
offset = aniter.get_offset()
buf.insert(aniter, " " + buddy.get_name() + ": ")
enditer = buf.get_iter_at_offset(offset)
buf.apply_tag_by_name("nickname", aniter, enditer)
def _insert_rich_message(self, buddy, msg):
msg = Emoticons.get_instance().replace(msg)
buf = self._chat_view.get_buffer()
self._insert_buddy(buf, buddy)
serializer = richtext.RichTextSerializer()
serializer.deserialize(msg, buf)
aniter = buf.get_end_iter()
buf.insert(aniter, "\n")
self._message_inserted()
buf = self._chat_view.get_buffer()
self._insert_buddy(buf, buddy)
serializer = richtext.RichTextSerializer()
serializer.deserialize(msg, buf)
aniter = buf.get_end_iter()
buf.insert(aniter, "\n")
self._message_inserted()
def _insert_sketch(self, buddy, svgdata):
"""Insert a sketch object into the chat buffer."""
pbl = gtk.gdk.PixbufLoader("svg")
pbl.write(svgdata)
pbl.close()
pbuf = pbl.get_pixbuf()
buf = self._chat_view.get_buffer()
def _insert_sketch(self, buddy, svgdata):
"""Insert a sketch object into the chat buffer."""
pbl = gtk.gdk.PixbufLoader("svg")
pbl.write(svgdata)
pbl.close()
pbuf = pbl.get_pixbuf()
buf = self._chat_view.get_buffer()
self._insert_buddy(buf, buddy)
rise = int(pbuf.get_height() / 3) * -1
sha_hash = sha.new()
sha_hash.update(svgdata)
tagname = "sketch-%s" % sha_hash.hexdigest()
if not buf.get_tag_table().lookup(tagname):
buf.create_tag(tagname, rise=(rise * PANGO_SCALE))
self._insert_buddy(buf, buddy)
rise = int(pbuf.get_height() / 3) * -1
sha_hash = sha.new()
sha_hash.update(svgdata)
tagname = "sketch-%s" % sha_hash.hexdigest()
if not buf.get_tag_table().lookup(tagname):
buf.create_tag(tagname, rise=(rise * PANGO_SCALE))
aniter = buf.get_end_iter()
buf.insert_pixbuf(aniter, pbuf)
aniter.backward_char()
enditer = buf.get_end_iter()
buf.apply_tag_by_name(tagname, aniter, enditer)
aniter = buf.get_end_iter()
buf.insert(aniter, "\n")
aniter = buf.get_end_iter()
buf.insert_pixbuf(aniter, pbuf)
aniter.backward_char()
enditer = buf.get_end_iter()
buf.apply_tag_by_name(tagname, aniter, enditer)
aniter = buf.get_end_iter()
buf.insert(aniter, "\n")
self._message_inserted()
self._message_inserted()
def _get_first_richtext_chunk(self, msg):
"""Scan the message for the first richtext-tagged chunk and return it."""
rt_last = -1
tag_rt_start = "<richtext>"
tag_rt_end = "</richtext>"
rt_first = msg.find(tag_rt_start)
length = -1
if rt_first >= 0:
length = len(msg)
rt_last = msg.find(tag_rt_end, rt_first)
if rt_first >= 0 and rt_last >= (rt_first + len(tag_rt_start)) and length > 0:
return msg[rt_first:rt_last + len(tag_rt_end)]
return None
def _get_first_richtext_chunk(self, msg):
"""Scan the message for the first richtext-tagged chunk and return it."""
rt_last = -1
tag_rt_start = "<richtext>"
tag_rt_end = "</richtext>"
rt_first = msg.find(tag_rt_start)
length = -1
if rt_first >= 0:
length = len(msg)
rt_last = msg.find(tag_rt_end, rt_first)
if rt_first >= 0 and rt_last >= (rt_first + len(tag_rt_start)) and length > 0:
return msg[rt_first:rt_last + len(tag_rt_end)]
return None
def _get_first_sketch_chunk(self, msg):
"""Scan the message for the first SVG-tagged chunk and return it."""
svg_last = -1
tag_svg_start = "<svg"
tag_svg_end = "</svg>"
desc_start = msg.find("<?xml version='1.0' encoding='UTF-8'?>")
if desc_start < 0:
return None
ignore = msg.find("<!DOCTYPE svg")
if ignore < 0:
return None
svg_first = msg.find(tag_svg_start)
length = -1
if svg_first >= 0:
length = len(msg)
svg_last = msg.find(tag_svg_end, svg_first)
if svg_first >= 0 and svg_last >= (svg_first + len(tag_svg_start)) and length > 0:
return msg[desc_start:svg_last + len(tag_svg_end)]
return None
def _get_first_sketch_chunk(self, msg):
"""Scan the message for the first SVG-tagged chunk and return it."""
svg_last = -1
tag_svg_start = "<svg"
tag_svg_end = "</svg>"
desc_start = msg.find("<?xml version='1.0' encoding='UTF-8'?>")
if desc_start < 0:
return None
ignore = msg.find("<!DOCTYPE svg")
if ignore < 0:
return None
svg_first = msg.find(tag_svg_start)
length = -1
if svg_first >= 0:
length = len(msg)
svg_last = msg.find(tag_svg_end, svg_first)
if svg_first >= 0 and svg_last >= (svg_first + len(tag_svg_start)) and length > 0:
return msg[desc_start:svg_last + len(tag_svg_end)]
return None
def recv_message(self, message):
"""Insert a remote chat message into the chat buffer."""
[nick, msg] = Chat.deserialize_message(message)
buddy = self._pservice.get_buddy_by_name(nick)
if not buddy:
logging.error('The buddy %s is not present.' % (nick))
return
def recv_message(self, message):
"""Insert a remote chat message into the chat buffer."""
[nick, msg] = Chat.deserialize_message(message)
buddy = self._pservice.get_buddy_by_name(nick)
if not buddy:
logging.error('The buddy %s is not present.' % (nick))
return
# FIXME a better way to compare buddies?
owner = self._pservice.get_owner()
if buddy.get_name() == owner.get_name():
return
# FIXME a better way to compare buddies?
owner = self._pservice.get_owner()
if buddy.get_name() == owner.get_name():
return
chunk = self._get_first_richtext_chunk(msg)
if chunk:
self._insert_rich_message(buddy, chunk)
return
chunk = self._get_first_richtext_chunk(msg)
if chunk:
self._insert_rich_message(buddy, chunk)
return
chunk = self._get_first_sketch_chunk(msg)
if chunk:
self._insert_sketch(buddy, chunk)
return
chunk = self._get_first_sketch_chunk(msg)
if chunk:
self._insert_sketch(buddy, chunk)
return
def set_stream_writer(self, stream_writer):
self._stream_writer = stream_writer
def set_stream_writer(self, stream_writer):
self._stream_writer = stream_writer
def send_sketch(self, svgdata):
if not svgdata or not len(svgdata):
return
if self._stream_writer:
self._stream_writer.write(self.serialize_message(svgdata))
owner = self._pservice.get_owner()
if owner:
self._insert_sketch(owner, svgdata)
def send_sketch(self, svgdata):
if not svgdata or not len(svgdata):
return
if self._stream_writer:
self._stream_writer.write(self.serialize_message(svgdata))
owner = self._pservice.get_owner()
if owner:
self._insert_sketch(owner, svgdata)
def send_text_message(self, text):
"""Send a chat message and insert it into the local buffer."""
if len(text) <= 0:
return
if self._stream_writer:
self._stream_writer.write(self.serialize_message(text))
else:
logging.warning("Cannot send message, there is no stream writer")
owner = self._pservice.get_owner()
if owner:
self._insert_rich_message(owner, text)
def send_text_message(self, text):
"""Send a chat message and insert it into the local buffer."""
if len(text) <= 0:
return
if self._stream_writer:
self._stream_writer.write(self.serialize_message(text))
else:
logging.warning("Cannot send message, there is no stream writer")
owner = self._pservice.get_owner()
if owner:
self._insert_rich_message(owner, text)
def serialize_message(self, message):
owner = self._pservice.get_owner()
return owner.get_name() + '||' + message
def deserialize_message(message):
return message.split('||', 1)
def serialize_message(self, message):
owner = self._pservice.get_owner()
return owner.get_name() + '||' + message
def deserialize_message(message):
return message.split('||', 1)
deserialize_message = staticmethod(deserialize_message)
deserialize_message = staticmethod(deserialize_message)
+70 -70
View File
@@ -22,83 +22,83 @@ from sugar.chat.sketchpad.SketchPad import SketchPad
import richtext
class ChatEditor(gtk.HBox):
TEXT_MODE = 0
SKETCH_MODE = 1
TEXT_MODE = 0
SKETCH_MODE = 1
def __init__(self, chat, mode):
gtk.HBox.__init__(self, False, 6)
def __init__(self, chat, mode):
gtk.HBox.__init__(self, False, 6)
self._chat = chat
self._chat = chat
self._notebook = gtk.Notebook()
self._notebook.set_show_tabs(False)
self._notebook.set_show_border(False)
self._notebook.set_size_request(-1, 70)
chat_view_sw = gtk.ScrolledWindow()
chat_view_sw.set_shadow_type(gtk.SHADOW_IN)
chat_view_sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
self._text_view = richtext.RichTextView()
self._text_view.connect("key-press-event", self.__key_press_event_cb)
chat_view_sw.add(self._text_view)
self._text_view.show()
self._notebook.append_page(chat_view_sw)
chat_view_sw.show()
self._sketchpad = SketchPad()
self._notebook.append_page(self._sketchpad)
self._sketchpad.show()
self.pack_start(self._notebook)
self._notebook.show()
send_button = gtk.Button(_("Send"))
send_button.set_size_request(60, -1)
send_button.connect('clicked', self.__send_button_clicked_cb)
self.pack_start(send_button, False, True)
send_button.show()
self.set_mode(mode)
self._notebook = gtk.Notebook()
self._notebook.set_show_tabs(False)
self._notebook.set_show_border(False)
self._notebook.set_size_request(-1, 70)
chat_view_sw = gtk.ScrolledWindow()
chat_view_sw.set_shadow_type(gtk.SHADOW_IN)
chat_view_sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
self._text_view = richtext.RichTextView()
self._text_view.connect("key-press-event", self.__key_press_event_cb)
chat_view_sw.add(self._text_view)
self._text_view.show()
self._notebook.append_page(chat_view_sw)
chat_view_sw.show()
self._sketchpad = SketchPad()
self._notebook.append_page(self._sketchpad)
self._sketchpad.show()
self.pack_start(self._notebook)
self._notebook.show()
send_button = gtk.Button(_("Send"))
send_button.set_size_request(60, -1)
send_button.connect('clicked', self.__send_button_clicked_cb)
self.pack_start(send_button, False, True)
send_button.show()
self.set_mode(mode)
def set_color(self, color):
self._sketchpad.set_color(color)
def get_buffer(self):
return self._text_view.get_buffer()
def set_color(self, color):
self._sketchpad.set_color(color)
def get_buffer(self):
return self._text_view.get_buffer()
def set_mode(self, mode):
self._mode = mode
if self._mode == ChatEditor.SKETCH_MODE:
self._notebook.set_current_page(1)
elif self._mode == ChatEditor.TEXT_MODE:
self._notebook.set_current_page(0)
def set_mode(self, mode):
self._mode = mode
if self._mode == ChatEditor.SKETCH_MODE:
self._notebook.set_current_page(1)
elif self._mode == ChatEditor.TEXT_MODE:
self._notebook.set_current_page(0)
def __send_button_clicked_cb(self, button):
self._send()
def __send_button_clicked_cb(self, button):
self._send()
def _send(self):
if self._mode == ChatEditor.SKETCH_MODE:
self._send_sketch()
elif self._mode == ChatEditor.TEXT_MODE:
self._send_text()
def _send(self):
if self._mode == ChatEditor.SKETCH_MODE:
self._send_sketch()
elif self._mode == ChatEditor.TEXT_MODE:
self._send_text()
def _send_sketch(self):
self._chat.send_sketch(self._sketchpad.to_svg())
self._sketchpad.clear()
def _send_sketch(self):
self._chat.send_sketch(self._sketchpad.to_svg())
self._sketchpad.clear()
def _send_text(self):
buf = self._text_view.get_buffer()
text = buf.get_text(buf.get_start_iter(), buf.get_end_iter())
if len(text.strip()) > 0:
serializer = richtext.RichTextSerializer()
text = serializer.serialize(buf)
self._chat.send_text_message(text)
def _send_text(self):
buf = self._text_view.get_buffer()
text = buf.get_text(buf.get_start_iter(), buf.get_end_iter())
if len(text.strip()) > 0:
serializer = richtext.RichTextSerializer()
text = serializer.serialize(buf)
self._chat.send_text_message(text)
buf.set_text("")
buf.place_cursor(buf.get_start_iter())
def __key_press_event_cb(self, text_view, event):
if event.keyval == gtk.keysyms.Return:
self._send()
return True
buf.set_text("")
buf.place_cursor(buf.get_start_iter())
def __key_press_event_cb(self, text_view, event):
if event.keyval == gtk.keysyms.Return:
self._send()
return True
+112 -112
View File
@@ -22,129 +22,129 @@ from sugar.chat.sketchpad.Toolbox import Toolbox
import richtext
class ChatToolbar(gtk.HBox):
def __init__(self, editor):
gtk.HBox.__init__(self, False, 24)
self._editor = editor
self._emt_popup = None
def __init__(self, editor):
gtk.HBox.__init__(self, False, 24)
self._editor = editor
self._emt_popup = None
spring = gtk.Label('')
self.pack_start(spring, True)
spring.show()
spring = gtk.Label('')
self.pack_start(spring, True)
spring.show()
toolbox = richtext.RichTextToolbox(editor.get_buffer())
self.pack_start(toolbox, False)
toolbox.show()
item = gtk.Button()
item.unset_flags(gtk.CAN_FOCUS)
toolbox = richtext.RichTextToolbox(editor.get_buffer())
self.pack_start(toolbox, False)
toolbox.show()
item = gtk.Button()
item.unset_flags(gtk.CAN_FOCUS)
e_hbox = gtk.HBox(False, 6)
e_image = gtk.Image()
e_image.set_from_icon_name('stock_smiley-1', gtk.ICON_SIZE_SMALL_TOOLBAR)
e_hbox.pack_start(e_image)
e_image.show()
arrow = gtk.Arrow(gtk.ARROW_DOWN, gtk.SHADOW_NONE)
e_hbox.pack_start(arrow)
arrow.show()
e_hbox = gtk.HBox(False, 6)
e_image = gtk.Image()
e_image.set_from_icon_name('stock_smiley-1', gtk.ICON_SIZE_SMALL_TOOLBAR)
e_hbox.pack_start(e_image)
e_image.show()
arrow = gtk.Arrow(gtk.ARROW_DOWN, gtk.SHADOW_NONE)
e_hbox.pack_start(arrow)
arrow.show()
item.set_image(e_hbox)
item.connect("clicked", self.__emoticons_button_clicked_cb)
toolbox.pack_start(item, False)
item.show()
# separator = gtk.SeparatorToolItem()
# toolbar.insert(separator, -1)
# separator.show()
item.set_image(e_hbox)
item.connect("clicked", self.__emoticons_button_clicked_cb)
toolbox.pack_start(item, False)
item.show()
# separator = gtk.SeparatorToolItem()
# toolbar.insert(separator, -1)
# separator.show()
# item = gtk.MenuToolButton(None, "Links")
# item.set_menu(gtk.Menu())
# item.connect("show-menu", self.__show_link_menu_cb)
# toolbar.insert(item, -1)
# item.show()
# item = gtk.MenuToolButton(None, "Links")
# item.set_menu(gtk.Menu())
# item.connect("show-menu", self.__show_link_menu_cb)
# toolbar.insert(item, -1)
# item.show()
toolbox = Toolbox()
toolbox.connect('color-selected', self._color_selected)
self.pack_start(toolbox, False)
toolbox.show()
toolbox = Toolbox()
toolbox.connect('color-selected', self._color_selected)
self.pack_start(toolbox, False)
toolbox.show()
spring = gtk.Label('')
self.pack_start(spring, True)
spring.show()
spring = gtk.Label('')
self.pack_start(spring, True)
spring.show()
def _color_selected(self, toolbox, color):
self._editor.set_color(color)
def _color_selected(self, toolbox, color):
self._editor.set_color(color)
def __link_activate_cb(self, item, link):
buf = self._editor.get_buffer()
buf.append_link(link['title'], link['address'])
def __link_activate_cb(self, item, link):
buf = self._editor.get_buffer()
buf.append_link(link['title'], link['address'])
def __show_link_menu_cb(self, button):
menu = gtk.Menu()
links = self.__get_browser_shell().get_links()
def __show_link_menu_cb(self, button):
menu = gtk.Menu()
links = self.__get_browser_shell().get_links()
for link in links:
item = gtk.MenuItem(link['title'], False)
item.connect("activate", self.__link_activate_cb, link)
menu.append(item)
item.show()
button.set_menu(menu)
for link in links:
item = gtk.MenuItem(link['title'], False)
item.connect("activate", self.__link_activate_cb, link)
menu.append(item)
item.show()
button.set_menu(menu)
def _create_emoticons_popup(self):
model = gtk.ListStore(gtk.gdk.Pixbuf, str)
for name in Emoticons.get_instance().get_all():
icon_theme = gtk.icon_theme_get_default()
try:
pixbuf = icon_theme.load_icon(name, 16, 0)
model.append([pixbuf, name])
except gobject.GError:
pass
def _create_emoticons_popup(self):
model = gtk.ListStore(gtk.gdk.Pixbuf, str)
for name in Emoticons.get_instance().get_all():
icon_theme = gtk.icon_theme_get_default()
try:
pixbuf = icon_theme.load_icon(name, 16, 0)
model.append([pixbuf, name])
except gobject.GError:
pass
icon_view = gtk.IconView(model)
icon_view.connect('selection-changed', self.__emoticon_selection_changed_cb)
icon_view.set_pixbuf_column(0)
icon_view.set_selection_mode(gtk.SELECTION_SINGLE)
frame = gtk.Frame()
frame.set_shadow_type(gtk.SHADOW_ETCHED_IN)
frame.add(icon_view)
icon_view.show()
window = gtk.Window(gtk.WINDOW_POPUP)
window.add(frame)
frame.show()
return window
def __emoticon_selection_changed_cb(self, icon_view):
items = icon_view.get_selected_items()
if items:
model = icon_view.get_model()
icon_name = model[items[0]][1]
self._editor.get_buffer().append_icon(icon_name)
self._emt_popup.hide()
def __emoticons_button_clicked_cb(self, button):
# FIXME grabs...
if not self._emt_popup:
self._emt_popup = self._create_emoticons_popup()
icon_view = gtk.IconView(model)
icon_view.connect('selection-changed', self.__emoticon_selection_changed_cb)
icon_view.set_pixbuf_column(0)
icon_view.set_selection_mode(gtk.SELECTION_SINGLE)
frame = gtk.Frame()
frame.set_shadow_type(gtk.SHADOW_ETCHED_IN)
frame.add(icon_view)
icon_view.show()
window = gtk.Window(gtk.WINDOW_POPUP)
window.add(frame)
frame.show()
return window
def __emoticon_selection_changed_cb(self, icon_view):
items = icon_view.get_selected_items()
if items:
model = icon_view.get_model()
icon_name = model[items[0]][1]
self._editor.get_buffer().append_icon(icon_name)
self._emt_popup.hide()
def __emoticons_button_clicked_cb(self, button):
# FIXME grabs...
if not self._emt_popup:
self._emt_popup = self._create_emoticons_popup()
if self._emt_popup.get_property('visible'):
self._emt_popup.hide()
else:
width = 180
height = 130
self._emt_popup.set_default_size(width, height)
[x, y] = button.window.get_origin()
x += button.allocation.x
y += button.allocation.y - height
self._emt_popup.move(x, y)
self._emt_popup.show()
if self._emt_popup.get_property('visible'):
self._emt_popup.hide()
else:
width = 180
height = 130
self._emt_popup.set_default_size(width, height)
[x, y] = button.window.get_origin()
x += button.allocation.x
y += button.allocation.y - height
self._emt_popup.move(x, y)
self._emt_popup.show()
+60 -60
View File
@@ -15,70 +15,70 @@
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
emoticons_table = [ \
[ 'stock_smiley-10', [ ':P', ':p' ] ], \
[ 'stock_smiley-19', None ], \
[ 'stock_smiley-2', None ], \
[ 'stock_smiley-11', None ], \
[ 'stock_smiley-1', [ ':)' ] ], \
[ 'stock_smiley-3', None ], \
[ 'stock_smiley-12', None ], \
[ 'stock_smiley-20', None ], \
[ 'stock_smiley-4', [ ':(' ] ], \
[ 'stock_smiley-13', None ], \
[ 'stock_smiley-21', None ], \
[ 'stock_smiley-5', None ], \
[ 'stock_smiley-14', None ], \
[ 'stock_smiley-22', None ], \
[ 'stock_smiley-6', None ], \
[ 'stock_smiley-15', None ], \
[ 'stock_smiley-23', None ], \
[ 'stock_smiley-7', None ], \
[ 'stock_smiley-16', None ], \
[ 'stock_smiley-24', None ], \
[ 'stock_smiley-8', None ], \
[ 'stock_smiley-17', None ], \
[ 'stock_smiley-25', None ], \
[ 'stock_smiley-9', None ], \
[ 'stock_smiley-18', None ], \
[ 'stock_smiley-26', None ], \
emoticons_table = [ \
[ 'stock_smiley-10', [ ':P', ':p' ] ], \
[ 'stock_smiley-19', None ], \
[ 'stock_smiley-2', None ], \
[ 'stock_smiley-11', None ], \
[ 'stock_smiley-1', [ ':)' ] ], \
[ 'stock_smiley-3', None ], \
[ 'stock_smiley-12', None ], \
[ 'stock_smiley-20', None ], \
[ 'stock_smiley-4', [ ':(' ] ], \
[ 'stock_smiley-13', None ], \
[ 'stock_smiley-21', None ], \
[ 'stock_smiley-5', None ], \
[ 'stock_smiley-14', None ], \
[ 'stock_smiley-22', None ], \
[ 'stock_smiley-6', None ], \
[ 'stock_smiley-15', None ], \
[ 'stock_smiley-23', None ], \
[ 'stock_smiley-7', None ], \
[ 'stock_smiley-16', None ], \
[ 'stock_smiley-24', None ], \
[ 'stock_smiley-8', None ], \
[ 'stock_smiley-17', None ], \
[ 'stock_smiley-25', None ], \
[ 'stock_smiley-9', None ], \
[ 'stock_smiley-18', None ], \
[ 'stock_smiley-26', None ], \
]
class Emoticons:
instance = None
instance = None
def get_instance():
if not Emoticons.instance:
Emoticons.instance = Emoticons()
return Emoticons.instance
def get_instance():
if not Emoticons.instance:
Emoticons.instance = Emoticons()
return Emoticons.instance
get_instance = staticmethod(get_instance)
get_instance = staticmethod(get_instance)
def __init__(self):
self._table = {}
def __init__(self):
self._table = {}
for emoticon in emoticons_table:
[ name, text_emts ] = emoticon
self.add(name, text_emts)
def add(self, icon_name, text=None):
self._table[icon_name] = text
def get_all(self):
return self._table.keys()
"""Replace emoticons text with the icon name.
Parse the provided text to find emoticons (in
textual form) and replace them with their xml
representation in the form:
<icon name="$EMOTICON_ICON_NAME"/>
"""
def replace(self, text):
for icon_name in self._table.keys():
text_emts = self._table[icon_name]
if text_emts:
for emoticon_text in text_emts:
xml = '<icon name="' + icon_name + '"/>'
text = text.replace(emoticon_text, xml)
return text
for emoticon in emoticons_table:
[ name, text_emts ] = emoticon
self.add(name, text_emts)
def add(self, icon_name, text=None):
self._table[icon_name] = text
def get_all(self):
return self._table.keys()
"""Replace emoticons text with the icon name.
Parse the provided text to find emoticons (in
textual form) and replace them with their xml
representation in the form:
<icon name="$EMOTICON_ICON_NAME"/>
"""
def replace(self, text):
for icon_name in self._table.keys():
text_emts = self._table[icon_name]
if text_emts:
for emoticon_text in text_emts:
xml = '<icon name="' + icon_name + '"/>'
text = text.replace(emoticon_text, xml)
return text
+10 -10
View File
@@ -23,15 +23,15 @@ from sugar.presence.PresenceService import PresenceService
import sugar.env
class GroupChat(Chat):
def __init__(self):
Chat.__init__(self)
self._group_stream = None
def __init__(self):
Chat.__init__(self)
self._group_stream = None
def _setup_stream(self, service):
self._group_stream = Stream.new_from_service(service)
self._group_stream.set_data_listener(self._group_recv_message)
self._stream_writer = self._group_stream.new_writer()
def _setup_stream(self, service):
self._group_stream = Stream.new_from_service(service)
self._group_stream.set_data_listener(self._group_recv_message)
self._stream_writer = self._group_stream.new_writer()
def _group_recv_message(self, address, msg):
logging.debug('Group chat received from %s message %s' % (address, msg))
self.recv_message(msg)
def _group_recv_message(self, address, msg):
logging.debug('Group chat received from %s message %s' % (address, msg))
self.recv_message(msg)
+366 -366
View File
@@ -21,431 +21,431 @@ import pango
import xml.sax
class RichTextView(gtk.TextView):
__gsignals__ = {
'link-clicked': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_STRING]))
}
__gsignals__ = {
'link-clicked': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_STRING]))
}
def __init__(self):
gtk.TextView.__init__(self, RichTextBuffer())
self.connect("motion-notify-event", self.__motion_notify_cb)
self.connect("button-press-event", self.__button_press_cb)
self.__hover_link = False
def __init__(self):
gtk.TextView.__init__(self, RichTextBuffer())
self.connect("motion-notify-event", self.__motion_notify_cb)
self.connect("button-press-event", self.__button_press_cb)
self.__hover_link = False
def _set_hover_link(self, hover_link):
if hover_link != self.__hover_link:
self.__hover_link = hover_link
display = self.get_toplevel().get_display()
child_window = self.get_window(gtk.TEXT_WINDOW_TEXT)
if hover_link:
cursor = gtk.gdk.Cursor(display, gtk.gdk.HAND2)
else:
cursor = gtk.gdk.Cursor(display, gtk.gdk.XTERM)
child_window.set_cursor(cursor)
gtk.gdk.flush()
def __iter_is_link(self, it):
item = self.get_buffer().get_tag_table().lookup("link")
if item:
return it.has_tag(item)
return False
def _set_hover_link(self, hover_link):
if hover_link != self.__hover_link:
self.__hover_link = hover_link
display = self.get_toplevel().get_display()
child_window = self.get_window(gtk.TEXT_WINDOW_TEXT)
if hover_link:
cursor = gtk.gdk.Cursor(display, gtk.gdk.HAND2)
else:
cursor = gtk.gdk.Cursor(display, gtk.gdk.XTERM)
child_window.set_cursor(cursor)
gtk.gdk.flush()
def __iter_is_link(self, it):
item = self.get_buffer().get_tag_table().lookup("link")
if item:
return it.has_tag(item)
return False
def __get_event_iter(self, event):
return self.get_iter_at_location(int(event.x), int(event.y))
def __get_event_iter(self, event):
return self.get_iter_at_location(int(event.x), int(event.y))
def __motion_notify_cb(self, widget, event):
if event.is_hint:
event.window.get_pointer();
it = self.__get_event_iter(event)
if it:
hover_link = self.__iter_is_link(it)
else:
hover_link = False
def __motion_notify_cb(self, widget, event):
if event.is_hint:
event.window.get_pointer();
it = self.__get_event_iter(event)
if it:
hover_link = self.__iter_is_link(it)
else:
hover_link = False
self._set_hover_link(hover_link)
def __button_press_cb(self, widget, event):
it = self.__get_event_iter(event)
if it and self.__iter_is_link(it):
buf = self.get_buffer()
address_tag = buf.get_tag_table().lookup("object-id")
self._set_hover_link(hover_link)
def __button_press_cb(self, widget, event):
it = self.__get_event_iter(event)
if it and self.__iter_is_link(it):
buf = self.get_buffer()
address_tag = buf.get_tag_table().lookup("object-id")
address_end = it.copy()
address_end.backward_to_tag_toggle(address_tag)
address_start = address_end.copy()
address_start.backward_to_tag_toggle(address_tag)
address = buf.get_text(address_start, address_end)
self.emit("link-clicked", address)
address_end = it.copy()
address_end.backward_to_tag_toggle(address_tag)
address_start = address_end.copy()
address_start.backward_to_tag_toggle(address_tag)
address = buf.get_text(address_start, address_end)
self.emit("link-clicked", address)
class RichTextBuffer(gtk.TextBuffer):
def __init__(self):
gtk.TextBuffer.__init__(self)
def __init__(self):
gtk.TextBuffer.__init__(self)
self.connect_after("insert-text", self.__insert_text_cb)
self.__create_tags()
self.active_tags = []
self.connect_after("insert-text", self.__insert_text_cb)
self.__create_tags()
self.active_tags = []
def append_link(self, title, address):
it = self.get_iter_at_mark(self.get_insert())
self.insert_with_tags_by_name(it, address, "link", "object-id")
self.insert_with_tags_by_name(it, title, "link")
def append_link(self, title, address):
it = self.get_iter_at_mark(self.get_insert())
self.insert_with_tags_by_name(it, address, "link", "object-id")
self.insert_with_tags_by_name(it, title, "link")
def append_icon(self, name, it = None):
if not it:
it = self.get_iter_at_mark(self.get_insert())
def append_icon(self, name, it = None):
if not it:
it = self.get_iter_at_mark(self.get_insert())
self.insert_with_tags_by_name(it, name, "icon", "object-id")
icon_theme = gtk.icon_theme_get_default()
try:
pixbuf = icon_theme.load_icon(name, 16, 0)
self.insert_pixbuf(it, pixbuf)
except gobject.GError:
pass
self.insert_with_tags_by_name(it, name, "icon", "object-id")
icon_theme = gtk.icon_theme_get_default()
try:
pixbuf = icon_theme.load_icon(name, 16, 0)
self.insert_pixbuf(it, pixbuf)
except gobject.GError:
pass
def apply_tag(self, tag_name):
self.active_tags.append(tag_name)
bounds = self.get_selection_bounds()
if bounds:
[start, end] = bounds
self.apply_tag_by_name(tag_name, start, end)
def apply_tag(self, tag_name):
self.active_tags.append(tag_name)
bounds = self.get_selection_bounds()
if bounds:
[start, end] = bounds
self.apply_tag_by_name(tag_name, start, end)
def unapply_tag(self, tag_name):
self.active_tags.remove(tag_name)
def unapply_tag(self, tag_name):
self.active_tags.remove(tag_name)
bounds = self.get_selection_bounds()
if bounds:
[start, end] = bounds
self.remove_tag_by_name(tag_name, start, end)
def __create_tags(self):
tag = self.create_tag("icon")
bounds = self.get_selection_bounds()
if bounds:
[start, end] = bounds
self.remove_tag_by_name(tag_name, start, end)
def __create_tags(self):
tag = self.create_tag("icon")
tag = self.create_tag("link")
tag.set_property("underline", pango.UNDERLINE_SINGLE)
tag.set_property("foreground", "#0000FF")
tag = self.create_tag("link")
tag.set_property("underline", pango.UNDERLINE_SINGLE)
tag.set_property("foreground", "#0000FF")
tag = self.create_tag("object-id")
tag.set_property("invisible", True)
tag = self.create_tag("object-id")
tag.set_property("invisible", True)
tag = self.create_tag("bold")
tag.set_property("weight", pango.WEIGHT_BOLD)
tag = self.create_tag("italic")
tag.set_property("style", pango.STYLE_ITALIC)
tag = self.create_tag("bold")
tag.set_property("weight", pango.WEIGHT_BOLD)
tag = self.create_tag("italic")
tag.set_property("style", pango.STYLE_ITALIC)
tag = self.create_tag("font-size-xx-small")
tag.set_property("scale", pango.SCALE_XX_SMALL)
tag = self.create_tag("font-size-xx-small")
tag.set_property("scale", pango.SCALE_XX_SMALL)
tag = self.create_tag("font-size-x-small")
tag.set_property("scale", pango.SCALE_X_SMALL)
tag = self.create_tag("font-size-x-small")
tag.set_property("scale", pango.SCALE_X_SMALL)
tag = self.create_tag("font-size-small")
tag.set_property("scale", pango.SCALE_SMALL)
tag = self.create_tag("font-size-small")
tag.set_property("scale", pango.SCALE_SMALL)
tag = self.create_tag("font-size-large")
tag.set_property("scale", pango.SCALE_LARGE)
tag = self.create_tag("font-size-large")
tag.set_property("scale", pango.SCALE_LARGE)
tag = self.create_tag("font-size-x-large")
tag.set_property("scale", pango.SCALE_X_LARGE)
tag = self.create_tag("font-size-x-large")
tag.set_property("scale", pango.SCALE_X_LARGE)
tag = self.create_tag("font-size-xx-large")
tag.set_property("scale", pango.SCALE_XX_LARGE)
def __insert_text_cb(self, widget, pos, text, length):
for tag in self.active_tags:
pos_end = pos.copy()
pos_end.backward_chars(length)
self.apply_tag_by_name(tag, pos, pos_end)
tag = self.create_tag("font-size-xx-large")
tag.set_property("scale", pango.SCALE_XX_LARGE)
def __insert_text_cb(self, widget, pos, text, length):
for tag in self.active_tags:
pos_end = pos.copy()
pos_end.backward_chars(length)
self.apply_tag_by_name(tag, pos, pos_end)
class RichTextToolbox(gtk.HBox):
def __init__(self, buf):
gtk.HBox.__init__(self, False, 6)
self.buf = buf
self._font_size = "normal"
self._font_scales = [ "xx-small", "x-small", "small", \
"normal", \
"large", "x-large", "xx-large" ]
image = gtk.Image()
image.set_from_stock(gtk.STOCK_BOLD, gtk.ICON_SIZE_SMALL_TOOLBAR)
def __init__(self, buf):
gtk.HBox.__init__(self, False, 6)
self.buf = buf
self._font_size = "normal"
self._font_scales = [ "xx-small", "x-small", "small", \
"normal", \
"large", "x-large", "xx-large" ]
image = gtk.Image()
image.set_from_stock(gtk.STOCK_BOLD, gtk.ICON_SIZE_SMALL_TOOLBAR)
item = gtk.ToggleButton()
item.set_image(image)
item.connect("toggled", self.__toggle_style_cb, "bold")
item.unset_flags(gtk.CAN_FOCUS)
self.pack_start(item, False)
item.show()
item = gtk.ToggleButton()
item.set_image(image)
item.connect("toggled", self.__toggle_style_cb, "bold")
item.unset_flags(gtk.CAN_FOCUS)
self.pack_start(item, False)
item.show()
image.show()
image.show()
image = gtk.Image()
image.set_from_stock(gtk.STOCK_ITALIC, gtk.ICON_SIZE_SMALL_TOOLBAR)
image = gtk.Image()
image.set_from_stock(gtk.STOCK_ITALIC, gtk.ICON_SIZE_SMALL_TOOLBAR)
item = gtk.ToggleButton()
item.set_image(image)
item.unset_flags(gtk.CAN_FOCUS)
item.connect("toggled", self.__toggle_style_cb, "italic")
self.pack_start(item, False)
item.show()
item = gtk.ToggleButton()
item.set_image(image)
item.unset_flags(gtk.CAN_FOCUS)
item.connect("toggled", self.__toggle_style_cb, "italic")
self.pack_start(item, False)
item.show()
image = gtk.Image()
image.set_from_stock(gtk.STOCK_GO_UP, gtk.ICON_SIZE_SMALL_TOOLBAR)
image = gtk.Image()
image.set_from_stock(gtk.STOCK_GO_UP, gtk.ICON_SIZE_SMALL_TOOLBAR)
self._font_size_up = gtk.Button()
self._font_size_up.set_image(image)
self._font_size_up.unset_flags(gtk.CAN_FOCUS)
self._font_size_up.connect("clicked", self.__font_size_up_cb)
self.pack_start(self._font_size_up, False)
self._font_size_up.show()
image.show()
self._font_size_up = gtk.Button()
self._font_size_up.set_image(image)
self._font_size_up.unset_flags(gtk.CAN_FOCUS)
self._font_size_up.connect("clicked", self.__font_size_up_cb)
self.pack_start(self._font_size_up, False)
self._font_size_up.show()
image.show()
image = gtk.Image()
image.set_from_stock(gtk.STOCK_GO_DOWN, gtk.ICON_SIZE_SMALL_TOOLBAR)
image = gtk.Image()
image.set_from_stock(gtk.STOCK_GO_DOWN, gtk.ICON_SIZE_SMALL_TOOLBAR)
self._font_size_down = gtk.Button()
self._font_size_down.set_image(image)
self._font_size_down.unset_flags(gtk.CAN_FOCUS)
self._font_size_down.connect("clicked", self.__font_size_down_cb)
self.pack_start(self._font_size_down, False)
self._font_size_down.show()
image.show()
def _get_font_size_index(self):
return self._font_scales.index(self._font_size);
def __toggle_style_cb(self, toggle, tag_name):
if toggle.get_active():
self.buf.apply_tag(tag_name)
else:
self.buf.unapply_tag(tag_name)
self._font_size_down = gtk.Button()
self._font_size_down.set_image(image)
self._font_size_down.unset_flags(gtk.CAN_FOCUS)
self._font_size_down.connect("clicked", self.__font_size_down_cb)
self.pack_start(self._font_size_down, False)
self._font_size_down.show()
image.show()
def _get_font_size_index(self):
return self._font_scales.index(self._font_size);
def __toggle_style_cb(self, toggle, tag_name):
if toggle.get_active():
self.buf.apply_tag(tag_name)
else:
self.buf.unapply_tag(tag_name)
def _set_font_size(self, font_size):
if self._font_size != "normal":
self.buf.unapply_tag("font-size-" + self._font_size)
if font_size != "normal":
self.buf.apply_tag("font-size-" + font_size)
self._font_size = font_size
can_up = self._get_font_size_index() < len(self._font_scales) - 1
can_down = self._get_font_size_index() > 0
self._font_size_up.set_sensitive(can_up)
self._font_size_down.set_sensitive(can_down)
def _set_font_size(self, font_size):
if self._font_size != "normal":
self.buf.unapply_tag("font-size-" + self._font_size)
if font_size != "normal":
self.buf.apply_tag("font-size-" + font_size)
self._font_size = font_size
can_up = self._get_font_size_index() < len(self._font_scales) - 1
can_down = self._get_font_size_index() > 0
self._font_size_up.set_sensitive(can_up)
self._font_size_down.set_sensitive(can_down)
def __font_size_up_cb(self, button):
index = self._get_font_size_index()
if index + 1 < len(self._font_scales):
self._set_font_size(self._font_scales[index + 1])
def __font_size_up_cb(self, button):
index = self._get_font_size_index()
if index + 1 < len(self._font_scales):
self._set_font_size(self._font_scales[index + 1])
def __font_size_down_cb(self, button):
index = self._get_font_size_index()
if index > 0:
self._set_font_size(self._font_scales[index - 1])
def __font_size_down_cb(self, button):
index = self._get_font_size_index()
if index > 0:
self._set_font_size(self._font_scales[index - 1])
class RichTextHandler(xml.sax.handler.ContentHandler):
def __init__(self, serializer, buf):
xml.sax.handler.ContentHandler.__init__(self)
self.buf = buf
self.serializer = serializer
self.tags = []
self._in_richtext = False
self._done = False
def __init__(self, serializer, buf):
xml.sax.handler.ContentHandler.__init__(self)
self.buf = buf
self.serializer = serializer
self.tags = []
self._in_richtext = False
self._done = False
def startElement(self, name, attrs):
# Look for, and only start parsing after 'richtext'
if not self._in_richtext and name == "richtext":
self._in_richtext = True
if not self._in_richtext:
return
def startElement(self, name, attrs):
# Look for, and only start parsing after 'richtext'
if not self._in_richtext and name == "richtext":
self._in_richtext = True
if not self._in_richtext:
return
if name != "richtext":
tag = self.serializer.deserialize_element(name, attrs)
self.tags.append(tag)
if name == "link":
self.href = attrs['href']
elif name == "icon":
self.buf.append_icon(attrs['name'], self.buf.get_end_iter())
if name != "richtext":
tag = self.serializer.deserialize_element(name, attrs)
self.tags.append(tag)
if name == "link":
self.href = attrs['href']
elif name == "icon":
self.buf.append_icon(attrs['name'], self.buf.get_end_iter())
def characters(self, data):
start_it = it = self.buf.get_end_iter()
mark = self.buf.create_mark(None, start_it, True)
self.buf.insert(it, data)
start_it = self.buf.get_iter_at_mark(mark)
def characters(self, data):
start_it = it = self.buf.get_end_iter()
mark = self.buf.create_mark(None, start_it, True)
self.buf.insert(it, data)
start_it = self.buf.get_iter_at_mark(mark)
for tag in self.tags:
self.buf.apply_tag_by_name(tag, start_it, it)
if tag == "link":
self.buf.insert_with_tags_by_name(start_it, self.href,
"link", "object-id")
for tag in self.tags:
self.buf.apply_tag_by_name(tag, start_it, it)
if tag == "link":
self.buf.insert_with_tags_by_name(start_it, self.href,
"link", "object-id")
def endElement(self, name):
if not self._done and self._in_richtext:
if name != "richtext":
self.tags.pop()
if name == "richtext":
self._done = True
self._in_richtext = False
def endElement(self, name):
if not self._done and self._in_richtext:
if name != "richtext":
self.tags.pop()
if name == "richtext":
self._done = True
self._in_richtext = False
class RichTextSerializer:
def __init__(self):
self._open_tags = []
def __init__(self):
self._open_tags = []
def deserialize_element(self, el_name, attributes):
if el_name == "bold":
return "bold"
elif el_name == "italic":
return "italic"
elif el_name == "font":
return "font-size-" + attributes["size"]
elif el_name == "link":
return "link"
elif el_name == "icon":
return "icon"
else:
return None
def deserialize_element(self, el_name, attributes):
if el_name == "bold":
return "bold"
elif el_name == "italic":
return "italic"
elif el_name == "font":
return "font-size-" + attributes["size"]
elif el_name == "link":
return "link"
elif el_name == "icon":
return "icon"
else:
return None
def _parse_object_id(self, it):
object_id_tag = self.buf.get_tag_table().lookup("object-id")
end = it.copy()
end.forward_to_tag_toggle(object_id_tag)
return self.buf.get_text(it, end)
def _parse_object_id(self, it):
object_id_tag = self.buf.get_tag_table().lookup("object-id")
end = it.copy()
end.forward_to_tag_toggle(object_id_tag)
return self.buf.get_text(it, end)
def serialize_tag_start(self, tag, it):
name = tag.get_property("name")
if name == "bold":
return "<bold>"
elif name == "italic":
return "<italic>"
elif name == "link":
address = self._parse_object_id(it)
return "<link " + "href=\"" + address + "\">"
elif name == "icon":
name = self._parse_object_id(it)
return "<icon " + "name=\"" + name + "\"/>"
elif name == "object-id":
return ""
elif name.startswith("font-size-"):
tag_name = name.replace("font-size-", "", 1)
return "<font size=\"" + tag_name + "\">"
else:
return "<unknown>"
def serialize_tag_start(self, tag, it):
name = tag.get_property("name")
if name == "bold":
return "<bold>"
elif name == "italic":
return "<italic>"
elif name == "link":
address = self._parse_object_id(it)
return "<link " + "href=\"" + address + "\">"
elif name == "icon":
name = self._parse_object_id(it)
return "<icon " + "name=\"" + name + "\"/>"
elif name == "object-id":
return ""
elif name.startswith("font-size-"):
tag_name = name.replace("font-size-", "", 1)
return "<font size=\"" + tag_name + "\">"
else:
return "<unknown>"
def serialize_tag_end(self, tag):
name = tag.get_property("name")
if name == "bold":
return "</bold>"
elif name == "italic":
return "</italic>"
elif name == "link":
return "</link>"
elif name == "icon":
return ""
elif name == "object-id":
return ""
elif name.startswith("font-size-"):
return "</font>"
else:
return "</unknown>"
def serialize(self, buf):
self.buf = buf
res = "<richtext>"
def serialize_tag_end(self, tag):
name = tag.get_property("name")
if name == "bold":
return "</bold>"
elif name == "italic":
return "</italic>"
elif name == "link":
return "</link>"
elif name == "icon":
return ""
elif name == "object-id":
return ""
elif name.startswith("font-size-"):
return "</font>"
else:
return "</unknown>"
def serialize(self, buf):
self.buf = buf
res = "<richtext>"
next_it = buf.get_start_iter()
while not next_it.is_end():
it = next_it.copy()
if not next_it.forward_to_tag_toggle(None):
next_it = buf.get_end_iter()
next_it = buf.get_start_iter()
while not next_it.is_end():
it = next_it.copy()
if not next_it.forward_to_tag_toggle(None):
next_it = buf.get_end_iter()
tags_to_reopen = []
tags_to_reopen = []
for tag in it.get_toggled_tags(False):
while 1:
open_tag = self._open_tags.pop()
res += self.serialize_tag_end(tag)
if open_tag == tag:
break
tags_to_reopen.append(open_tag)
for tag in tags_to_reopen:
self._open_tags.append(tag)
res += self.serialize_tag_start(tag, it)
for tag in it.get_toggled_tags(True):
self._open_tags.append(tag)
res += self.serialize_tag_start(tag, it)
res += buf.get_text(it, next_it, False)
for tag in it.get_toggled_tags(False):
while 1:
open_tag = self._open_tags.pop()
res += self.serialize_tag_end(tag)
if open_tag == tag:
break
tags_to_reopen.append(open_tag)
for tag in tags_to_reopen:
self._open_tags.append(tag)
res += self.serialize_tag_start(tag, it)
for tag in it.get_toggled_tags(True):
self._open_tags.append(tag)
res += self.serialize_tag_start(tag, it)
res += buf.get_text(it, next_it, False)
if next_it.is_end():
self._open_tags.reverse()
for tag in self._open_tags:
res += self.serialize_tag_end(tag)
res += "</richtext>"
return res
if next_it.is_end():
self._open_tags.reverse()
for tag in self._open_tags:
res += self.serialize_tag_end(tag)
res += "</richtext>"
return res
def deserialize(self, xml_string, buf):
parser = xml.sax.make_parser()
handler = RichTextHandler(self, buf)
parser.setContentHandler(handler)
parser.feed(xml_string)
parser.close()
def deserialize(self, xml_string, buf):
parser = xml.sax.make_parser()
handler = RichTextHandler(self, buf)
parser.setContentHandler(handler)
parser.feed(xml_string)
parser.close()
def test_quit(w, rb):
print RichTextSerializer().serialize(rb)
gtk.main_quit()
print RichTextSerializer().serialize(rb)
gtk.main_quit()
def link_clicked(v, address):
print "Link clicked " + address
print "Link clicked " + address
if __name__ == "__main__":
window = gtk.Window()
window.set_default_size(400, 300)
vbox = gtk.VBox()
view = RichTextView()
view.connect("link-clicked", link_clicked)
vbox.pack_start(view)
view.show()
window = gtk.Window()
window.set_default_size(400, 300)
vbox = gtk.VBox()
view = RichTextView()
view.connect("link-clicked", link_clicked)
vbox.pack_start(view)
view.show()
rich_buf = view.get_buffer()
test_xml = "<richtext>"
rich_buf = view.get_buffer()
test_xml = "<richtext>"
test_xml += "<bold><italic>Test</italic>one</bold>\n"
test_xml += "<bold><italic>Test two</italic></bold>"
test_xml += "<font size=\"xx-small\">Test three</font>"
test_xml += "<link href=\"http://www.gnome.org\">Test link</link>"
test_xml += "<icon name=\"stock_help-chat\"/>"
test_xml += "</richtext>"
test_xml += "<bold><italic>Test</italic>one</bold>\n"
test_xml += "<bold><italic>Test two</italic></bold>"
test_xml += "<font size=\"xx-small\">Test three</font>"
test_xml += "<link href=\"http://www.gnome.org\">Test link</link>"
test_xml += "<icon name=\"stock_help-chat\"/>"
test_xml += "</richtext>"
RichTextSerializer().deserialize(test_xml, rich_buf)
toolbar = RichTextToolbar(rich_buf)
vbox.pack_start(toolbar, False)
toolbar.show()
window.add(vbox)
vbox.show()
window.show()
window.connect("destroy", test_quit, rich_buf)
RichTextSerializer().deserialize(test_xml, rich_buf)
toolbar = RichTextToolbar(rich_buf)
vbox.pack_start(toolbar, False)
toolbar.show()
window.add(vbox)
vbox.show()
window.show()
window.connect("destroy", test_quit, rich_buf)
gtk.main()
gtk.main()
+33 -33
View File
@@ -18,37 +18,37 @@
from SVGdraw import path
class Sketch:
def __init__(self, rgb):
self._points = []
self._rgb = (float(rgb[0]), float(rgb[1]), float(rgb[2]))
def add_point(self, x, y):
self._points.append((x, y))
def __init__(self, rgb):
self._points = []
self._rgb = (float(rgb[0]), float(rgb[1]), float(rgb[2]))
def add_point(self, x, y):
self._points.append((x, y))
def get_points(self):
return self._points
def draw(self, ctx):
start = True
for (x, y) in self._points:
if start:
ctx.move_to(x, y)
start = False
else:
ctx.line_to(x, y)
ctx.set_source_rgb(self._rgb[0], self._rgb[1], self._rgb[2])
ctx.stroke()
def draw_to_svg(self):
i = 0
for (x, y) in self._points:
coords = str(x) + ' ' + str(y) + ' '
if i == 0:
path_data = 'M ' + coords
elif i == 1:
path_data += 'L ' + coords
else:
path_data += coords
i += 1
color = "#%02X%02X%02X" % (255 * self._rgb[0], 255 * self._rgb[1], 255 * self._rgb[2])
return path(path_data, fill = 'none', stroke = color)
def get_points(self):
return self._points
def draw(self, ctx):
start = True
for (x, y) in self._points:
if start:
ctx.move_to(x, y)
start = False
else:
ctx.line_to(x, y)
ctx.set_source_rgb(self._rgb[0], self._rgb[1], self._rgb[2])
ctx.stroke()
def draw_to_svg(self):
i = 0
for (x, y) in self._points:
coords = str(x) + ' ' + str(y) + ' '
if i == 0:
path_data = 'M ' + coords
elif i == 1:
path_data += 'L ' + coords
else:
path_data += coords
i += 1
color = "#%02X%02X%02X" % (255 * self._rgb[0], 255 * self._rgb[1], 255 * self._rgb[2])
return path(path_data, fill = 'none', stroke = color)
+85 -85
View File
@@ -23,101 +23,101 @@ from SVGdraw import drawing
from SVGdraw import svg
class SketchPad(gtk.DrawingArea):
__gsignals__ = {
'new-user-sketch':(gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT]))
}
__gsignals__ = {
'new-user-sketch':(gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT]))
}
def __init__(self, bgcolor=(0.6, 1, 0.4)):
gtk.DrawingArea.__init__(self)
def __init__(self, bgcolor=(0.6, 1, 0.4)):
gtk.DrawingArea.__init__(self)
self._active_sketch = None
self._rgb = (0.0, 0.0, 0.0)
self._bgcolor = bgcolor
self._sketches = []
self._active_sketch = None
self._rgb = (0.0, 0.0, 0.0)
self._bgcolor = bgcolor
self._sketches = []
self.add_events(gtk.gdk.BUTTON_PRESS_MASK |
gtk.gdk.BUTTON_RELEASE_MASK |
gtk.gdk.BUTTON1_MOTION_MASK)
self.connect("button-press-event", self._button_press_cb)
self.connect("button-release-event", self._button_release_cb)
self.connect("motion-notify-event", self._motion_notify_cb)
self.connect('expose_event', self.expose)
def clear(self):
self._sketches = []
self.window.invalidate_rect(None, False)
self.add_events(gtk.gdk.BUTTON_PRESS_MASK |
gtk.gdk.BUTTON_RELEASE_MASK |
gtk.gdk.BUTTON1_MOTION_MASK)
self.connect("button-press-event", self._button_press_cb)
self.connect("button-release-event", self._button_release_cb)
self.connect("motion-notify-event", self._motion_notify_cb)
self.connect('expose_event', self.expose)
def clear(self):
self._sketches = []
self.window.invalidate_rect(None, False)
def expose(self, widget, event):
"""Draw the background of the sketchpad."""
rect = self.get_allocation()
ctx = widget.window.cairo_create()
ctx.set_source_rgb(self._bgcolor[0], self._bgcolor[1], self._bgcolor[2])
ctx.rectangle(0, 0, rect.width, rect.height)
ctx.fill_preserve()
ctx.set_source_rgb(0, 0.3, 0.2)
ctx.stroke()
for sketch in self._sketches:
sketch.draw(ctx)
return False
def expose(self, widget, event):
"""Draw the background of the sketchpad."""
rect = self.get_allocation()
ctx = widget.window.cairo_create()
ctx.set_source_rgb(self._bgcolor[0], self._bgcolor[1], self._bgcolor[2])
ctx.rectangle(0, 0, rect.width, rect.height)
ctx.fill_preserve()
ctx.set_source_rgb(0, 0.3, 0.2)
ctx.stroke()
for sketch in self._sketches:
sketch.draw(ctx)
return False
def set_color(self, color):
"""Sets the current drawing color of the sketchpad.
color agument should be 3-item tuple of rgb values between 0 and 1."""
self._rgb = color
def set_color(self, color):
"""Sets the current drawing color of the sketchpad.
color agument should be 3-item tuple of rgb values between 0 and 1."""
self._rgb = color
def add_sketch(self, sketch):
"""Add a sketch to the the pad. Mostly for subclasses and clients."""
self._sketches.append(sketch)
self.window.invalidate_rect(None, False)
def add_sketch(self, sketch):
"""Add a sketch to the the pad. Mostly for subclasses and clients."""
self._sketches.append(sketch)
self.window.invalidate_rect(None, False)
def add_point(self, event):
if not self._active_sketch:
return
self._active_sketch.add_point(event.x, event.y)
self.window.invalidate_rect(None, False)
def _button_press_cb(self, widget, event):
self._active_sketch = Sketch(self._rgb)
self._sketches.append(self._active_sketch)
self.add_point(event)
def _button_release_cb(self, widget, event):
self.add_point(event)
self.emit('new-user-sketch', self._active_sketch)
self._active_sketch = None
def _motion_notify_cb(self, widget, event):
self.add_point(event)
def to_svg(self):
"""Return a string containing an SVG representation of this sketch."""
d = drawing()
s = svg()
for sketch in self._sketches:
s.addElement(sketch.draw_to_svg())
d.setSVG(s)
return d.toXml()
def add_point(self, event):
if not self._active_sketch:
return
self._active_sketch.add_point(event.x, event.y)
self.window.invalidate_rect(None, False)
def _button_press_cb(self, widget, event):
self._active_sketch = Sketch(self._rgb)
self._sketches.append(self._active_sketch)
self.add_point(event)
def _button_release_cb(self, widget, event):
self.add_point(event)
self.emit('new-user-sketch', self._active_sketch)
self._active_sketch = None
def _motion_notify_cb(self, widget, event):
self.add_point(event)
def to_svg(self):
"""Return a string containing an SVG representation of this sketch."""
d = drawing()
s = svg()
for sketch in self._sketches:
s.addElement(sketch.draw_to_svg())
d.setSVG(s)
return d.toXml()
def test_quit(w, skpad):
print skpad.to_svg()
gtk.main_quit()
print skpad.to_svg()
gtk.main_quit()
if __name__ == "__main__":
window = gtk.Window()
window.set_default_size(400, 300)
window.connect("destroy", lambda w: gtk.main_quit())
window = gtk.Window()
window.set_default_size(400, 300)
window.connect("destroy", lambda w: gtk.main_quit())
sketchpad = SketchPad()
window.add(sketchpad)
sketchpad.show()
window.show()
window.connect("destroy", test_quit, sketchpad)
sketchpad = SketchPad()
window.add(sketchpad)
sketchpad.show()
window.show()
window.connect("destroy", test_quit, sketchpad)
gtk.main()
gtk.main()
+47 -47
View File
@@ -19,59 +19,59 @@ import gtk
import gobject
class ColorButton(gtk.RadioButton):
def __init__(self, group, rgb):
gtk.RadioButton.__init__(self, group)
self._rgb = rgb
self.set_mode(False)
self.set_relief(gtk.RELIEF_NONE)
drawing_area = gtk.DrawingArea()
drawing_area.set_size_request(24, 24)
drawing_area.connect_after('expose_event', self.expose)
self.add(drawing_area)
drawing_area.show()
def __init__(self, group, rgb):
gtk.RadioButton.__init__(self, group)
self._rgb = rgb
self.set_mode(False)
self.set_relief(gtk.RELIEF_NONE)
drawing_area = gtk.DrawingArea()
drawing_area.set_size_request(24, 24)
drawing_area.connect_after('expose_event', self.expose)
self.add(drawing_area)
drawing_area.show()
def color(self):
return self._rgb
def color(self):
return self._rgb
def expose(self, widget, event):
rect = widget.get_allocation()
ctx = widget.window.cairo_create()
def expose(self, widget, event):
rect = widget.get_allocation()
ctx = widget.window.cairo_create()
ctx.set_source_rgb(self._rgb[0], self._rgb[1] , self._rgb[2])
ctx.rectangle(4, 4, rect.width - 8, rect.height - 8)
ctx.fill()
return False
ctx.set_source_rgb(self._rgb[0], self._rgb[1] , self._rgb[2])
ctx.rectangle(4, 4, rect.width - 8, rect.height - 8)
ctx.fill()
return False
class Toolbox(gtk.HBox):
__gsignals__ = {
'color-selected': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT]))
}
__gsignals__ = {
'color-selected': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT]))
}
def __init__(self):
gtk.HBox.__init__(self, False, 6)
self._colors_group = None
self._add_color([0, 0, 0])
self._add_color([1, 0, 0])
self._add_color([0, 1, 0])
self._add_color([0, 0, 1])
def _add_color(self, rgb):
color = ColorButton(self._colors_group, rgb)
color.unset_flags(gtk.CAN_FOCUS)
color.connect('clicked', self.__color_clicked_cb, rgb)
self.pack_start(color, False)
def __init__(self):
gtk.HBox.__init__(self, False, 6)
self._colors_group = None
self._add_color([0, 0, 0])
self._add_color([1, 0, 0])
self._add_color([0, 1, 0])
self._add_color([0, 0, 1])
def _add_color(self, rgb):
color = ColorButton(self._colors_group, rgb)
color.unset_flags(gtk.CAN_FOCUS)
color.connect('clicked', self.__color_clicked_cb, rgb)
self.pack_start(color, False)
if self._colors_group == None:
self._colors_group = color
if self._colors_group == None:
self._colors_group = color
color.show()
color.show()
def __color_clicked_cb(self, button, rgb):
self.emit("color-selected", button.color())
def __color_clicked_cb(self, button, rgb):
self.emit("color-selected", button.color())
+59 -59
View File
@@ -7,69 +7,69 @@ DBUS_PATH = "/org/laptop/Clipboard"
class ClipboardService(gobject.GObject):
__gsignals__ = {
'object-added': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([str, str, str])),
'object-deleted': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([str])),
'object-state-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([str, int])),
}
def __init__(self):
gobject.GObject.__init__(self)
self._dbus_service = None
bus = dbus.SessionBus()
bus.add_signal_receiver(self._name_owner_changed_cb,
signal_name="NameOwnerChanged",
dbus_interface="org.freedesktop.DBus")
# Try to register to ClipboardService, if we fail, we'll try later.
try:
self._connect_clipboard_signals()
except dbus.DBusException, exception:
pass
def _connect_clipboard_signals(self):
bus = dbus.SessionBus()
proxy_obj = bus.get_object(DBUS_SERVICE, DBUS_PATH)
self._dbus_service = dbus.Interface(proxy_obj, DBUS_SERVICE)
self._dbus_service.connect_to_signal('object_added',
self._object_added_cb)
self._dbus_service.connect_to_signal('object_deleted',
self._object_deleted_cb)
self._dbus_service.connect_to_signal('object_state_changed',
self._object_state_changed_cb)
__gsignals__ = {
'object-added': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([str, str, str])),
'object-deleted': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([str])),
'object-state-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([str, int])),
}
def __init__(self):
gobject.GObject.__init__(self)
self._dbus_service = None
bus = dbus.SessionBus()
bus.add_signal_receiver(self._name_owner_changed_cb,
signal_name="NameOwnerChanged",
dbus_interface="org.freedesktop.DBus")
# Try to register to ClipboardService, if we fail, we'll try later.
try:
self._connect_clipboard_signals()
except dbus.DBusException, exception:
pass
def _connect_clipboard_signals(self):
bus = dbus.SessionBus()
proxy_obj = bus.get_object(DBUS_SERVICE, DBUS_PATH)
self._dbus_service = dbus.Interface(proxy_obj, DBUS_SERVICE)
self._dbus_service.connect_to_signal('object_added',
self._object_added_cb)
self._dbus_service.connect_to_signal('object_deleted',
self._object_deleted_cb)
self._dbus_service.connect_to_signal('object_state_changed',
self._object_state_changed_cb)
def _name_owner_changed_cb(self, name, old, new):
if name != DBUS_SERVICE:
return
if (not old and not len(old)) and (new and len(new)):
# ClipboardService started up
self._connect_clipboard_signals()
def _object_added_cb(self, name, mimeType, fileName):
self.emit('object-added', name, mimeType, fileName)
def _name_owner_changed_cb(self, name, old, new):
if name != DBUS_SERVICE:
return
if (not old and not len(old)) and (new and len(new)):
# ClipboardService started up
self._connect_clipboard_signals()
def _object_added_cb(self, name, mimeType, fileName):
self.emit('object-added', name, mimeType, fileName)
def _object_deleted_cb(self, fileName):
self.emit('object-deleted', fileName)
def _object_deleted_cb(self, fileName):
self.emit('object-deleted', fileName)
def _object_state_changed_cb(self, fileName, percent):
self.emit('object-state-changed', fileName, percent)
def add_object(self, name, mimeType, fileName):
self._dbus_service.add_object(name, mimeType, fileName)
def _object_state_changed_cb(self, fileName, percent):
self.emit('object-state-changed', fileName, percent)
def add_object(self, name, mimeType, fileName):
self._dbus_service.add_object(name, mimeType, fileName)
def delete_object(self, fileName):
self._dbus_service.delete_object(fileName)
def set_object_state(self, fileName, percent):
self._dbus_service.set_object_state(fileName, percent)
def delete_object(self, fileName):
self._dbus_service.delete_object(fileName)
def set_object_state(self, fileName, percent):
self._dbus_service.set_object_state(fileName, percent)
_clipboard_service = None
def get_instance():
global _clipboard_service
if not _clipboard_service:
_clipboard_service = ClipboardService()
return _clipboard_service
global _clipboard_service
if not _clipboard_service:
_clipboard_service = ClipboardService()
return _clipboard_service
+84 -84
View File
@@ -24,108 +24,108 @@ import gobject
from sugar import env
def get_display_number():
"""Find a free display number trying to connect to 6000+ ports"""
retries = 20
display_number = 1
display_is_free = False
"""Find a free display number trying to connect to 6000+ ports"""
retries = 20
display_number = 1
display_is_free = False
while not display_is_free and retries > 0:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.connect(('127.0.0.1', 6000 + display_number))
s.close()
while not display_is_free and retries > 0:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.connect(('127.0.0.1', 6000 + display_number))
s.close()
display_number += 1
retries -= 1
except:
display_is_free = True
display_number += 1
retries -= 1
except:
display_is_free = True
if display_is_free:
return display_number
else:
logging.error('Cannot find a free display.')
sys.exit(0)
if display_is_free:
return display_number
else:
logging.error('Cannot find a free display.')
sys.exit(0)
class Process:
"""Object representing one of the session processes"""
"""Object representing one of the session processes"""
def __init__(self, command):
self._command = command
def get_name(self):
return self._command
def start(self, standard_output=False):
args = self._command.split()
flags = gobject.SPAWN_SEARCH_PATH
result = gobject.spawn_async(args, flags=flags,
standard_output=standard_output)
self.pid = result[0]
self._stdout = result[2]
def __init__(self, command):
self._command = command
def get_name(self):
return self._command
def start(self, standard_output=False):
args = self._command.split()
flags = gobject.SPAWN_SEARCH_PATH
result = gobject.spawn_async(args, flags=flags,
standard_output=standard_output)
self.pid = result[0]
self._stdout = result[2]
class MatchboxProcess(Process):
def __init__(self):
kbd_config = os.path.join(env.get_data_dir(), 'kbdconfig')
options = '-kbdconfig %s ' % kbd_config
def __init__(self):
kbd_config = os.path.join(env.get_data_dir(), 'kbdconfig')
options = '-kbdconfig %s ' % kbd_config
options += '-use_titlebar no '
options += '-theme olpc '
options += '-use_titlebar no '
options += '-theme olpc '
command = 'matchbox-window-manager %s ' % options
Process.__init__(self, command)
def get_name(self):
return 'Matchbox'
command = 'matchbox-window-manager %s ' % options
Process.__init__(self, command)
def get_name(self):
return 'Matchbox'
class XephyrProcess(Process):
def __init__(self, fullscreen):
self._display = get_display_number()
cmd = 'Xephyr :%d -ac ' % (self._display)
if fullscreen:
cmd += '-fullscreen '
else:
cmd += '-screen 800x600 '
Process.__init__(self, cmd)
def get_name(self):
return 'Xephyr'
def __init__(self, fullscreen):
self._display = get_display_number()
cmd = 'Xephyr :%d -ac ' % (self._display)
if fullscreen:
cmd += '-fullscreen '
else:
cmd += '-screen 800x600 '
Process.__init__(self, cmd)
def get_name(self):
return 'Xephyr'
def start(self):
Process.start(self)
os.environ['DISPLAY'] = ":%d" % (self._display)
os.environ['SUGAR_XEPHYR_PID'] = '%d' % self.pid
def start(self):
Process.start(self)
os.environ['DISPLAY'] = ":%d" % (self._display)
os.environ['SUGAR_XEPHYR_PID'] = '%d' % self.pid
class XnestProcess(Process):
def __init__(self):
self._display = get_display_number()
cmd = 'Xnest :%d -ac -geometry 800x600' % (self._display)
Process.__init__(self, cmd)
def get_name(self):
return 'Xnest'
def __init__(self):
self._display = get_display_number()
cmd = 'Xnest :%d -ac -geometry 800x600' % (self._display)
Process.__init__(self, cmd)
def get_name(self):
return 'Xnest'
def start(self):
Process.start(self)
os.environ['DISPLAY'] = ":%d" % (self._display)
def start(self):
Process.start(self)
os.environ['DISPLAY'] = ":%d" % (self._display)
class Emulator(object):
"""The OLPC emulator"""
def __init__(self, fullscreen):
self._fullscreen = fullscreen
"""The OLPC emulator"""
def __init__(self, fullscreen):
self._fullscreen = fullscreen
def start(self):
try:
process = XephyrProcess(self._fullscreen)
process.start()
except:
try:
process = XnestProcess()
process.start()
except:
print 'Cannot run the emulator. You need to install \
Xephyr or Xnest.'
sys.exit(0)
def start(self):
try:
process = XephyrProcess(self._fullscreen)
process.start()
except:
try:
process = XnestProcess()
process.start()
except:
print 'Cannot run the emulator. You need to install \
Xephyr or Xnest.'
sys.exit(0)
process = MatchboxProcess()
process.start()
process = MatchboxProcess()
process.start()
+24 -24
View File
@@ -20,43 +20,43 @@ import sys
import pwd
try:
from sugar.__uninstalled__ import *
from sugar.__uninstalled__ import *
except ImportError:
from sugar.__installed__ import *
from sugar.__installed__ import *
def get_profile_path():
if os.environ.has_key('SUGAR_PROFILE'):
profile_id = os.environ['SUGAR_PROFILE']
else:
profile_id = 'default'
if os.environ.has_key('SUGAR_PROFILE'):
profile_id = os.environ['SUGAR_PROFILE']
else:
profile_id = 'default'
path = os.path.join(os.path.expanduser('~/.sugar'), profile_id)
if not os.path.isdir(path):
try:
os.makedirs(path)
except OSError, exc:
print "Could not create user directory."
path = os.path.join(os.path.expanduser('~/.sugar'), profile_id)
if not os.path.isdir(path):
try:
os.makedirs(path)
except OSError, exc:
print "Could not create user directory."
return path
return path
def get_data_dir():
return sugar_data_dir
return sugar_data_dir
def get_services_dir():
return sugar_services_dir
return sugar_services_dir
def get_shell_bin_dir():
return sugar_shell_bin_dir
return sugar_shell_bin_dir
# http://standards.freedesktop.org/basedir-spec/basedir-spec-0.6.html
def get_data_dirs():
if os.environ.has_key('XDG_DATA_DIRS'):
return os.environ['XDG_DATA_DIRS'].split(':')
else:
return [ '/usr/local/share/', '/usr/share/' ]
if os.environ.has_key('XDG_DATA_DIRS'):
return os.environ['XDG_DATA_DIRS'].split(':')
else:
return [ '/usr/local/share/', '/usr/share/' ]
def get_user_service_dir():
service_dir = os.path.expanduser('~/.local/share/dbus-1/services')
if not os.path.isdir(service_dir):
os.makedirs(service_dir)
return service_dir
service_dir = os.path.expanduser('~/.local/share/dbus-1/services')
if not os.path.isdir(service_dir):
os.makedirs(service_dir)
return service_dir
+90 -90
View File
@@ -24,108 +24,108 @@ import gtk
import hippo
class ClipboardBubble(hippo.CanvasBox, hippo.CanvasItem):
__gtype_name__ = 'ClipboardBubble'
__gtype_name__ = 'ClipboardBubble'
__gproperties__ = {
'fill-color': (object, None, None,
gobject.PARAM_READWRITE),
'stroke-color': (object, None, None,
gobject.PARAM_READWRITE),
'progress-color': (object, None, None,
gobject.PARAM_READWRITE),
'percent' : (object, None, None,
gobject.PARAM_READWRITE),
}
__gproperties__ = {
'fill-color': (object, None, None,
gobject.PARAM_READWRITE),
'stroke-color': (object, None, None,
gobject.PARAM_READWRITE),
'progress-color': (object, None, None,
gobject.PARAM_READWRITE),
'percent' : (object, None, None,
gobject.PARAM_READWRITE),
}
def __init__(self, **kwargs):
self._stroke_color = 0xFFFFFFFF
self._fill_color = 0xFFFFFFFF
self._progress_color = 0x000000FF
self._percent = 0
self._radius = 8
def __init__(self, **kwargs):
self._stroke_color = 0xFFFFFFFF
self._fill_color = 0xFFFFFFFF
self._progress_color = 0x000000FF
self._percent = 0
self._radius = 8
hippo.CanvasBox.__init__(self, **kwargs)
hippo.CanvasBox.__init__(self, **kwargs)
def do_set_property(self, pspec, value):
if pspec.name == 'fill-color':
self._fill_color = value
self.emit_paint_needed(0, 0, -1, -1)
elif pspec.name == 'stroke-color':
self._stroke_color = value
self.emit_paint_needed(0, 0, -1, -1)
elif pspec.name == 'progress-color':
self._progress_color = value
self.emit_paint_needed(0, 0, -1, -1)
elif pspec.name == 'percent':
self._percent = value
self.emit_paint_needed(0, 0, -1, -1)
def do_set_property(self, pspec, value):
if pspec.name == 'fill-color':
self._fill_color = value
self.emit_paint_needed(0, 0, -1, -1)
elif pspec.name == 'stroke-color':
self._stroke_color = value
self.emit_paint_needed(0, 0, -1, -1)
elif pspec.name == 'progress-color':
self._progress_color = value
self.emit_paint_needed(0, 0, -1, -1)
elif pspec.name == 'percent':
self._percent = value
self.emit_paint_needed(0, 0, -1, -1)
def do_get_property(self, pspec):
if pspec.name == 'fill-color':
return self._fill_color
elif pspec.name == 'stroke-color':
return self._stroke_color
elif pspec.name == 'progress-color':
return self._progress_color
elif pspec.name == 'percent':
return self._percent
def do_get_property(self, pspec):
if pspec.name == 'fill-color':
return self._fill_color
elif pspec.name == 'stroke-color':
return self._stroke_color
elif pspec.name == 'progress-color':
return self._progress_color
elif pspec.name == 'percent':
return self._percent
def _int_to_rgb(self, int_color):
red = (int_color >> 24) & 0x000000FF
green = (int_color >> 16) & 0x000000FF
blue = (int_color >> 8) & 0x000000FF
alpha = int_color & 0x000000FF
return (red / 255.0, green / 255.0, blue / 255.0)
def _int_to_rgb(self, int_color):
red = (int_color >> 24) & 0x000000FF
green = (int_color >> 16) & 0x000000FF
blue = (int_color >> 8) & 0x000000FF
alpha = int_color & 0x000000FF
return (red / 255.0, green / 255.0, blue / 255.0)
def do_paint_below_children(self, cr, damaged_box):
[width, height] = self.get_allocation()
def do_paint_below_children(self, cr, damaged_box):
[width, height] = self.get_allocation()
line_width = 3.0
x = line_width
y = line_width
width -= line_width * 2
height -= line_width * 2
line_width = 3.0
x = line_width
y = line_width
width -= line_width * 2
height -= line_width * 2
self._paint_ellipse(cr, x, y, width, height, self._fill_color)
self._paint_ellipse(cr, x, y, width, height, self._fill_color)
color = self._int_to_rgb(self._stroke_color)
cr.set_source_rgb(*color)
cr.set_line_width(line_width)
cr.stroke();
color = self._int_to_rgb(self._stroke_color)
cr.set_source_rgb(*color)
cr.set_line_width(line_width)
cr.stroke();
self._paint_progress_bar(cr, x, y, width, height, line_width)
self._paint_progress_bar(cr, x, y, width, height, line_width)
def _paint_progress_bar(self, cr, x, y, width, height, line_width):
prog_x = x + line_width
prog_y = y + line_width
prog_width = (width - (line_width * 2)) * (self._percent / 100.0)
prog_height = (height - (line_width * 2))
def _paint_progress_bar(self, cr, x, y, width, height, line_width):
prog_x = x + line_width
prog_y = y + line_width
prog_width = (width - (line_width * 2)) * (self._percent / 100.0)
prog_height = (height - (line_width * 2))
self._paint_ellipse(cr, prog_x, prog_y, width, height, self._progress_color)
self._paint_ellipse(cr, prog_x, prog_y, width, height, self._progress_color)
def _paint_ellipse(self, cr, x, y, width, height, fill_color):
cr.move_to(x + self._radius, y)
cr.arc(x + width - self._radius,
y + self._radius,
self._radius,
math.pi * 1.5,
math.pi * 2)
cr.arc(x + width - self._radius,
x + height - self._radius,
self._radius,
0,
math.pi * 0.5)
cr.arc(x + self._radius,
y + height - self._radius,
self._radius,
math.pi * 0.5,
math.pi)
cr.arc(x + self._radius,
y + self._radius,
self._radius,
math.pi,
math.pi * 1.5);
def _paint_ellipse(self, cr, x, y, width, height, fill_color):
cr.move_to(x + self._radius, y)
cr.arc(x + width - self._radius,
y + self._radius,
self._radius,
math.pi * 1.5,
math.pi * 2)
cr.arc(x + width - self._radius,
x + height - self._radius,
self._radius,
0,
math.pi * 0.5)
cr.arc(x + self._radius,
y + height - self._radius,
self._radius,
math.pi * 0.5,
math.pi)
cr.arc(x + self._radius,
y + self._radius,
self._radius,
math.pi,
math.pi * 1.5);
color = self._int_to_rgb(fill_color)
cr.set_source_rgb(*color)
cr.fill_preserve();
color = self._int_to_rgb(fill_color)
cr.set_source_rgb(*color)
cr.fill_preserve();
+42 -42
View File
@@ -22,56 +22,56 @@ import gtk
import hippo
class Bubble(hippo.CanvasBox, hippo.CanvasItem):
__gtype_name__ = 'SugarBubble'
__gtype_name__ = 'SugarBubble'
__gproperties__ = {
'color' : (object, None, None,
gobject.PARAM_READWRITE),
}
__gproperties__ = {
'color' : (object, None, None,
gobject.PARAM_READWRITE),
}
def __init__(self, **kwargs):
self._color = None
self._radius = 8
def __init__(self, **kwargs):
self._color = None
self._radius = 8
hippo.CanvasBox.__init__(self, **kwargs)
hippo.CanvasBox.__init__(self, **kwargs)
def do_set_property(self, pspec, value):
if pspec.name == 'color':
self._color = value
self.emit_paint_needed(0, 0, -1, -1)
def do_set_property(self, pspec, value):
if pspec.name == 'color':
self._color = value
self.emit_paint_needed(0, 0, -1, -1)
def do_get_property(self, pspec):
if pspec.name == 'color':
return self._color
def do_get_property(self, pspec):
if pspec.name == 'color':
return self._color
def _string_to_rgb(self, color_string):
col = gtk.gdk.color_parse(color_string)
return (col.red / 65535.0, col.green / 65535.0, col.blue / 65535.0)
def _string_to_rgb(self, color_string):
col = gtk.gdk.color_parse(color_string)
return (col.red / 65535.0, col.green / 65535.0, col.blue / 65535.0)
def do_paint_below_children(self, cr, damaged_box):
[width, height] = self.get_allocation()
def do_paint_below_children(self, cr, damaged_box):
[width, height] = self.get_allocation()
line_width = 3.0
x = line_width
y = line_width
width -= line_width * 2
height -= line_width * 2
line_width = 3.0
x = line_width
y = line_width
width -= line_width * 2
height -= line_width * 2
cr.move_to(x + self._radius, y);
cr.arc(x + width - self._radius, y + self._radius,
self._radius, math.pi * 1.5, math.pi * 2);
cr.arc(x + width - self._radius, x + height - self._radius,
self._radius, 0, math.pi * 0.5);
cr.arc(x + self._radius, y + height - self._radius,
self._radius, math.pi * 0.5, math.pi);
cr.arc(x + self._radius, y + self._radius, self._radius,
math.pi, math.pi * 1.5);
cr.move_to(x + self._radius, y);
cr.arc(x + width - self._radius, y + self._radius,
self._radius, math.pi * 1.5, math.pi * 2);
cr.arc(x + width - self._radius, x + height - self._radius,
self._radius, 0, math.pi * 0.5);
cr.arc(x + self._radius, y + height - self._radius,
self._radius, math.pi * 0.5, math.pi);
cr.arc(x + self._radius, y + self._radius, self._radius,
math.pi, math.pi * 1.5);
color = self._string_to_rgb(self._color.get_fill_color())
cr.set_source_rgb(*color)
cr.fill_preserve();
color = self._string_to_rgb(self._color.get_fill_color())
cr.set_source_rgb(*color)
cr.fill_preserve();
color = self._string_to_rgb(self._color.get_stroke_color())
cr.set_source_rgb(*color)
cr.set_line_width(line_width)
cr.stroke();
color = self._string_to_rgb(self._color.get_stroke_color())
cr.set_source_rgb(*color)
cr.set_line_width(line_width)
cr.stroke();
+101 -101
View File
@@ -26,133 +26,133 @@ import cairo
from sugar.graphics.iconcolor import IconColor
class _IconCache:
def __init__(self):
self._icons = {}
self._theme = gtk.icon_theme_get_default()
def __init__(self):
self._icons = {}
self._theme = gtk.icon_theme_get_default()
def _read_icon(self, filename, color):
icon_file = open(filename, 'r')
def _read_icon(self, filename, color):
icon_file = open(filename, 'r')
if color == None:
return rsvg.Handle(file=filename)
else:
data = icon_file.read()
icon_file.close()
if color == None:
return rsvg.Handle(file=filename)
else:
data = icon_file.read()
icon_file.close()
fill = color.get_fill_color()
stroke = color.get_stroke_color()
entity = '<!ENTITY fill_color "%s">' % fill
data = re.sub('<!ENTITY fill_color .*>', entity, data)
fill = color.get_fill_color()
stroke = color.get_stroke_color()
entity = '<!ENTITY fill_color "%s">' % fill
data = re.sub('<!ENTITY fill_color .*>', entity, data)
entity = '<!ENTITY stroke_color "%s">' % stroke
data = re.sub('<!ENTITY stroke_color .*>', entity, data)
entity = '<!ENTITY stroke_color "%s">' % stroke
data = re.sub('<!ENTITY stroke_color .*>', entity, data)
return rsvg.Handle(data=data)
return rsvg.Handle(data=data)
def get_handle(self, name, color, size):
info = self._theme.lookup_icon(name, int(size), 0)
def get_handle(self, name, color, size):
info = self._theme.lookup_icon(name, int(size), 0)
if color:
key = (info.get_filename(), color.to_string())
else:
key = info.get_filename()
if color:
key = (info.get_filename(), color.to_string())
else:
key = info.get_filename()
if self._icons.has_key(key):
icon = self._icons[key]
else:
icon = self._read_icon(info.get_filename(), color)
self._icons[key] = icon
return icon
if self._icons.has_key(key):
icon = self._icons[key]
else:
icon = self._read_icon(info.get_filename(), color)
self._icons[key] = icon
return icon
class CanvasIcon(hippo.CanvasBox, hippo.CanvasItem):
__gtype_name__ = 'CanvasIcon'
__gtype_name__ = 'CanvasIcon'
__gproperties__ = {
'icon-name': (str, None, None, None,
gobject.PARAM_READWRITE),
'color' : (object, None, None,
gobject.PARAM_READWRITE),
'size' : (int, None, None,
0, 1024, 24,
gobject.PARAM_READWRITE)
}
__gproperties__ = {
'icon-name': (str, None, None, None,
gobject.PARAM_READWRITE),
'color' : (object, None, None,
gobject.PARAM_READWRITE),
'size' : (int, None, None,
0, 1024, 24,
gobject.PARAM_READWRITE)
}
_cache = _IconCache()
_cache = _IconCache()
def __init__(self, **kwargs):
self._size = 24
self._color = None
self._icon_name = None
def __init__(self, **kwargs):
self._size = 24
self._color = None
self._icon_name = None
hippo.CanvasBox.__init__(self, **kwargs)
hippo.CanvasBox.__init__(self, **kwargs)
self._buffer = None
self._buffer = None
self.connect('button-press-event', self._button_press_event_cb)
self.connect('button-press-event', self._button_press_event_cb)
def do_set_property(self, pspec, value):
if pspec.name == 'icon-name':
self._icon_name = value
self._buffer = None
self.emit_paint_needed(0, 0, -1, -1)
elif pspec.name == 'color':
self._buffer = None
self._color = value
self.emit_paint_needed(0, 0, -1, -1)
elif pspec.name == 'size':
self._buffer = None
self._size = value
self.emit_request_changed()
def do_set_property(self, pspec, value):
if pspec.name == 'icon-name':
self._icon_name = value
self._buffer = None
self.emit_paint_needed(0, 0, -1, -1)
elif pspec.name == 'color':
self._buffer = None
self._color = value
self.emit_paint_needed(0, 0, -1, -1)
elif pspec.name == 'size':
self._buffer = None
self._size = value
self.emit_request_changed()
def do_get_property(self, pspec):
if pspec.name == 'size':
return self._size
elif pspec.name == 'icon-name':
return self._icon_name
elif pspec.name == 'color':
return self._color
def do_get_property(self, pspec):
if pspec.name == 'size':
return self._size
elif pspec.name == 'icon-name':
return self._icon_name
elif pspec.name == 'color':
return self._color
def _get_buffer(self, cr, handle, size):
if self._buffer == None:
target = cr.get_target()
surface = target.create_similar(cairo.CONTENT_COLOR_ALPHA,
int(size) + 1, int(size) + 1)
def _get_buffer(self, cr, handle, size):
if self._buffer == None:
target = cr.get_target()
surface = target.create_similar(cairo.CONTENT_COLOR_ALPHA,
int(size) + 1, int(size) + 1)
dimensions = handle.get_dimension_data()
scale = float(size) / float(dimensions[0])
dimensions = handle.get_dimension_data()
scale = float(size) / float(dimensions[0])
ctx = cairo.Context(surface)
ctx.scale(scale, scale)
handle.render_cairo(ctx)
del ctx
ctx = cairo.Context(surface)
ctx.scale(scale, scale)
handle.render_cairo(ctx)
del ctx
self._buffer = surface
self._buffer_scale = scale
self._buffer = surface
self._buffer_scale = scale
return self._buffer
return self._buffer
def do_paint_below_children(self, cr, damaged_box):
icon_name = self._icon_name
if icon_name == None:
icon_name = 'stock-missing'
def do_paint_below_children(self, cr, damaged_box):
icon_name = self._icon_name
if icon_name == None:
icon_name = 'stock-missing'
handle = CanvasIcon._cache.get_handle(
icon_name, self._color, self._size)
buf = self._get_buffer(cr, handle, self._size)
handle = CanvasIcon._cache.get_handle(
icon_name, self._color, self._size)
buf = self._get_buffer(cr, handle, self._size)
[width, height] = self.get_allocation()
x = (width - self._size) / 2
y = (height - self._size) / 2
cr.set_source_surface(buf, x, y)
cr.paint()
[width, height] = self.get_allocation()
x = (width - self._size) / 2
y = (height - self._size) / 2
cr.set_source_surface(buf, x, y)
cr.paint()
def do_get_width_request(self):
return self._size
def do_get_width_request(self):
return self._size
def do_get_height_request(self, for_width):
return self._size
def do_get_height_request(self, for_width):
return self._size
def _button_press_event_cb(self, item, event):
item.emit_activated()
def _button_press_event_cb(self, item, event):
item.emit_activated()
+12 -12
View File
@@ -21,19 +21,19 @@ COLS = 16
ROWS = 12
class Grid(object):
def __init__(self):
self._factor = gtk.gdk.screen_width() / COLS
def __init__(self):
self._factor = gtk.gdk.screen_width() / COLS
def point(self, grid_x, grid_y):
return [grid_x * self._factor, grid_y * self._factor]
def point(self, grid_x, grid_y):
return [grid_x * self._factor, grid_y * self._factor]
def rectangle(self, grid_x, grid_y, grid_w, grid_h):
return [grid_x * self._factor, grid_y * self._factor,
grid_w * self._factor, grid_h * self._factor]
def rectangle(self, grid_x, grid_y, grid_w, grid_h):
return [grid_x * self._factor, grid_y * self._factor,
grid_w * self._factor, grid_h * self._factor]
def dimension(self, grid_dimension):
return grid_dimension * self._factor
def dimension(self, grid_dimension):
return grid_dimension * self._factor
def fit_point(self, x, y):
return [int(x / self._factor), int(y / self._factor)]
def fit_point(self, x, y):
return [int(x / self._factor), int(y / self._factor)]
+20 -20
View File
@@ -20,32 +20,32 @@ import random
from sugar.graphics.colors import colors
def _parse_string(color_string):
if color_string == 'white':
return ['#ffffff', '#414141']
if color_string == 'white':
return ['#ffffff', '#414141']
splitted = color_string.split(',')
if len(splitted) == 2:
return [splitted[0], splitted[1]]
else:
return None
splitted = color_string.split(',')
if len(splitted) == 2:
return [splitted[0], splitted[1]]
else:
return None
def is_valid(color_string):
return (_parse_string(color_string) != None)
return (_parse_string(color_string) != None)
class IconColor:
def __init__(self, color_string=None):
if color_string == None or not is_valid(color_string):
n = int(random.random() * (len(colors) - 1))
[self._stroke, self._fill] = colors[n]
else:
[self._stroke, self._fill] = _parse_string(color_string)
def __init__(self, color_string=None):
if color_string == None or not is_valid(color_string):
n = int(random.random() * (len(colors) - 1))
[self._stroke, self._fill] = colors[n]
else:
[self._stroke, self._fill] = _parse_string(color_string)
def get_stroke_color(self):
return self._stroke
def get_stroke_color(self):
return self._stroke
def get_fill_color(self):
return self._fill
def get_fill_color(self):
return self._fill
def to_string(self):
return '%s,%s' % (self._stroke, self._fill)
def to_string(self):
return '%s,%s' % (self._stroke, self._fill)
+62 -62
View File
@@ -23,85 +23,85 @@ from sugar.graphics.canvasicon import CanvasIcon
from sugar.graphics import style
class Menu(gtk.Window):
__gsignals__ = {
'action': (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE, ([int])),
}
__gsignals__ = {
'action': (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE, ([int])),
}
def __init__(self, title=None, content_box=None):
gtk.Window.__init__(self, gtk.WINDOW_POPUP)
def __init__(self, title=None, content_box=None):
gtk.Window.__init__(self, gtk.WINDOW_POPUP)
canvas = hippo.Canvas()
self.add(canvas)
canvas.show()
canvas = hippo.Canvas()
self.add(canvas)
canvas.show()
self._root = hippo.CanvasBox()
style.apply_stylesheet(self._root, 'menu')
canvas.set_root(self._root)
self._root = hippo.CanvasBox()
style.apply_stylesheet(self._root, 'menu')
canvas.set_root(self._root)
if title:
self._title_item = hippo.CanvasText(text=title)
style.apply_stylesheet(self._title_item, 'menu.Title')
self._root.append(self._title_item)
else:
self._title_item = None
if title:
self._title_item = hippo.CanvasText(text=title)
style.apply_stylesheet(self._title_item, 'menu.Title')
self._root.append(self._title_item)
else:
self._title_item = None
if content_box:
separator = self._create_separator()
self._root.append(separator)
self._root.append(content_box)
if content_box:
separator = self._create_separator()
self._root.append(separator)
self._root.append(content_box)
self._action_box = None
self._item_box = None
self._action_box = None
self._item_box = None
def _create_separator(self):
separator = hippo.CanvasBox()
style.apply_stylesheet(separator, 'menu.Separator')
return separator
def _create_separator(self):
separator = hippo.CanvasBox()
style.apply_stylesheet(separator, 'menu.Separator')
return separator
def _create_item_box(self):
if self._title_item:
separator = self._create_separator()
self._root.append(separator)
def _create_item_box(self):
if self._title_item:
separator = self._create_separator()
self._root.append(separator)
self._item_box = hippo.CanvasBox(
orientation=hippo.ORIENTATION_VERTICAL)
self._root.append(self._item_box)
self._item_box = hippo.CanvasBox(
orientation=hippo.ORIENTATION_VERTICAL)
self._root.append(self._item_box)
def _create_action_box(self):
separator = self._create_separator()
self._root.append(separator)
def _create_action_box(self):
separator = self._create_separator()
self._root.append(separator)
self._action_box = hippo.CanvasBox(
orientation=hippo.ORIENTATION_HORIZONTAL)
self._root.append(self._action_box)
self._action_box = hippo.CanvasBox(
orientation=hippo.ORIENTATION_HORIZONTAL)
self._root.append(self._action_box)
def add_item(self, label, action_id):
if not self._item_box:
self._create_item_box()
def add_item(self, label, action_id):
if not self._item_box:
self._create_item_box()
text = hippo.CanvasText(text=label)
style.apply_stylesheet(text, 'menu.Item')
text = hippo.CanvasText(text=label)
style.apply_stylesheet(text, 'menu.Item')
# FIXME need a way to make hippo items activable in python
text.connect('button-press-event', self._item_clicked_cb, action_id)
#text.connect('activated', self._action_clicked_cb, action_id)
# FIXME need a way to make hippo items activable in python
text.connect('button-press-event', self._item_clicked_cb, action_id)
#text.connect('activated', self._action_clicked_cb, action_id)
self._item_box.append(text)
self._item_box.append(text)
def add_action(self, icon, action_id):
if not self._action_box:
self._create_action_box()
def add_action(self, icon, action_id):
if not self._action_box:
self._create_action_box()
style.apply_stylesheet(icon, 'menu.ActionIcon')
icon.connect('activated', self._action_clicked_cb, action_id)
self._action_box.append(icon)
style.apply_stylesheet(icon, 'menu.ActionIcon')
icon.connect('activated', self._action_clicked_cb, action_id)
self._action_box.append(icon)
def remove_action(self, icon):
self._action_box.remove(icon)
def remove_action(self, icon):
self._action_box.remove(icon)
def _item_clicked_cb(self, icon, event, action):
self.emit('action', action)
def _item_clicked_cb(self, icon, event, action):
self.emit('action', action)
def _action_clicked_cb(self, icon, action):
self.emit('action', action)
def _action_clicked_cb(self, icon, action):
self.emit('action', action)
+41 -41
View File
@@ -23,58 +23,58 @@ from sugar.graphics.canvasicon import CanvasIcon
from sugar.graphics.timeline import Timeline
class MenuIcon(CanvasIcon):
def __init__(self, menu_shell, **kwargs):
CanvasIcon.__init__(self, **kwargs)
def __init__(self, menu_shell, **kwargs):
CanvasIcon.__init__(self, **kwargs)
self._menu_shell = menu_shell
self._menu = None
self._hover_menu = False
self._menu_shell = menu_shell
self._menu = None
self._hover_menu = False
self._timeline = Timeline(self)
self._timeline.add_tag('popup', 6, 6)
self._timeline.add_tag('before_popdown', 7, 7)
self._timeline.add_tag('popdown', 8, 8)
self._timeline = Timeline(self)
self._timeline.add_tag('popup', 6, 6)
self._timeline.add_tag('before_popdown', 7, 7)
self._timeline.add_tag('popdown', 8, 8)
self.connect('motion-notify-event', self._motion_notify_event_cb)
self.connect('motion-notify-event', self._motion_notify_event_cb)
def do_popup(self, current, n_frames):
if self._menu:
return
def do_popup(self, current, n_frames):
if self._menu:
return
self._menu = self.create_menu()
self._menu = self.create_menu()
self._menu.connect('enter-notify-event',
self._menu_enter_notify_event_cb)
self._menu.connect('leave-notify-event',
self._menu_leave_notify_event_cb)
self._menu.connect('enter-notify-event',
self._menu_enter_notify_event_cb)
self._menu.connect('leave-notify-event',
self._menu_leave_notify_event_cb)
[x, y] = self._menu_shell.get_position(self._menu, self)
[x, y] = self._menu_shell.get_position(self._menu, self)
self._menu.move(x, y)
self._menu.show()
self._menu.move(x, y)
self._menu.show()
self._menu_shell.set_active(self)
self._menu_shell.set_active(self)
def do_popdown(self, current, frame):
if self._menu:
self._menu.destroy()
self._menu = None
self._menu_shell.set_active(None)
def do_popdown(self, current, frame):
if self._menu:
self._menu.destroy()
self._menu = None
self._menu_shell.set_active(None)
def popdown(self):
self._timeline.play('popdown', 'popdown')
def popdown(self):
self._timeline.play('popdown', 'popdown')
def _motion_notify_event_cb(self, item, event):
if event.detail == hippo.MOTION_DETAIL_ENTER:
self._timeline.play(None, 'popup')
elif event.detail == hippo.MOTION_DETAIL_LEAVE:
if not self._hover_menu:
self._timeline.play('before_popdown', 'popdown')
def _motion_notify_event_cb(self, item, event):
if event.detail == hippo.MOTION_DETAIL_ENTER:
self._timeline.play(None, 'popup')
elif event.detail == hippo.MOTION_DETAIL_LEAVE:
if not self._hover_menu:
self._timeline.play('before_popdown', 'popdown')
def _menu_enter_notify_event_cb(self, widget, event):
self._hover_menu = True
self._timeline.play('popup', 'popup')
def _menu_enter_notify_event_cb(self, widget, event):
self._hover_menu = True
self._timeline.play('popup', 'popup')
def _menu_leave_notify_event_cb(self, widget, event):
self._hover_menu = False
self._timeline.play('popdown', 'popdown')
def _menu_leave_notify_event_cb(self, widget, event):
self._hover_menu = False
self._timeline.play('popdown', 'popdown')
+63 -63
View File
@@ -19,83 +19,83 @@ import gobject
import gtk
class MenuShell(gobject.GObject):
__gsignals__ = {
'activated': (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE, ([])),
'deactivated': (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE, ([])),
}
__gsignals__ = {
'activated': (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE, ([])),
'deactivated': (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE, ([])),
}
AUTO = 0
LEFT = 1
RIGHT = 2
TOP = 3
BOTTOM = 4
AUTO = 0
LEFT = 1
RIGHT = 2
TOP = 3
BOTTOM = 4
def __init__(self, parent_canvas):
gobject.GObject.__init__(self)
def __init__(self, parent_canvas):
gobject.GObject.__init__(self)
self._parent_canvas = parent_canvas
self._menu_controller = None
self._position = MenuShell.AUTO
self._parent_canvas = parent_canvas
self._menu_controller = None
self._position = MenuShell.AUTO
def set_position(self, position):
self._position = position
def set_position(self, position):
self._position = position
def is_active(self):
return (self._menu_controller != None)
def is_active(self):
return (self._menu_controller != None)
def set_active(self, controller):
if controller == None:
self.emit('deactivated')
else:
self.emit('activated')
def set_active(self, controller):
if controller == None:
self.emit('deactivated')
else:
self.emit('activated')
if self._menu_controller:
self._menu_controller.popdown()
self._menu_controller = controller
if self._menu_controller:
self._menu_controller.popdown()
self._menu_controller = controller
def _get_item_rect(self, item):
[x, y] = item.get_context().translate_to_widget(item)
def _get_item_rect(self, item):
[x, y] = item.get_context().translate_to_widget(item)
[origin_x, origin_y] = self._parent_canvas.window.get_origin()
x += origin_x
y += origin_y
[origin_x, origin_y] = self._parent_canvas.window.get_origin()
x += origin_x
y += origin_y
[w, h] = item.get_allocation()
[w, h] = item.get_allocation()
return [x, y, w, h]
return [x, y, w, h]
def get_position(self, menu, item):
[item_x, item_y, item_w, item_h] = self._get_item_rect(item)
[menu_w, menu_h] = menu.size_request()
def get_position(self, menu, item):
[item_x, item_y, item_w, item_h] = self._get_item_rect(item)
[menu_w, menu_h] = menu.size_request()
left_x = item_x - menu_w
left_y = item_y
right_x = item_x + item_w
right_y = item_y
top_x = item_x
top_y = item_y - menu_h
bottom_x = item_x
bottom_y = item_y + item_h
left_x = item_x - menu_w
left_y = item_y
right_x = item_x + item_w
right_y = item_y
top_x = item_x
top_y = item_y - menu_h
bottom_x = item_x
bottom_y = item_y + item_h
if self._position == MenuShell.LEFT:
[x, y] = [left_x, left_y]
elif self._position == MenuShell.RIGHT:
[x, y] = [right_x, right_y]
elif self._position == MenuShell.TOP:
[x, y] = [top_x, top_y]
elif self._position == MenuShell.BOTTOM:
[x, y] = [bottom_x, bottom_y]
elif self._position == MenuShell.AUTO:
[x, y] = [right_x, right_y]
if x + menu_w > gtk.gdk.screen_width():
[x, y] = [left_x, left_y]
if self._position == MenuShell.LEFT:
[x, y] = [left_x, left_y]
elif self._position == MenuShell.RIGHT:
[x, y] = [right_x, right_y]
elif self._position == MenuShell.TOP:
[x, y] = [top_x, top_y]
elif self._position == MenuShell.BOTTOM:
[x, y] = [bottom_x, bottom_y]
elif self._position == MenuShell.AUTO:
[x, y] = [right_x, right_y]
if x + menu_w > gtk.gdk.screen_width():
[x, y] = [left_x, left_y]
x = min(x, gtk.gdk.screen_width() - menu_w)
x = max(0, x)
x = min(x, gtk.gdk.screen_width() - menu_w)
x = max(0, x)
y = min(y, gtk.gdk.screen_height() - menu_h)
y = max(0, y)
y = min(y, gtk.gdk.screen_height() - menu_h)
y = max(0, y)
return [x, y]
return [x, y]
+50 -50
View File
@@ -25,72 +25,72 @@ _CHILDREN_FACTOR = 1
_FLAKE_DISTANCE = 6
class SnowflakeBox(hippo.CanvasBox, hippo.CanvasItem):
__gtype_name__ = 'SugarSnowflakeBox'
def __init__(self, **kwargs):
hippo.CanvasBox.__init__(self, **kwargs)
self._root = None
__gtype_name__ = 'SugarSnowflakeBox'
def __init__(self, **kwargs):
hippo.CanvasBox.__init__(self, **kwargs)
self._root = None
def set_root(self, icon):
self._root = icon
def set_root(self, icon):
self._root = icon
def _get_center(self):
[width, height] = self.get_allocation()
return [width / 2, height / 2]
def _get_center(self):
[width, height] = self.get_allocation()
return [width / 2, height / 2]
def _get_radius(self):
return _BASE_RADIUS + _CHILDREN_FACTOR * self._get_n_children()
def _get_radius(self):
return _BASE_RADIUS + _CHILDREN_FACTOR * self._get_n_children()
def _layout_root(self):
[width, height] = self._root.get_allocation()
[cx, cy] = self._get_center()
def _layout_root(self):
[width, height] = self._root.get_allocation()
[cx, cy] = self._get_center()
x = cx - (width / 2)
y = cy - (height / 2)
x = cx - (width / 2)
y = cy - (height / 2)
self.move(self._root, int(x), int(y))
self.move(self._root, int(x), int(y))
def _get_n_children(self):
return len(self.get_children()) - 1
def _get_n_children(self):
return len(self.get_children()) - 1
def _layout_child(self, child, index):
r = self._get_radius()
if (self._get_n_children() > 10):
r += _FLAKE_DISTANCE * (index % 3)
def _layout_child(self, child, index):
r = self._get_radius()
if (self._get_n_children() > 10):
r += _FLAKE_DISTANCE * (index % 3)
angle = 2 * math.pi * index / self._get_n_children()
angle = 2 * math.pi * index / self._get_n_children()
[width, height] = child.get_allocation()
[cx, cy] = self._get_center()
[width, height] = child.get_allocation()
[cx, cy] = self._get_center()
x = cx + math.cos(angle) * r - (width / 2)
y = cy + math.sin(angle) * r - (height / 2)
x = cx + math.cos(angle) * r - (width / 2)
y = cy + math.sin(angle) * r - (height / 2)
self.move(child, int(x), int(y))
self.move(child, int(x), int(y))
def do_get_width_request(self):
hippo.CanvasBox.do_get_width_request(self)
def do_get_width_request(self):
hippo.CanvasBox.do_get_width_request(self)
max_child_size = 0
for child in self.get_children():
width = child.get_width_request()
height = child.get_height_request(width)
max_child_size = max (max_child_size, width)
max_child_size = max (max_child_size, height)
max_child_size = 0
for child in self.get_children():
width = child.get_width_request()
height = child.get_height_request(width)
max_child_size = max (max_child_size, width)
max_child_size = max (max_child_size, height)
return self._get_radius() * 2 + \
max_child_size + _FLAKE_DISTANCE * 2
return self._get_radius() * 2 + \
max_child_size + _FLAKE_DISTANCE * 2
def do_get_height_request(self, width):
hippo.CanvasBox.do_get_height_request(self, width)
return width
def do_get_height_request(self, width):
hippo.CanvasBox.do_get_height_request(self, width)
return width
def do_allocate(self, width, height):
hippo.CanvasBox.do_allocate(self, width, height)
def do_allocate(self, width, height):
hippo.CanvasBox.do_allocate(self, width, height)
self._layout_root()
self._layout_root()
index = 0
for child in self.get_children():
if child != self._root:
self._layout_child(child, index)
index += 1
index = 0
for child in self.get_children():
if child != self._root:
self._layout_child(child, index)
index += 1
+76 -76
View File
@@ -25,108 +25,108 @@ _DISTANCE_THRESHOLD = 10.0
_FORCE_CONSTANT = 0.1
class SpreadBox(hippo.CanvasBox, hippo.CanvasItem):
__gtype_name__ = 'SugarSpreadBox'
__gtype_name__ = 'SugarSpreadBox'
def __init__(self, **kwargs):
hippo.CanvasBox.__init__(self, **kwargs)
def __init__(self, **kwargs):
hippo.CanvasBox.__init__(self, **kwargs)
self._items_to_position = []
self._stable = False
self._items_to_position = []
self._stable = False
def add_item(self, item):
self._items_to_position.append(item)
self.append(item, hippo.PACK_FIXED)
def add_item(self, item):
self._items_to_position.append(item)
self.append(item, hippo.PACK_FIXED)
def remove_item(self, item):
if self._items_to_position.count(item) > 0:
self._items_to_position.remove(item)
self.remove(item)
def remove_item(self, item):
if self._items_to_position.count(item) > 0:
self._items_to_position.remove(item)
self.remove(item)
def _get_item_radius(self, item):
[width, height] = item.get_request()
return math.sqrt(width ** 2 + height ** 2) / 2
def _get_item_radius(self, item):
[width, height] = item.get_request()
return math.sqrt(width ** 2 + height ** 2) / 2
def _get_item_center(self, item):
[width, height] = item.get_request()
[x, y] = self.get_position(item)
def _get_item_center(self, item):
[width, height] = item.get_request()
[x, y] = self.get_position(item)
c_x = int(x + float(width) / 2.0)
c_y = int(y + float(height) / 2.0)
c_x = int(x + float(width) / 2.0)
c_y = int(y + float(height) / 2.0)
return [c_x, c_y]
return [c_x, c_y]
def _get_repulsion(self, icon1, icon2):
[c1_x, c1_y] = self._get_item_center(icon1)
[c2_x, c2_y] = self._get_item_center(icon2)
def _get_repulsion(self, icon1, icon2):
[c1_x, c1_y] = self._get_item_center(icon1)
[c2_x, c2_y] = self._get_item_center(icon2)
a = c2_x - c1_x
b = c2_y - c1_y
a = c2_x - c1_x
b = c2_y - c1_y
r1 = self._get_item_radius(icon1)
r2 = self._get_item_radius(icon2)
distance = math.sqrt(a ** 2 + b ** 2) - r1 - r2
r1 = self._get_item_radius(icon1)
r2 = self._get_item_radius(icon2)
distance = math.sqrt(a ** 2 + b ** 2) - r1 - r2
if distance < _DISTANCE_THRESHOLD:
f_x = int(math.ceil(-_FORCE_CONSTANT * float(a)))
f_y = int(math.ceil(-_FORCE_CONSTANT * float(b)))
else:
f_x = 0
f_y = 0
if distance < _DISTANCE_THRESHOLD:
f_x = int(math.ceil(-_FORCE_CONSTANT * float(a)))
f_y = int(math.ceil(-_FORCE_CONSTANT * float(b)))
else:
f_x = 0
f_y = 0
return [f_x, f_y]
return [f_x, f_y]
def _clamp_position(self, icon, x, y):
x = max(0, x)
y = max(0, y)
def _clamp_position(self, icon, x, y):
x = max(0, x)
y = max(0, y)
[item_w, item_h] = icon.get_request()
[box_w, box_h] = self.get_allocation()
[item_w, item_h] = icon.get_request()
[box_w, box_h] = self.get_allocation()
x = min(box_w - item_w, x)
y = min(box_h - item_h, y)
x = min(box_w - item_w, x)
y = min(box_h - item_h, y)
return [x, y]
return [x, y]
def _spread_icons(self):
self._stable = True
def _spread_icons(self):
self._stable = True
for icon1 in self.get_children():
vx = 0
vy = 0
for icon1 in self.get_children():
vx = 0
vy = 0
for icon2 in self.get_children():
if icon1 != icon2:
[f_x, f_y] = self._get_repulsion(icon1, icon2)
if f_x != 0 or f_y != 0:
self._stable = False
vx += f_x
vy += f_y
for icon2 in self.get_children():
if icon1 != icon2:
[f_x, f_y] = self._get_repulsion(icon1, icon2)
if f_x != 0 or f_y != 0:
self._stable = False
vx += f_x
vy += f_y
if vx != 0 or vy != 0:
[x, y] = self.get_position(icon1)
new_x = x + vx
new_y = y + vy
if vx != 0 or vy != 0:
[x, y] = self.get_position(icon1)
new_x = x + vx
new_y = y + vy
[new_x, new_y] = self._clamp_position(icon1, new_x, new_y)
[new_x, new_y] = self._clamp_position(icon1, new_x, new_y)
self.move(icon1, new_x, new_y)
self.move(icon1, new_x, new_y)
def do_allocate(self, width, height):
hippo.CanvasBox.do_allocate(self, width, height)
def do_allocate(self, width, height):
hippo.CanvasBox.do_allocate(self, width, height)
for item in self._items_to_position:
[item_w, item_h] = item.get_request()
for item in self._items_to_position:
[item_w, item_h] = item.get_request()
x = int(random.random() * width - item_w)
y = int(random.random() * height - item_h)
x = int(random.random() * width - item_w)
y = int(random.random() * height - item_h)
[x, y] = self._clamp_position(item, x, y)
self.move(item, x, y)
[x, y] = self._clamp_position(item, x, y)
self.move(item, x, y)
self._items_to_position = []
self._items_to_position = []
tries = 20
self._spread_icons()
while not self._stable and tries > 0:
self._spread_icons()
tries -= 1
tries = 20
self._spread_icons()
while not self._stable and tries > 0:
self._spread_icons()
tries -= 1
+12 -12
View File
@@ -31,21 +31,21 @@ large_icon_size = standard_icon_size * 2.0
xlarge_icon_size = standard_icon_size * 3.0
def load_stylesheet(module):
for objname in dir(module):
if not objname.startswith('_'):
obj = getattr(module, objname)
if isinstance(obj, dict):
register_stylesheet(objname.replace('_', '.'), obj)
for objname in dir(module):
if not objname.startswith('_'):
obj = getattr(module, objname)
if isinstance(obj, dict):
register_stylesheet(objname.replace('_', '.'), obj)
def register_stylesheet(name, style):
_styles[name] = style
_styles[name] = style
def apply_stylesheet(item, stylesheet_name):
if _styles.has_key(stylesheet_name):
style_sheet = _styles[stylesheet_name]
for name in style_sheet.keys():
item.set_property(name, style_sheet[name])
if _styles.has_key(stylesheet_name):
style_sheet = _styles[stylesheet_name]
for name in style_sheet.keys():
item.set_property(name, style_sheet[name])
def get_font_description(style, relative_size):
base_size = 18 * _screen_factor
return '%s %dpx' % (style, int(base_size * relative_size))
base_size = 18 * _screen_factor
return '%s %dpx' % (style, int(base_size * relative_size))
+12 -12
View File
@@ -1,31 +1,31 @@
from sugar.graphics import style
menu = {
'background_color' : 0x000000FF,
'spacing' : style.space_unit,
'padding' : style.space_unit
'background_color' : 0x000000FF,
'spacing' : style.space_unit,
'padding' : style.space_unit
}
menu_Title = {
'color' : 0xFFFFFFFF,
'font' : style.get_font_description('Bold', 1.2)
'color' : 0xFFFFFFFF,
'font' : style.get_font_description('Bold', 1.2)
}
menu_Separator = {
'background_color' : 0xFFFFFFFF,
'box_height' : style.separator_thickness
'background_color' : 0xFFFFFFFF,
'box_height' : style.separator_thickness
}
menu_ActionIcon = {
'size' : style.standard_icon_size
'size' : style.standard_icon_size
}
menu_Item = {
'color' : 0xFFFFFFFF,
'font' : style.get_font_description('Plain', 1.1)
'color' : 0xFFFFFFFF,
'font' : style.get_font_description('Plain', 1.1)
}
menu_Text = {
'color' : 0xFFFFFFFF,
'font' : style.get_font_description('Plain', 1.2)
'color' : 0xFFFFFFFF,
'font' : style.get_font_description('Plain', 1.2)
}
+75 -75
View File
@@ -18,100 +18,100 @@
import gobject
class _Tag:
def __init__(self, name, start_frame, end_frame):
self.name = name
self.start_frame = start_frame
self.end_frame = end_frame
def __init__(self, name, start_frame, end_frame):
self.name = name
self.start_frame = start_frame
self.end_frame = end_frame
class TimelineObserver:
def __init__(self, observer):
self._observer = observer
def __init__(self, observer):
self._observer = observer
def next_frame(self, tag, current_frame, n_frames):
try:
method = getattr(self._observer, 'do_' + tag)
except AttributeError:
method = None
def next_frame(self, tag, current_frame, n_frames):
try:
method = getattr(self._observer, 'do_' + tag)
except AttributeError:
method = None
if method:
method(current_frame, n_frames)
if method:
method(current_frame, n_frames)
class Timeline:
def __init__(self, observer):
self._fps = 12
self._tags = []
self._name_to_tag = {}
self._current_frame = 0
self._timeout_sid = 0
self._observer = TimelineObserver(observer)
def __init__(self, observer):
self._fps = 12
self._tags = []
self._name_to_tag = {}
self._current_frame = 0
self._timeout_sid = 0
self._observer = TimelineObserver(observer)
def add_tag(self, name, start_frame, end_frame):
tag = _Tag(name, start_frame, end_frame)
self._tags.append(tag)
self._name_to_tag[name] = tag
def add_tag(self, name, start_frame, end_frame):
tag = _Tag(name, start_frame, end_frame)
self._tags.append(tag)
self._name_to_tag[name] = tag
def remove_tag(self, name):
tag = self._tags[name]
self._tags.remove(tag)
del self._tags[name]
def remove_tag(self, name):
tag = self._tags[name]
self._tags.remove(tag)
del self._tags[name]
def _next_frame(self, tag, frame):
n_frames = tag.start_frame - tag.end_frame
self._observer.next_frame(tag.name, frame, n_frames)
def _next_frame(self, tag, frame):
n_frames = tag.start_frame - tag.end_frame
self._observer.next_frame(tag.name, frame, n_frames)
def goto(self, tag_name, end_frame=False):
self.pause()
def goto(self, tag_name, end_frame=False):
self.pause()
tag = self._name_to_tag[tag_name]
if end_frame:
self._current_frame = tag.end_frame
else:
self._current_frame = tag.start_frame
tag = self._name_to_tag[tag_name]
if end_frame:
self._current_frame = tag.end_frame
else:
self._current_frame = tag.start_frame
self._next_frame(tag, self._current_frame)
self._next_frame(tag, self._current_frame)
def on_tag(self, name):
tag = self._name_to_tag[name]
return (tag.start_frame <= self._current_frame and \
tag.end_frame >= self._current_frame)
def on_tag(self, name):
tag = self._name_to_tag[name]
return (tag.start_frame <= self._current_frame and \
tag.end_frame >= self._current_frame)
def _get_tags_for_frame(self, frame):
result = []
for tag in self._tags:
if tag.start_frame <= frame and tag.end_frame >= frame:
result.append(tag)
return result
def _get_tags_for_frame(self, frame):
result = []
for tag in self._tags:
if tag.start_frame <= frame and tag.end_frame >= frame:
result.append(tag)
return result
def _timeout_cb(self, end_frame):
for tag in self._get_tags_for_frame(self._current_frame):
cur_frame = self._current_frame - tag.start_frame
self._next_frame(tag, cur_frame)
def _timeout_cb(self, end_frame):
for tag in self._get_tags_for_frame(self._current_frame):
cur_frame = self._current_frame - tag.start_frame
self._next_frame(tag, cur_frame)
if self._current_frame < end_frame:
self._current_frame += 1
return True
else:
return False
if self._current_frame < end_frame:
self._current_frame += 1
return True
else:
return False
def play(self, start_tag=None, stop_tag=None):
self.pause()
def play(self, start_tag=None, stop_tag=None):
self.pause()
if start_tag == None:
start = 0
else:
start = self._name_to_tag[start_tag].start_frame
if start_tag == None:
start = 0
else:
start = self._name_to_tag[start_tag].start_frame
if stop_tag == None:
end = self._tags[len(self._tags) - 1].end_frame
else:
end = self._name_to_tag[stop_tag].end_frame
if stop_tag == None:
end = self._tags[len(self._tags) - 1].end_frame
else:
end = self._name_to_tag[stop_tag].end_frame
self._current_frame = start
self._current_frame = start
interval = 1000 / self._fps
self._timeout_sid = gobject.timeout_add(
interval, self._timeout_cb, end)
interval = 1000 / self._fps
self._timeout_sid = gobject.timeout_add(
interval, self._timeout_cb, end)
def pause(self):
if self._timeout_sid > 0:
gobject.source_remove(self._timeout_sid)
def pause(self):
if self._timeout_sid > 0:
gobject.source_remove(self._timeout_sid)
+55 -55
View File
@@ -29,82 +29,82 @@ STDOUT_LEVEL = 1000
STDERR_LEVEL = 2000
class LogWriter:
def __init__(self, module_id):
self._module_id = module_id
def __init__(self, module_id):
self._module_id = module_id
logs_dir = _get_logs_dir()
log_path = os.path.join(logs_dir, module_id + '.log')
self._log_file = open(log_path, 'w')
logs_dir = _get_logs_dir()
log_path = os.path.join(logs_dir, module_id + '.log')
self._log_file = open(log_path, 'w')
def write_record(self, record):
self.write(record.levelno, record.msg)
def write_record(self, record):
self.write(record.levelno, record.msg)
def write(self, level, msg):
if level == logging.ERROR:
level_txt = 'ERROR'
elif level == logging.WARNING:
level_txt = 'WARNING'
elif level == logging.DEBUG:
level_txt = 'DEBUG'
elif level == logging.INFO:
level_txt = 'INFO'
elif level == STDERR_LEVEL:
level_txt = 'STDERR'
elif level == STDOUT_LEVEL:
level_txt = 'STDOUT'
def write(self, level, msg):
if level == logging.ERROR:
level_txt = 'ERROR'
elif level == logging.WARNING:
level_txt = 'WARNING'
elif level == logging.DEBUG:
level_txt = 'DEBUG'
elif level == logging.INFO:
level_txt = 'INFO'
elif level == STDERR_LEVEL:
level_txt = 'STDERR'
elif level == STDOUT_LEVEL:
level_txt = 'STDOUT'
fmt = "%s - %s\n" % (level_txt, msg)
fmt = fmt.encode("utf8")
self._log_file.write(fmt)
self._log_file.flush()
fmt = "%s - %s\n" % (level_txt, msg)
fmt = fmt.encode("utf8")
self._log_file.write(fmt)
self._log_file.flush()
class Handler(logging.Handler):
def __init__(self, writer):
logging.Handler.__init__(self)
def __init__(self, writer):
logging.Handler.__init__(self)
self._writer = writer
self._writer = writer
def emit(self, record):
self._writer.write_record(record)
def emit(self, record):
self._writer.write_record(record)
class StdoutCatcher:
def write(self, txt):
_log_writer.write(STDOUT_LEVEL, txt)
sys.__stdout__.write(txt)
def write(self, txt):
_log_writer.write(STDOUT_LEVEL, txt)
sys.__stdout__.write(txt)
class StderrCatcher:
def write(self, txt):
_log_writer.write(STDERR_LEVEL, txt)
sys.__stderr__.write(txt)
def write(self, txt):
_log_writer.write(STDERR_LEVEL, txt)
sys.__stderr__.write(txt)
def __exception_handler(typ, exc, tb):
trace = StringIO()
traceback.print_exception(typ, exc, tb, None, trace)
print >> sys.stderr, trace.getvalue()
trace = StringIO()
traceback.print_exception(typ, exc, tb, None, trace)
print >> sys.stderr, trace.getvalue()
_log_writer.write(logging.ERROR, trace.getvalue())
_log_writer.write(logging.ERROR, trace.getvalue())
def _get_logs_dir():
logs_dir = os.path.join(env.get_profile_path(), 'logs')
if not os.path.isdir(logs_dir):
os.makedirs(logs_dir)
return logs_dir
logs_dir = os.path.join(env.get_profile_path(), 'logs')
if not os.path.isdir(logs_dir):
os.makedirs(logs_dir)
return logs_dir
def start(module_id):
log_writer = LogWriter(module_id)
log_writer = LogWriter(module_id)
root_logger = logging.getLogger('')
root_logger.setLevel(logging.DEBUG)
root_logger.addHandler(Handler(log_writer))
root_logger = logging.getLogger('')
root_logger.setLevel(logging.DEBUG)
root_logger.addHandler(Handler(log_writer))
sys.stdout = StdoutCatcher()
sys.stderr = StderrCatcher()
sys.stdout = StdoutCatcher()
sys.stderr = StderrCatcher()
global _log_writer
_log_writer = log_writer
sys.excepthook = __exception_handler
global _log_writer
_log_writer = log_writer
sys.excepthook = __exception_handler
def cleanup():
logs_dir = _get_logs_dir()
for f in os.listdir(logs_dir):
os.remove(os.path.join(logs_dir, f))
logs_dir = _get_logs_dir()
for f in os.listdir(logs_dir):
os.remove(os.path.join(logs_dir, f))
File diff suppressed because it is too large Load Diff
+15 -15
View File
@@ -21,18 +21,18 @@ from sugar.p2p.Notifier import Notifier
from sugar.p2p import network
class NotificationListener:
def __init__(self, service):
logging.debug('Start notification listener. Service %s, address %s, port %s' % (service.get_type(), service.get_address(), service.get_port()))
server = network.GroupServer(service.get_address(),
service.get_port(),
self._recv_multicast)
server.start()
self._listeners = []
def add_listener(self, listener):
self._listeners.append(listener)
def _recv_multicast(self, msg):
for listener in self._listeners:
listener(msg)
def __init__(self, service):
logging.debug('Start notification listener. Service %s, address %s, port %s' % (service.get_type(), service.get_address(), service.get_port()))
server = network.GroupServer(service.get_address(),
service.get_port(),
self._recv_multicast)
server.start()
self._listeners = []
def add_listener(self, listener):
self._listeners.append(listener)
def _recv_multicast(self, msg):
for listener in self._listeners:
listener(msg)
+7 -7
View File
@@ -18,10 +18,10 @@
from sugar.p2p import network
class Notifier:
def __init__(self, service):
address = service.get_address()
port = service.get_port()
self._client = network.GroupClient(address, port)
def notify(self, msg):
self._client.send_msg(msg)
def __init__(self, service):
address = service.get_address()
port = service.get_port()
self._client = network.GroupClient(address, port)
def notify(self, msg):
self._client.send_msg(msg)
+107 -107
View File
@@ -26,135 +26,135 @@ from MostlyReliablePipe import MostlyReliablePipe
from sugar.presence import Service
def is_multicast_address(address):
"""Simple numerical check for whether an IP4 address
is in the range for multicast addresses or not."""
if not address:
return False
if address[3] != '.':
return False
first = int(float(address[:3]))
if first >= 224 and first <= 239:
return True
return False
"""Simple numerical check for whether an IP4 address
is in the range for multicast addresses or not."""
if not address:
return False
if address[3] != '.':
return False
first = int(float(address[:3]))
if first >= 224 and first <= 239:
return True
return False
class Stream(object):
def __init__(self, service):
if not service.get_port():
raise ValueError("service must have an address.")
self._service = service
self._reader_port = self._service.get_port()
self._writer_port = self._reader_port
self._address = self._service.get_address()
self._callback = None
def __init__(self, service):
if not service.get_port():
raise ValueError("service must have an address.")
self._service = service
self._reader_port = self._service.get_port()
self._writer_port = self._reader_port
self._address = self._service.get_address()
self._callback = None
def new_from_service(service, start_reader=True):
if is_multicast_address(service.get_address()):
return MulticastStream(service)
else:
return UnicastStream(service, start_reader)
new_from_service = staticmethod(new_from_service)
def new_from_service(service, start_reader=True):
if is_multicast_address(service.get_address()):
return MulticastStream(service)
else:
return UnicastStream(service, start_reader)
new_from_service = staticmethod(new_from_service)
def set_data_listener(self, callback):
self._callback = callback
def set_data_listener(self, callback):
self._callback = callback
def _recv(self, address, data):
if self._callback:
self._callback(address, data)
def _recv(self, address, data):
if self._callback:
self._callback(address, data)
class UnicastStreamWriter(object):
def __init__(self, stream, service):
# set up the writer
self._service = service
if not service.get_address():
raise ValueError("service must have a valid address.")
self._address = self._service.get_address()
self._port = self._service.get_port()
self._xmlrpc_addr = "http://%s:%d" % (self._address, self._port)
self._writer = network.GlibServerProxy(self._xmlrpc_addr)
def __init__(self, stream, service):
# set up the writer
self._service = service
if not service.get_address():
raise ValueError("service must have a valid address.")
self._address = self._service.get_address()
self._port = self._service.get_port()
self._xmlrpc_addr = "http://%s:%d" % (self._address, self._port)
self._writer = network.GlibServerProxy(self._xmlrpc_addr)
def write(self, xmlrpc_data):
"""Write some data to the default endpoint of this pipe on the remote server."""
try:
self._writer.message(None, None, xmlrpc_data)
return True
except (socket.error, xmlrpclib.Fault, xmlrpclib.ProtocolError):
traceback.print_exc()
return False
def write(self, xmlrpc_data):
"""Write some data to the default endpoint of this pipe on the remote server."""
try:
self._writer.message(None, None, xmlrpc_data)
return True
except (socket.error, xmlrpclib.Fault, xmlrpclib.ProtocolError):
traceback.print_exc()
return False
def custom_request(self, method_name, request_cb, user_data, *args):
"""Call a custom XML-RPC method on the remote server."""
try:
method = getattr(self._writer, method_name)
method(request_cb, user_data, *args)
return True
except (socket.error, xmlrpclib.Fault, xmlrpclib.ProtocolError):
traceback.print_exc()
return False
def custom_request(self, method_name, request_cb, user_data, *args):
"""Call a custom XML-RPC method on the remote server."""
try:
method = getattr(self._writer, method_name)
method(request_cb, user_data, *args)
return True
except (socket.error, xmlrpclib.Fault, xmlrpclib.ProtocolError):
traceback.print_exc()
return False
class UnicastStream(Stream):
def __init__(self, service, start_reader=True):
"""Initializes the stream. If the 'start_reader' argument is True,
the stream will initialize and start a new stream reader, if it
is False, no reader will be created and the caller must call the
start_reader() method to start the stream reader and be able to
receive any data from the stream."""
Stream.__init__(self, service)
if start_reader:
self.start_reader()
def __init__(self, service, start_reader=True):
"""Initializes the stream. If the 'start_reader' argument is True,
the stream will initialize and start a new stream reader, if it
is False, no reader will be created and the caller must call the
start_reader() method to start the stream reader and be able to
receive any data from the stream."""
Stream.__init__(self, service)
if start_reader:
self.start_reader()
def start_reader(self):
"""Start the stream's reader, which for UnicastStream objects is
and XMLRPC server. If there's a port conflict with some other
service, the reader will try to find another port to use instead.
Returns the port number used for the reader."""
# Set up the reader
self._reader = network.GlibXMLRPCServer(("", self._reader_port))
self._reader.register_function(self._message, "message")
def start_reader(self):
"""Start the stream's reader, which for UnicastStream objects is
and XMLRPC server. If there's a port conflict with some other
service, the reader will try to find another port to use instead.
Returns the port number used for the reader."""
# Set up the reader
self._reader = network.GlibXMLRPCServer(("", self._reader_port))
self._reader.register_function(self._message, "message")
def _message(self, message):
"""Called by the XMLRPC server when network data arrives."""
address = network.get_authinfo()
self._recv(address, message)
return True
def _message(self, message):
"""Called by the XMLRPC server when network data arrives."""
address = network.get_authinfo()
self._recv(address, message)
return True
def register_reader_handler(self, handler, name):
"""Register a custom message handler with the reader. This call
adds a custom XMLRPC method call with the name 'name' to the reader's
XMLRPC server, which then calls the 'handler' argument back when
a method call for it arrives over the network."""
if name == "message":
raise ValueError("Handler name 'message' is a reserved handler.")
self._reader.register_function(handler, name)
def register_reader_handler(self, handler, name):
"""Register a custom message handler with the reader. This call
adds a custom XMLRPC method call with the name 'name' to the reader's
XMLRPC server, which then calls the 'handler' argument back when
a method call for it arrives over the network."""
if name == "message":
raise ValueError("Handler name 'message' is a reserved handler.")
self._reader.register_function(handler, name)
def new_writer(self, service):
"""Return a new stream writer object."""
return UnicastStreamWriter(self, service)
def new_writer(self, service):
"""Return a new stream writer object."""
return UnicastStreamWriter(self, service)
class MulticastStream(Stream):
def __init__(self, service):
Stream.__init__(self, service)
self._service = service
self._internal_start_reader()
def __init__(self, service):
Stream.__init__(self, service)
self._service = service
self._internal_start_reader()
def start_reader(self):
return self._reader_port
def start_reader(self):
return self._reader_port
def _internal_start_reader(self):
logging.debug('Start multicast stream, address %s, port %d' % (self._address, self._reader_port))
if not self._service.get_address():
raise ValueError("service must have a valid address.")
self._pipe = MostlyReliablePipe('', self._address, self._reader_port,
self._recv_data_cb)
self._pipe.start()
def _internal_start_reader(self):
logging.debug('Start multicast stream, address %s, port %d' % (self._address, self._reader_port))
if not self._service.get_address():
raise ValueError("service must have a valid address.")
self._pipe = MostlyReliablePipe('', self._address, self._reader_port,
self._recv_data_cb)
self._pipe.start()
def write(self, data):
self._pipe.send(data)
def write(self, data):
self._pipe.send(data)
def _recv_data_cb(self, address, data, user_data=None):
self._recv(address[0], data)
def _recv_data_cb(self, address, data, user_data=None):
self._recv(address[0], data)
def new_writer(self, service=None):
return self
def new_writer(self, service=None):
return self
+263 -263
View File
@@ -35,347 +35,347 @@ RESULT_SUCCESS = 1
__authinfos = {}
def _add_authinfo(authinfo):
__authinfos[threading.currentThread()] = authinfo
__authinfos[threading.currentThread()] = authinfo
def get_authinfo():
return __authinfos.get(threading.currentThread())
return __authinfos.get(threading.currentThread())
def _del_authinfo():
del __authinfos[threading.currentThread()]
del __authinfos[threading.currentThread()]
class GlibTCPServer(SocketServer.TCPServer):
"""GlibTCPServer
"""GlibTCPServer
Integrate socket accept into glib mainloop.
"""
Integrate socket accept into glib mainloop.
"""
allow_reuse_address = True
request_queue_size = 20
allow_reuse_address = True
request_queue_size = 20
def __init__(self, server_address, RequestHandlerClass):
SocketServer.TCPServer.__init__(self, server_address, RequestHandlerClass)
self.socket.setblocking(0) # Set nonblocking
def __init__(self, server_address, RequestHandlerClass):
SocketServer.TCPServer.__init__(self, server_address, RequestHandlerClass)
self.socket.setblocking(0) # Set nonblocking
# Watch the listener socket for data
gobject.io_add_watch(self.socket, gobject.IO_IN, self._handle_accept)
# Watch the listener socket for data
gobject.io_add_watch(self.socket, gobject.IO_IN, self._handle_accept)
def _handle_accept(self, source, condition):
"""Process incoming data on the server's socket by doing an accept()
via handle_request()."""
if not (condition & gobject.IO_IN):
return True
self.handle_request()
return True
def _handle_accept(self, source, condition):
"""Process incoming data on the server's socket by doing an accept()
via handle_request()."""
if not (condition & gobject.IO_IN):
return True
self.handle_request()
return True
class GlibXMLRPCRequestHandler(SimpleXMLRPCServer.SimpleXMLRPCRequestHandler):
""" GlibXMLRPCRequestHandler
The stock SimpleXMLRPCRequestHandler and server don't allow any way to pass
the client's address and/or SSL certificate into the function that actually
_processes_ the request. So we have to store it in a thread-indexed dict.
"""
""" GlibXMLRPCRequestHandler
The stock SimpleXMLRPCRequestHandler and server don't allow any way to pass
the client's address and/or SSL certificate into the function that actually
_processes_ the request. So we have to store it in a thread-indexed dict.
"""
def do_POST(self):
_add_authinfo(self.client_address)
try:
SimpleXMLRPCServer.SimpleXMLRPCRequestHandler.do_POST(self)
except socket.timeout:
pass
except socket.error, e:
print "Error (%s): socket error - '%s'" % (self.client_address, e)
except:
print "Error while processing POST:"
traceback.print_exc()
_del_authinfo()
def do_POST(self):
_add_authinfo(self.client_address)
try:
SimpleXMLRPCServer.SimpleXMLRPCRequestHandler.do_POST(self)
except socket.timeout:
pass
except socket.error, e:
print "Error (%s): socket error - '%s'" % (self.client_address, e)
except:
print "Error while processing POST:"
traceback.print_exc()
_del_authinfo()
class GlibXMLRPCServer(GlibTCPServer, SimpleXMLRPCServer.SimpleXMLRPCDispatcher):
"""GlibXMLRPCServer
Use nonblocking sockets and handle the accept via glib rather than
blocking on accept().
"""
"""GlibXMLRPCServer
Use nonblocking sockets and handle the accept via glib rather than
blocking on accept().
"""
def __init__(self, addr, requestHandler=GlibXMLRPCRequestHandler, logRequests=0):
self.logRequests = logRequests
SimpleXMLRPCServer.SimpleXMLRPCDispatcher.__init__(self)
GlibTCPServer.__init__(self, addr, requestHandler)
def __init__(self, addr, requestHandler=GlibXMLRPCRequestHandler, logRequests=0):
self.logRequests = logRequests
SimpleXMLRPCServer.SimpleXMLRPCDispatcher.__init__(self)
GlibTCPServer.__init__(self, addr, requestHandler)
def _marshaled_dispatch(self, data, dispatch_method = None):
"""Dispatches an XML-RPC method from marshalled (XML) data.
def _marshaled_dispatch(self, data, dispatch_method = None):
"""Dispatches an XML-RPC method from marshalled (XML) data.
XML-RPC methods are dispatched from the marshalled (XML) data
using the _dispatch method and the result is returned as
marshalled data. For backwards compatibility, a dispatch
function can be provided as an argument (see comment in
SimpleXMLRPCRequestHandler.do_POST) but overriding the
existing method through subclassing is the prefered means
of changing method dispatch behavior.
"""
XML-RPC methods are dispatched from the marshalled (XML) data
using the _dispatch method and the result is returned as
marshalled data. For backwards compatibility, a dispatch
function can be provided as an argument (see comment in
SimpleXMLRPCRequestHandler.do_POST) but overriding the
existing method through subclassing is the prefered means
of changing method dispatch behavior.
"""
params, method = xmlrpclib.loads(data)
params, method = xmlrpclib.loads(data)
# generate response
try:
if dispatch_method is not None:
response = dispatch_method(method, params)
else:
response = self._dispatch(method, params)
# wrap response in a singleton tuple
response = (response,)
response = xmlrpclib.dumps(response, methodresponse=1)
except xmlrpclib.Fault, fault:
response = xmlrpclib.dumps(fault)
except:
print "Exception while processing request:"
traceback.print_exc()
# generate response
try:
if dispatch_method is not None:
response = dispatch_method(method, params)
else:
response = self._dispatch(method, params)
# wrap response in a singleton tuple
response = (response,)
response = xmlrpclib.dumps(response, methodresponse=1)
except xmlrpclib.Fault, fault:
response = xmlrpclib.dumps(fault)
except:
print "Exception while processing request:"
traceback.print_exc()
# report exception back to server
response = xmlrpclib.dumps(
xmlrpclib.Fault(1, "%s:%s" % (sys.exc_type, sys.exc_value))
)
# report exception back to server
response = xmlrpclib.dumps(
xmlrpclib.Fault(1, "%s:%s" % (sys.exc_type, sys.exc_value))
)
return response
return response
class GlibHTTP(httplib.HTTP):
"""Subclass HTTP so we can return it's connection class' socket."""
def connect(self, host=None, port=None):
httplib.HTTP.connect(self, host, port)
self._conn.sock.setblocking(0)
def get_sock(self):
return self._conn.sock
"""Subclass HTTP so we can return it's connection class' socket."""
def connect(self, host=None, port=None):
httplib.HTTP.connect(self, host, port)
self._conn.sock.setblocking(0)
def get_sock(self):
return self._conn.sock
class GlibXMLRPCTransport(xmlrpclib.Transport):
"""Integrate the request with the glib mainloop rather than blocking."""
##
# Connect to server.
#
# @param host Target host.
# @return A connection handle.
"""Integrate the request with the glib mainloop rather than blocking."""
##
# Connect to server.
#
# @param host Target host.
# @return A connection handle.
def __init__(self):
pass
def __init__(self):
pass
def make_connection(self, host):
"""Use our own connection object so we can get its socket."""
# create a HTTP connection object from a host descriptor
host, extra_headers, x509 = self.get_host_info(host)
return GlibHTTP(host)
def make_connection(self, host):
"""Use our own connection object so we can get its socket."""
# create a HTTP connection object from a host descriptor
host, extra_headers, x509 = self.get_host_info(host)
return GlibHTTP(host)
##
# Send a complete request, and parse the response.
#
# @param host Target host.
# @param handler Target PRC handler.
# @param request_body XML-RPC request body.
# @param verbose Debugging flag.
# @return Parsed response.
##
# Send a complete request, and parse the response.
#
# @param host Target host.
# @param handler Target PRC handler.
# @param request_body XML-RPC request body.
# @param verbose Debugging flag.
# @return Parsed response.
def start_request(self, host, handler, request_body, verbose=0, request_cb=None, user_data=None):
"""Do the first half of the request by sending data to the remote
server. The bottom half bits get run when the remote server's response
actually comes back."""
# issue XML-RPC request
def start_request(self, host, handler, request_body, verbose=0, request_cb=None, user_data=None):
"""Do the first half of the request by sending data to the remote
server. The bottom half bits get run when the remote server's response
actually comes back."""
# issue XML-RPC request
h = self.make_connection(host)
if verbose:
h.set_debuglevel(1)
h = self.make_connection(host)
if verbose:
h.set_debuglevel(1)
self.send_request(h, handler, request_body)
self.send_host(h, host)
self.send_user_agent(h)
self.send_content(h, request_body)
self.send_request(h, handler, request_body)
self.send_host(h, host)
self.send_user_agent(h)
self.send_content(h, request_body)
# Schedule a GIOWatch so we don't block waiting for the response
gobject.io_add_watch(h.get_sock(), gobject.IO_IN, self._finish_request,
h, host, handler, verbose, request_cb, user_data)
# Schedule a GIOWatch so we don't block waiting for the response
gobject.io_add_watch(h.get_sock(), gobject.IO_IN, self._finish_request,
h, host, handler, verbose, request_cb, user_data)
def _finish_request(self, source, condition, h, host, handler, verbose, request_cb, user_data):
"""Parse and return response when the remote server actually returns it."""
if not (condition & gobject.IO_IN):
return True
def _finish_request(self, source, condition, h, host, handler, verbose, request_cb, user_data):
"""Parse and return response when the remote server actually returns it."""
if not (condition & gobject.IO_IN):
return True
try:
errcode, errmsg, headers = h.getreply()
except socket.error, err:
if err[0] != 104:
raise socket.error(err)
else:
gobject.idle_add(request_cb, RESULT_FAILED, None, user_data)
return False
if errcode != 200:
raise xmlrpclib.ProtocolError(host + handler, errcode, errmsg, headers)
self.verbose = verbose
response = self._parse_response(h.getfile(), h.get_sock())
if request_cb:
if len(response) == 1:
response = response[0]
gobject.idle_add(request_cb, RESULT_SUCCESS, response, user_data)
return False
try:
errcode, errmsg, headers = h.getreply()
except socket.error, err:
if err[0] != 104:
raise socket.error(err)
else:
gobject.idle_add(request_cb, RESULT_FAILED, None, user_data)
return False
if errcode != 200:
raise xmlrpclib.ProtocolError(host + handler, errcode, errmsg, headers)
self.verbose = verbose
response = self._parse_response(h.getfile(), h.get_sock())
if request_cb:
if len(response) == 1:
response = response[0]
gobject.idle_add(request_cb, RESULT_SUCCESS, response, user_data)
return False
class _Method:
"""Right, so python people thought it would be funny to make this
class private to xmlrpclib.py..."""
# some magic to bind an XML-RPC method to an RPC server.
# supports "nested" methods (e.g. examples.getStateName)
def __init__(self, send, name):
self.__send = send
self.__name = name
def __getattr__(self, name):
return _Method(self.__send, "%s.%s" % (self.__name, name))
def __call__(self, request_cb, user_data, *args):
return self.__send(self.__name, request_cb, user_data, args)
"""Right, so python people thought it would be funny to make this
class private to xmlrpclib.py..."""
# some magic to bind an XML-RPC method to an RPC server.
# supports "nested" methods (e.g. examples.getStateName)
def __init__(self, send, name):
self.__send = send
self.__name = name
def __getattr__(self, name):
return _Method(self.__send, "%s.%s" % (self.__name, name))
def __call__(self, request_cb, user_data, *args):
return self.__send(self.__name, request_cb, user_data, args)
class GlibServerProxy(xmlrpclib.ServerProxy):
"""Subclass xmlrpclib.ServerProxy so we can run the XML-RPC request
in two parts, integrated with the glib mainloop, such that we don't
block anywhere.
Using this object is somewhat special; it requires more arguments to each
XML-RPC request call than the normal xmlrpclib.ServerProxy object:
client = GlibServerProxy("http://127.0.0.1:8888")
user_data = "bar"
xmlrpc_arg1 = "test"
xmlrpc_arg2 = "foo"
client.test(xmlrpc_test_cb, user_data, xmlrpc_arg1, xmlrpc_arg2)
"""Subclass xmlrpclib.ServerProxy so we can run the XML-RPC request
in two parts, integrated with the glib mainloop, such that we don't
block anywhere.
Using this object is somewhat special; it requires more arguments to each
XML-RPC request call than the normal xmlrpclib.ServerProxy object:
client = GlibServerProxy("http://127.0.0.1:8888")
user_data = "bar"
xmlrpc_arg1 = "test"
xmlrpc_arg2 = "foo"
client.test(xmlrpc_test_cb, user_data, xmlrpc_arg1, xmlrpc_arg2)
Here, 'xmlrpc_test_cb' is the callback function, which has the following
signature:
def xmlrpc_test_cb(result_status, response, user_data=None):
...
"""
def __init__(self, uri, encoding=None, verbose=0, allow_none=0):
self._transport = GlibXMLRPCTransport()
self._encoding = encoding
self._verbose = verbose
self._allow_none = allow_none
xmlrpclib.ServerProxy.__init__(self, uri, self._transport, encoding, verbose, allow_none)
Here, 'xmlrpc_test_cb' is the callback function, which has the following
signature:
def xmlrpc_test_cb(result_status, response, user_data=None):
...
"""
def __init__(self, uri, encoding=None, verbose=0, allow_none=0):
self._transport = GlibXMLRPCTransport()
self._encoding = encoding
self._verbose = verbose
self._allow_none = allow_none
xmlrpclib.ServerProxy.__init__(self, uri, self._transport, encoding, verbose, allow_none)
# get the url
import urllib
urltype, uri = urllib.splittype(uri)
if urltype not in ("http", "https"):
raise IOError, "unsupported XML-RPC protocol"
self._host, self._handler = urllib.splithost(uri)
if not self._handler:
self._handler = "/RPC2"
# get the url
import urllib
urltype, uri = urllib.splittype(uri)
if urltype not in ("http", "https"):
raise IOError, "unsupported XML-RPC protocol"
self._host, self._handler = urllib.splithost(uri)
if not self._handler:
self._handler = "/RPC2"
def __request(self, methodname, request_cb, user_data, params):
"""Call the method on the remote server. We just start the request here
and the transport itself takes care of scheduling the response callback
when the remote server returns the response. We don't want to block anywhere."""
def __request(self, methodname, request_cb, user_data, params):
"""Call the method on the remote server. We just start the request here
and the transport itself takes care of scheduling the response callback
when the remote server returns the response. We don't want to block anywhere."""
request = xmlrpclib.dumps(params, methodname, encoding=self._encoding,
allow_none=self._allow_none)
request = xmlrpclib.dumps(params, methodname, encoding=self._encoding,
allow_none=self._allow_none)
try:
response = self._transport.start_request(
self._host,
self._handler,
request,
verbose=self._verbose,
request_cb=request_cb,
user_data=user_data
)
except socket.error, exc:
gobject.idle_add(request_cb, RESULT_FAILED, None, user_data)
try:
response = self._transport.start_request(
self._host,
self._handler,
request,
verbose=self._verbose,
request_cb=request_cb,
user_data=user_data
)
except socket.error, exc:
gobject.idle_add(request_cb, RESULT_FAILED, None, user_data)
def __getattr__(self, name):
# magic method dispatcher
return _Method(self.__request, name)
def __getattr__(self, name):
# magic method dispatcher
return _Method(self.__request, name)
class GroupServer(object):
_MAX_MSG_SIZE = 500
_MAX_MSG_SIZE = 500
def __init__(self, address, port, data_cb):
self._address = address
self._port = port
self._data_cb = data_cb
def __init__(self, address, port, data_cb):
self._address = address
self._port = port
self._data_cb = data_cb
self._setup_listener()
self._setup_listener()
def _setup_listener(self):
# Listener socket
self._listen_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
def _setup_listener(self):
# Listener socket
self._listen_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# Set some options to make it multicast-friendly
self._listen_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self._listen_sock.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_TTL, 20)
self._listen_sock.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_LOOP, 1)
# Set some options to make it multicast-friendly
self._listen_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self._listen_sock.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_TTL, 20)
self._listen_sock.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_LOOP, 1)
def start(self):
# Set some more multicast options
self._listen_sock.bind(('', self._port))
self._listen_sock.settimeout(2)
intf = socket.gethostbyname(socket.gethostname())
self._listen_sock.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_IF, socket.inet_aton(intf) + socket.inet_aton('0.0.0.0'))
self._listen_sock.setsockopt(socket.SOL_IP, socket.IP_ADD_MEMBERSHIP, socket.inet_aton(self._address) + socket.inet_aton('0.0.0.0'))
def start(self):
# Set some more multicast options
self._listen_sock.bind(('', self._port))
self._listen_sock.settimeout(2)
intf = socket.gethostbyname(socket.gethostname())
self._listen_sock.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_IF, socket.inet_aton(intf) + socket.inet_aton('0.0.0.0'))
self._listen_sock.setsockopt(socket.SOL_IP, socket.IP_ADD_MEMBERSHIP, socket.inet_aton(self._address) + socket.inet_aton('0.0.0.0'))
# Watch the listener socket for data
gobject.io_add_watch(self._listen_sock, gobject.IO_IN, self._handle_incoming_data)
# Watch the listener socket for data
gobject.io_add_watch(self._listen_sock, gobject.IO_IN, self._handle_incoming_data)
def _handle_incoming_data(self, source, condition):
if not (condition & gobject.IO_IN):
return True
msg = {}
msg['data'], (msg['addr'], msg['port']) = source.recvfrom(self._MAX_MSG_SIZE)
if self._data_cb:
self._data_cb(msg)
return True
def _handle_incoming_data(self, source, condition):
if not (condition & gobject.IO_IN):
return True
msg = {}
msg['data'], (msg['addr'], msg['port']) = source.recvfrom(self._MAX_MSG_SIZE)
if self._data_cb:
self._data_cb(msg)
return True
class GroupClient(object):
_MAX_MSG_SIZE = 500
_MAX_MSG_SIZE = 500
def __init__(self, address, port):
self._address = address
self._port = port
def __init__(self, address, port):
self._address = address
self._port = port
self._send_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# Make the socket multicast-aware, and set TTL.
self._send_sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 20) # Change TTL (=20) to suit
self._send_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# Make the socket multicast-aware, and set TTL.
self._send_sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 20) # Change TTL (=20) to suit
def send_msg(self, data):
self._send_sock.sendto(data, (self._address, self._port))
def send_msg(self, data):
self._send_sock.sendto(data, (self._address, self._port))
class Test(object):
def test(self, arg1):
print "Request got %s" % arg1
return "success"
def test(self, arg1):
print "Request got %s" % arg1
return "success"
def xmlrpc_test_cb(response, user_data=None):
print "Response was %s, user_data was %s" % (response, user_data)
import gtk
gtk.main_quit()
print "Response was %s, user_data was %s" % (response, user_data)
import gtk
gtk.main_quit()
def xmlrpc_test():
client = GlibServerProxy("http://127.0.0.1:8888")
client.test(xmlrpc_test_cb, "bar", "test data")
client = GlibServerProxy("http://127.0.0.1:8888")
client.test(xmlrpc_test_cb, "bar", "test data")
def main():
import gtk
server = GlibXMLRPCServer(("", 8888))
inst = Test()
server.register_instance(inst)
gobject.idle_add(xmlrpc_test)
import gtk
server = GlibXMLRPCServer(("", 8888))
inst = Test()
server.register_instance(inst)
gobject.idle_add(xmlrpc_test)
try:
gtk.main()
except KeyboardInterrupt:
print 'Ctrl+C pressed, exiting...'
print "Done."
try:
gtk.main()
except KeyboardInterrupt:
print 'Ctrl+C pressed, exiting...'
print "Done."
if __name__ == "__main__":
main()
main()
+78 -78
View File
@@ -20,98 +20,98 @@ import dbus
class Activity(gobject.GObject):
__gsignals__ = {
'buddy-joined': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT])),
'buddy-left': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT])),
'service-appeared': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT])),
'service-disappeared': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT]))
}
__gsignals__ = {
'buddy-joined': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT])),
'buddy-left': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT])),
'service-appeared': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT])),
'service-disappeared': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT]))
}
_PRESENCE_SERVICE = "org.laptop.Presence"
_ACTIVITY_DBUS_INTERFACE = "org.laptop.Presence.Activity"
_PRESENCE_SERVICE = "org.laptop.Presence"
_ACTIVITY_DBUS_INTERFACE = "org.laptop.Presence.Activity"
def __init__(self, bus, new_obj_cb, del_obj_cb, object_path):
gobject.GObject.__init__(self)
self._object_path = object_path
self._ps_new_object = new_obj_cb
self._ps_del_object = del_obj_cb
bobj = bus.get_object(self._PRESENCE_SERVICE, object_path)
self._activity = dbus.Interface(bobj, self._ACTIVITY_DBUS_INTERFACE)
self._activity.connect_to_signal('BuddyJoined', self._buddy_joined_cb)
self._activity.connect_to_signal('BuddyLeft', self._buddy_left_cb)
self._activity.connect_to_signal('ServiceAppeared', self._service_appeared_cb)
self._activity.connect_to_signal('ServiceDisappeared', self._service_disappeared_cb)
self._id = None
self._color = None
def __init__(self, bus, new_obj_cb, del_obj_cb, object_path):
gobject.GObject.__init__(self)
self._object_path = object_path
self._ps_new_object = new_obj_cb
self._ps_del_object = del_obj_cb
bobj = bus.get_object(self._PRESENCE_SERVICE, object_path)
self._activity = dbus.Interface(bobj, self._ACTIVITY_DBUS_INTERFACE)
self._activity.connect_to_signal('BuddyJoined', self._buddy_joined_cb)
self._activity.connect_to_signal('BuddyLeft', self._buddy_left_cb)
self._activity.connect_to_signal('ServiceAppeared', self._service_appeared_cb)
self._activity.connect_to_signal('ServiceDisappeared', self._service_disappeared_cb)
self._id = None
self._color = None
def object_path(self):
return self._object_path
def object_path(self):
return self._object_path
def _emit_buddy_joined_signal(self, object_path):
self.emit('buddy-joined', self._ps_new_object(object_path))
return False
def _emit_buddy_joined_signal(self, object_path):
self.emit('buddy-joined', self._ps_new_object(object_path))
return False
def _buddy_joined_cb(self, object_path):
gobject.idle_add(self._emit_buddy_joined_signal, object_path)
def _buddy_joined_cb(self, object_path):
gobject.idle_add(self._emit_buddy_joined_signal, object_path)
def _emit_buddy_left_signal(self, object_path):
self.emit('buddy-left', self._ps_new_object(object_path))
return False
def _emit_buddy_left_signal(self, object_path):
self.emit('buddy-left', self._ps_new_object(object_path))
return False
def _buddy_left_cb(self, object_path):
gobject.idle_add(self._emit_buddy_left_signal, object_path)
def _buddy_left_cb(self, object_path):
gobject.idle_add(self._emit_buddy_left_signal, object_path)
def _emit_service_appeared_signal(self, object_path):
self.emit('service-appeared', self._ps_new_object(object_path))
return False
def _emit_service_appeared_signal(self, object_path):
self.emit('service-appeared', self._ps_new_object(object_path))
return False
def _service_appeared_cb(self, object_path):
gobject.idle_add(self._emit_service_appeared_signal, object_path)
def _service_appeared_cb(self, object_path):
gobject.idle_add(self._emit_service_appeared_signal, object_path)
def _emit_service_disappeared_signal(self, object_path):
self.emit('service-disappeared', self._ps_new_object(object_path))
return False
def _emit_service_disappeared_signal(self, object_path):
self.emit('service-disappeared', self._ps_new_object(object_path))
return False
def _service_disappeared_cb(self, object_path):
gobject.idle_add(self._emit_service_disappeared_signal, object_path)
def _service_disappeared_cb(self, object_path):
gobject.idle_add(self._emit_service_disappeared_signal, object_path)
def get_id(self):
# Cache activity ID, which should never change anyway
if not self._id:
self._id = self._activity.getId()
return self._id
def get_id(self):
# Cache activity ID, which should never change anyway
if not self._id:
self._id = self._activity.getId()
return self._id
def get_color(self):
if not self._color:
self._color = self._activity.getColor()
return self._color
def get_color(self):
if not self._color:
self._color = self._activity.getColor()
return self._color
def get_services(self):
resp = self._activity.getServices()
servs = []
for item in resp:
servs.append(self._ps_new_object(item))
return servs
def get_services(self):
resp = self._activity.getServices()
servs = []
for item in resp:
servs.append(self._ps_new_object(item))
return servs
def get_services_of_type(self, stype):
resp = self._activity.getServicesOfType(stype)
servs = []
for item in resp:
servs.append(self._ps_new_object(item))
return servs
def get_services_of_type(self, stype):
resp = self._activity.getServicesOfType(stype)
servs = []
for item in resp:
servs.append(self._ps_new_object(item))
return servs
def get_joined_buddies(self):
resp = self._activity.getJoinedBuddies()
buddies = []
for item in resp:
buddies.append(self._ps_new_object(item))
return buddies
def get_joined_buddies(self):
resp = self._activity.getJoinedBuddies()
buddies = []
for item in resp:
buddies.append(self._ps_new_object(item))
return buddies
def owner_has_joined(self):
# FIXME
return False
def owner_has_joined(self):
# FIXME
return False
+140 -140
View File
@@ -21,173 +21,173 @@ import dbus
class Buddy(gobject.GObject):
__gsignals__ = {
'icon-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([])),
'disappeared': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([])),
'service-appeared': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT])),
'service-disappeared': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT])),
'joined-activity': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT])),
'left-activity': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT])),
'property-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT])),
'current-activity-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT]))
}
__gsignals__ = {
'icon-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([])),
'disappeared': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([])),
'service-appeared': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT])),
'service-disappeared': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT])),
'joined-activity': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT])),
'left-activity': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT])),
'property-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT])),
'current-activity-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT]))
}
_PRESENCE_SERVICE = "org.laptop.Presence"
_BUDDY_DBUS_INTERFACE = "org.laptop.Presence.Buddy"
_PRESENCE_SERVICE = "org.laptop.Presence"
_BUDDY_DBUS_INTERFACE = "org.laptop.Presence.Buddy"
def __init__(self, bus, new_obj_cb, del_obj_cb, object_path):
gobject.GObject.__init__(self)
self._object_path = object_path
self._ps_new_object = new_obj_cb
self._ps_del_object = del_obj_cb
self._properties = {}
bobj = bus.get_object(self._PRESENCE_SERVICE, object_path)
self._buddy = dbus.Interface(bobj, self._BUDDY_DBUS_INTERFACE)
self._buddy.connect_to_signal('IconChanged', self._icon_changed_cb)
self._buddy.connect_to_signal('ServiceAppeared', self._service_appeared_cb)
self._buddy.connect_to_signal('ServiceDisappeared', self._service_disappeared_cb)
self._buddy.connect_to_signal('Disappeared', self._disappeared_cb)
self._buddy.connect_to_signal('JoinedActivity', self._joined_activity_cb)
self._buddy.connect_to_signal('LeftActivity', self._left_activity_cb)
self._buddy.connect_to_signal('PropertyChanged', self._property_changed_cb)
self._buddy.connect_to_signal('CurrentActivityChanged', self._current_activity_changed_cb)
self._properties = self._get_properties_helper()
def __init__(self, bus, new_obj_cb, del_obj_cb, object_path):
gobject.GObject.__init__(self)
self._object_path = object_path
self._ps_new_object = new_obj_cb
self._ps_del_object = del_obj_cb
self._properties = {}
bobj = bus.get_object(self._PRESENCE_SERVICE, object_path)
self._buddy = dbus.Interface(bobj, self._BUDDY_DBUS_INTERFACE)
self._buddy.connect_to_signal('IconChanged', self._icon_changed_cb)
self._buddy.connect_to_signal('ServiceAppeared', self._service_appeared_cb)
self._buddy.connect_to_signal('ServiceDisappeared', self._service_disappeared_cb)
self._buddy.connect_to_signal('Disappeared', self._disappeared_cb)
self._buddy.connect_to_signal('JoinedActivity', self._joined_activity_cb)
self._buddy.connect_to_signal('LeftActivity', self._left_activity_cb)
self._buddy.connect_to_signal('PropertyChanged', self._property_changed_cb)
self._buddy.connect_to_signal('CurrentActivityChanged', self._current_activity_changed_cb)
self._properties = self._get_properties_helper()
self._current_activity = None
try:
self._current_activity = self._buddy.getCurrentActivity()
except Exception, e:
pass
self._current_activity = None
try:
self._current_activity = self._buddy.getCurrentActivity()
except Exception, e:
pass
def _get_properties_helper(self):
props = self._buddy.getProperties()
if not props:
return {}
return props
def _get_properties_helper(self):
props = self._buddy.getProperties()
if not props:
return {}
return props
def object_path(self):
return self._object_path
def object_path(self):
return self._object_path
def _emit_icon_changed_signal(self):
self.emit('icon-changed')
return False
def _emit_icon_changed_signal(self):
self.emit('icon-changed')
return False
def _icon_changed_cb(self):
gobject.idle_add(self._emit_icon_changed_signal)
def _icon_changed_cb(self):
gobject.idle_add(self._emit_icon_changed_signal)
def _emit_disappeared_signal(self):
self.emit('disappeared')
def _emit_disappeared_signal(self):
self.emit('disappeared')
def _disappeared_cb(self):
gobject.idle_add(self._emit_disappeared_signal)
def _disappeared_cb(self):
gobject.idle_add(self._emit_disappeared_signal)
def _emit_service_appeared_signal(self, object_path):
self.emit('service-appeared', self._ps_new_object(object_path))
return False
def _emit_service_appeared_signal(self, object_path):
self.emit('service-appeared', self._ps_new_object(object_path))
return False
def _service_appeared_cb(self, object_path):
gobject.idle_add(self._emit_service_appeared_signal, object_path)
def _service_appeared_cb(self, object_path):
gobject.idle_add(self._emit_service_appeared_signal, object_path)
def _emit_service_disappeared_signal(self, object_path):
self.emit('service-disappeared', self._ps_new_object(object_path))
return False
def _emit_service_disappeared_signal(self, object_path):
self.emit('service-disappeared', self._ps_new_object(object_path))
return False
def _service_disappeared_cb(self, object_path):
gobject.idle_add(self._emit_service_disappeared_signal, object_path)
def _service_disappeared_cb(self, object_path):
gobject.idle_add(self._emit_service_disappeared_signal, object_path)
def _emit_joined_activity_signal(self, object_path):
self.emit('joined-activity', self._ps_new_object(object_path))
return False
def _emit_joined_activity_signal(self, object_path):
self.emit('joined-activity', self._ps_new_object(object_path))
return False
def _joined_activity_cb(self, object_path):
gobject.idle_add(self._emit_joined_activity_signal, object_path)
def _joined_activity_cb(self, object_path):
gobject.idle_add(self._emit_joined_activity_signal, object_path)
def _emit_left_activity_signal(self, object_path):
self.emit('left-activity', self._ps_new_object(object_path))
return False
def _emit_left_activity_signal(self, object_path):
self.emit('left-activity', self._ps_new_object(object_path))
return False
def _left_activity_cb(self, object_path):
gobject.idle_add(self._emit_left_activity_signal, object_path)
def _left_activity_cb(self, object_path):
gobject.idle_add(self._emit_left_activity_signal, object_path)
def _handle_property_changed_signal(self, prop_list):
self._properties = self._get_properties_helper()
self.emit('property-changed', prop_list)
return False
def _handle_property_changed_signal(self, prop_list):
self._properties = self._get_properties_helper()
self.emit('property-changed', prop_list)
return False
def _property_changed_cb(self, prop_list):
gobject.idle_add(self._handle_property_changed_signal, prop_list)
def _property_changed_cb(self, prop_list):
gobject.idle_add(self._handle_property_changed_signal, prop_list)
def _handle_current_activity_changed_signal(self, act_list):
if len(act_list) == 0:
self._current_activity = None
self.emit('current-activity-changed', None)
else:
self._current_activity = act_list[0]
self.emit('current-activity-changed', self._ps_new_object(act_list[0]))
return False
def _handle_current_activity_changed_signal(self, act_list):
if len(act_list) == 0:
self._current_activity = None
self.emit('current-activity-changed', None)
else:
self._current_activity = act_list[0]
self.emit('current-activity-changed', self._ps_new_object(act_list[0]))
return False
def _current_activity_changed_cb(self, act_list):
gobject.idle_add(self._handle_current_activity_changed_signal, act_list)
def _current_activity_changed_cb(self, act_list):
gobject.idle_add(self._handle_current_activity_changed_signal, act_list)
def get_name(self):
return self._properties['name']
def get_name(self):
return self._properties['name']
def get_ip4_address(self):
return self._properties['ip4_address']
def get_ip4_address(self):
return self._properties['ip4_address']
def is_owner(self):
return self._properties['owner']
def is_owner(self):
return self._properties['owner']
def get_color(self):
return self._properties['color']
def get_color(self):
return self._properties['color']
def get_icon(self):
return self._buddy.getIcon()
def get_icon(self):
return self._buddy.getIcon()
def get_current_activity(self):
if not self._current_activity:
return None
return self._ps_new_object(self._current_activity)
def get_current_activity(self):
if not self._current_activity:
return None
return self._ps_new_object(self._current_activity)
def get_icon_pixbuf(self):
icon = self._buddy.getIcon()
if icon and len(icon):
pbl = gtk.gdk.PixbufLoader()
icon_data = ""
for item in icon:
if item < 0:
item = item + 128
icon_data = icon_data + chr(item)
pbl.write(icon_data)
pbl.close()
return pbl.get_pixbuf()
else:
return None
def get_icon_pixbuf(self):
icon = self._buddy.getIcon()
if icon and len(icon):
pbl = gtk.gdk.PixbufLoader()
icon_data = ""
for item in icon:
if item < 0:
item = item + 128
icon_data = icon_data + chr(item)
pbl.write(icon_data)
pbl.close()
return pbl.get_pixbuf()
else:
return None
def get_service_of_type(self, stype, activity=None):
try:
act_op = "/"
if activity:
act_op = activity.object_path()
object_path = self._buddy.getServiceOfType(stype, act_op)
except dbus.exceptions.DBusException:
return None
return self._ps_new_object(object_path)
def get_service_of_type(self, stype, activity=None):
try:
act_op = "/"
if activity:
act_op = activity.object_path()
object_path = self._buddy.getServiceOfType(stype, act_op)
except dbus.exceptions.DBusException:
return None
return self._ps_new_object(object_path)
def get_joined_activities(self):
try:
resp = self._buddy.getJoinedActivities()
except dbus.exceptions.DBusException:
return []
acts = []
for item in resp:
acts.append(self._ps_new_object(item))
return acts
def get_joined_activities(self):
try:
resp = self._buddy.getJoinedActivities()
except dbus.exceptions.DBusException:
return []
acts = []
for item in resp:
acts.append(self._ps_new_object(item))
return acts
+167 -167
View File
@@ -20,23 +20,23 @@ import dbus, dbus.glib, gobject
import Buddy, Service, Activity
class ObjectCache(object):
def __init__(self):
self._cache = {}
def __init__(self):
self._cache = {}
def get(self, object_path):
try:
return self._cache[object_path]
except KeyError:
return None
def get(self, object_path):
try:
return self._cache[object_path]
except KeyError:
return None
def add(self, obj):
op = obj.object_path()
if not self._cache.has_key(op):
self._cache[op] = obj
def add(self, obj):
op = obj.object_path()
if not self._cache.has_key(op):
self._cache[op] = obj
def remove(self, object_path):
if self._cache.has_key(object_path):
del self._cache[object_path]
def remove(self, object_path):
if self._cache.has_key(object_path):
del self._cache[object_path]
DBUS_SERVICE = "org.laptop.Presence"
@@ -46,192 +46,192 @@ DBUS_PATH = "/org/laptop/Presence"
class PresenceService(gobject.GObject):
__gsignals__ = {
'buddy-appeared': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT])),
'buddy-disappeared': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT])),
'service-appeared': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT])),
'service-disappeared': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT])),
'activity-appeared': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT])),
'activity-disappeared': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT]))
}
__gsignals__ = {
'buddy-appeared': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT])),
'buddy-disappeared': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT])),
'service-appeared': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT])),
'service-disappeared': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT])),
'activity-appeared': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT])),
'activity-disappeared': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT]))
}
_PS_BUDDY_OP = DBUS_PATH + "/Buddies/"
_PS_SERVICE_OP = DBUS_PATH + "/Services/"
_PS_ACTIVITY_OP = DBUS_PATH + "/Activities/"
_PS_BUDDY_OP = DBUS_PATH + "/Buddies/"
_PS_SERVICE_OP = DBUS_PATH + "/Services/"
_PS_ACTIVITY_OP = DBUS_PATH + "/Activities/"
def __init__(self):
gobject.GObject.__init__(self)
self._objcache = ObjectCache()
self._bus = dbus.SessionBus()
self._ps = dbus.Interface(self._bus.get_object(DBUS_SERVICE,
DBUS_PATH), DBUS_INTERFACE)
self._ps.connect_to_signal('BuddyAppeared', self._buddy_appeared_cb)
self._ps.connect_to_signal('BuddyDisappeared', self._buddy_disappeared_cb)
self._ps.connect_to_signal('ServiceAppeared', self._service_appeared_cb)
self._ps.connect_to_signal('ServiceDisappeared', self._service_disappeared_cb)
self._ps.connect_to_signal('ActivityAppeared', self._activity_appeared_cb)
self._ps.connect_to_signal('ActivityDisappeared', self._activity_disappeared_cb)
def __init__(self):
gobject.GObject.__init__(self)
self._objcache = ObjectCache()
self._bus = dbus.SessionBus()
self._ps = dbus.Interface(self._bus.get_object(DBUS_SERVICE,
DBUS_PATH), DBUS_INTERFACE)
self._ps.connect_to_signal('BuddyAppeared', self._buddy_appeared_cb)
self._ps.connect_to_signal('BuddyDisappeared', self._buddy_disappeared_cb)
self._ps.connect_to_signal('ServiceAppeared', self._service_appeared_cb)
self._ps.connect_to_signal('ServiceDisappeared', self._service_disappeared_cb)
self._ps.connect_to_signal('ActivityAppeared', self._activity_appeared_cb)
self._ps.connect_to_signal('ActivityDisappeared', self._activity_disappeared_cb)
def _new_object(self, object_path):
obj = self._objcache.get(object_path)
if not obj:
if object_path.startswith(self._PS_SERVICE_OP):
obj = Service.Service(self._bus, self._new_object,
self._del_object, object_path)
elif object_path.startswith(self._PS_BUDDY_OP):
obj = Buddy.Buddy(self._bus, self._new_object,
self._del_object, object_path)
elif object_path.startswith(self._PS_ACTIVITY_OP):
obj = Activity.Activity(self._bus, self._new_object,
self._del_object, object_path)
else:
raise RuntimeError("Unknown object type")
self._objcache.add(obj)
return obj
def _new_object(self, object_path):
obj = self._objcache.get(object_path)
if not obj:
if object_path.startswith(self._PS_SERVICE_OP):
obj = Service.Service(self._bus, self._new_object,
self._del_object, object_path)
elif object_path.startswith(self._PS_BUDDY_OP):
obj = Buddy.Buddy(self._bus, self._new_object,
self._del_object, object_path)
elif object_path.startswith(self._PS_ACTIVITY_OP):
obj = Activity.Activity(self._bus, self._new_object,
self._del_object, object_path)
else:
raise RuntimeError("Unknown object type")
self._objcache.add(obj)
return obj
def _del_object(self, object_path):
# FIXME
pass
def _del_object(self, object_path):
# FIXME
pass
def _emit_buddy_appeared_signal(self, object_path):
self.emit('buddy-appeared', self._new_object(object_path))
return False
def _emit_buddy_appeared_signal(self, object_path):
self.emit('buddy-appeared', self._new_object(object_path))
return False
def _buddy_appeared_cb(self, op):
gobject.idle_add(self._emit_buddy_appeared_signal, op)
def _buddy_appeared_cb(self, op):
gobject.idle_add(self._emit_buddy_appeared_signal, op)
def _emit_buddy_disappeared_signal(self, object_path):
self.emit('buddy-disappeared', self._new_object(object_path))
return False
def _emit_buddy_disappeared_signal(self, object_path):
self.emit('buddy-disappeared', self._new_object(object_path))
return False
def _buddy_disappeared_cb(self, object_path):
gobject.idle_add(self._emit_buddy_disappeared_signal, object_path)
def _buddy_disappeared_cb(self, object_path):
gobject.idle_add(self._emit_buddy_disappeared_signal, object_path)
def _emit_service_appeared_signal(self, object_path):
self.emit('service-appeared', self._new_object(object_path))
return False
def _emit_service_appeared_signal(self, object_path):
self.emit('service-appeared', self._new_object(object_path))
return False
def _service_appeared_cb(self, object_path):
gobject.idle_add(self._emit_service_appeared_signal, object_path)
def _service_appeared_cb(self, object_path):
gobject.idle_add(self._emit_service_appeared_signal, object_path)
def _emit_service_disappeared_signal(self, object_path):
self.emit('service-disappeared', self._new_object(object_path))
return False
def _emit_service_disappeared_signal(self, object_path):
self.emit('service-disappeared', self._new_object(object_path))
return False
def _service_disappeared_cb(self, object_path):
gobject.idle_add(self._emit_service_disappeared_signal, object_path)
def _service_disappeared_cb(self, object_path):
gobject.idle_add(self._emit_service_disappeared_signal, object_path)
def _emit_activity_appeared_signal(self, object_path):
self.emit('activity-appeared', self._new_object(object_path))
return False
def _emit_activity_appeared_signal(self, object_path):
self.emit('activity-appeared', self._new_object(object_path))
return False
def _activity_appeared_cb(self, object_path):
gobject.idle_add(self._emit_activity_appeared_signal, object_path)
def _activity_appeared_cb(self, object_path):
gobject.idle_add(self._emit_activity_appeared_signal, object_path)
def _emit_activity_disappeared_signal(self, object_path):
self.emit('activity-disappeared', self._new_object(object_path))
return False
def _emit_activity_disappeared_signal(self, object_path):
self.emit('activity-disappeared', self._new_object(object_path))
return False
def _activity_disappeared_cb(self, object_path):
gobject.idle_add(self._emit_activity_disappeared_signal, object_path)
def _activity_disappeared_cb(self, object_path):
gobject.idle_add(self._emit_activity_disappeared_signal, object_path)
def get(self, object_path):
return self._new_object(object_path)
def get(self, object_path):
return self._new_object(object_path)
def get_services(self):
resp = self._ps.getServices()
servs = []
for item in resp:
servs.append(self._new_object(item))
return servs
def get_services(self):
resp = self._ps.getServices()
servs = []
for item in resp:
servs.append(self._new_object(item))
return servs
def get_services_of_type(self, stype):
resp = self._ps.getServicesOfType(stype)
servs = []
for item in resp:
servs.append(self._new_object(item))
return servs
def get_services_of_type(self, stype):
resp = self._ps.getServicesOfType(stype)
servs = []
for item in resp:
servs.append(self._new_object(item))
return servs
def get_activities(self):
resp = self._ps.getActivities()
acts = []
for item in resp:
acts.append(self._new_object(item))
return acts
def get_activities(self):
resp = self._ps.getActivities()
acts = []
for item in resp:
acts.append(self._new_object(item))
return acts
def get_activity(self, activity_id):
try:
act_op = self._ps.getActivity(activity_id)
except dbus.exceptions.DBusException:
return None
return self._new_object(act_op)
def get_activity(self, activity_id):
try:
act_op = self._ps.getActivity(activity_id)
except dbus.exceptions.DBusException:
return None
return self._new_object(act_op)
def get_buddies(self):
resp = self._ps.getBuddies()
buddies = []
for item in resp:
buddies.append(self._new_object(item))
return buddies
def get_buddies(self):
resp = self._ps.getBuddies()
buddies = []
for item in resp:
buddies.append(self._new_object(item))
return buddies
def get_buddy_by_name(self, name):
try:
buddy_op = self._ps.getBuddyByName(name)
except dbus.exceptions.DBusException:
return None
return self._new_object(buddy_op)
def get_buddy_by_name(self, name):
try:
buddy_op = self._ps.getBuddyByName(name)
except dbus.exceptions.DBusException:
return None
return self._new_object(buddy_op)
def get_buddy_by_address(self, addr):
try:
buddy_op = self._ps.getBuddyByAddress(addr)
except dbus.exceptions.DBusException:
return None
return self._new_object(buddy_op)
def get_buddy_by_address(self, addr):
try:
buddy_op = self._ps.getBuddyByAddress(addr)
except dbus.exceptions.DBusException:
return None
return self._new_object(buddy_op)
def get_owner(self):
try:
owner_op = self._ps.getOwner()
except dbus.exceptions.DBusException:
return None
return self._new_object(owner_op)
def get_owner(self):
try:
owner_op = self._ps.getOwner()
except dbus.exceptions.DBusException:
return None
return self._new_object(owner_op)
def share_activity(self, activity, stype, properties={}, address=None, port=-1, domain=u"local"):
actid = activity.get_id()
if address == None:
address = u""
serv_op = self._ps.shareActivity(actid, stype, properties, address, port, domain)
return self._new_object(serv_op)
def share_activity(self, activity, stype, properties={}, address=None, port=-1, domain=u"local"):
actid = activity.get_id()
if address == None:
address = u""
serv_op = self._ps.shareActivity(actid, stype, properties, address, port, domain)
return self._new_object(serv_op)
def register_service(self, name, stype, properties={}, address=None, port=-1, domain=u"local"):
if address == None:
address = u""
serv_op = self._ps.registerService(name, stype, properties, address, port, domain)
return self._new_object(serv_op)
def register_service(self, name, stype, properties={}, address=None, port=-1, domain=u"local"):
if address == None:
address = u""
serv_op = self._ps.registerService(name, stype, properties, address, port, domain)
return self._new_object(serv_op)
def unregister_service(self, service):
self._ps.unregisterService(service.object_path())
def unregister_service(self, service):
self._ps.unregisterService(service.object_path())
def register_service_type(self, stype):
self._ps.registerServiceType(stype)
def register_service_type(self, stype):
self._ps.registerServiceType(stype)
def unregister_service_type(self, stype):
self._ps.unregisterServiceType(stype)
def unregister_service_type(self, stype):
self._ps.unregisterServiceType(stype)
_ps = None
def get_instance():
global _ps
if not _ps:
_ps = PresenceService()
return _ps
global _ps
if not _ps:
_ps = PresenceService()
return _ps
def start():
bus = dbus.SessionBus()
ps = dbus.Interface(bus.get_object(DBUS_SERVICE, DBUS_PATH), DBUS_INTERFACE)
ps.start()
bus = dbus.SessionBus()
ps = dbus.Interface(bus.get_object(DBUS_SERVICE, DBUS_PATH), DBUS_INTERFACE)
ps.start()
+77 -77
View File
@@ -20,101 +20,101 @@ import dbus
def _one_dict_differs(dict1, dict2):
diff_keys = []
for key, value in dict1.items():
if not dict2.has_key(key) or dict2[key] != value:
diff_keys.append(key)
return diff_keys
diff_keys = []
for key, value in dict1.items():
if not dict2.has_key(key) or dict2[key] != value:
diff_keys.append(key)
return diff_keys
def _dicts_differ(dict1, dict2):
diff_keys = []
diff1 = _one_dict_differs(dict1, dict2)
diff2 = _one_dict_differs(dict2, dict1)
for key in diff2:
if key not in diff1:
diff_keys.append(key)
diff_keys += diff1
return diff_keys
diff_keys = []
diff1 = _one_dict_differs(dict1, dict2)
diff2 = _one_dict_differs(dict2, dict1)
for key in diff2:
if key not in diff1:
diff_keys.append(key)
diff_keys += diff1
return diff_keys
class Service(gobject.GObject):
_PRESENCE_SERVICE = "org.laptop.Presence"
_SERVICE_DBUS_INTERFACE = "org.laptop.Presence.Service"
_PRESENCE_SERVICE = "org.laptop.Presence"
_SERVICE_DBUS_INTERFACE = "org.laptop.Presence.Service"
__gsignals__ = {
'published-value-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT]))
}
__gsignals__ = {
'published-value-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT]))
}
def __init__(self, bus, new_obj_cb, del_obj_cb, object_path):
gobject.GObject.__init__(self)
self._object_path = object_path
self._ps_new_object = new_obj_cb
self._ps_del_object = del_obj_cb
sobj = bus.get_object(self._PRESENCE_SERVICE, object_path)
self._service = dbus.Interface(sobj, self._SERVICE_DBUS_INTERFACE)
self._service.connect_to_signal('PropertyChanged', self.__property_changed_cb)
self._service.connect_to_signal('PublishedValueChanged',
self.__published_value_changed_cb)
self._props = self._service.getProperties()
self._pubvals = self._service.getPublishedValues()
def __init__(self, bus, new_obj_cb, del_obj_cb, object_path):
gobject.GObject.__init__(self)
self._object_path = object_path
self._ps_new_object = new_obj_cb
self._ps_del_object = del_obj_cb
sobj = bus.get_object(self._PRESENCE_SERVICE, object_path)
self._service = dbus.Interface(sobj, self._SERVICE_DBUS_INTERFACE)
self._service.connect_to_signal('PropertyChanged', self.__property_changed_cb)
self._service.connect_to_signal('PublishedValueChanged',
self.__published_value_changed_cb)
self._props = self._service.getProperties()
self._pubvals = self._service.getPublishedValues()
def object_path(self):
return self._object_path
def object_path(self):
return self._object_path
def __property_changed_cb(self, prop_list):
self._props = self._service.getProperties()
def __property_changed_cb(self, prop_list):
self._props = self._service.getProperties()
def get_published_value(self, key):
return self._pubvals[key]
def get_published_value(self, key):
return self._pubvals[key]
def get_published_values(self):
self._pubvals = self._service.getPublishedValues()
return self._pubvals
def get_published_values(self):
self._pubvals = self._service.getPublishedValues()
return self._pubvals
def set_published_value(self, key, value):
if self._pubvals.has_key(key):
if self._pubvals[key] == value:
return
self._pubvals[key] = value
self._service.setPublishedValue(key, value)
def set_published_value(self, key, value):
if self._pubvals.has_key(key):
if self._pubvals[key] == value:
return
self._pubvals[key] = value
self._service.setPublishedValue(key, value)
def set_published_values(self, vals):
self._service.setPublishedValues(vals)
self._pubvals = vals
def set_published_values(self, vals):
self._service.setPublishedValues(vals)
self._pubvals = vals
def __published_value_changed_cb(self, keys):
oldvals = self._pubvals
self.get_published_values()
diff_keys = _dicts_differ(oldvals, self._pubvals)
if len(diff_keys) > 0:
self.emit('published-value-changed', diff_keys)
def __published_value_changed_cb(self, keys):
oldvals = self._pubvals
self.get_published_values()
diff_keys = _dicts_differ(oldvals, self._pubvals)
if len(diff_keys) > 0:
self.emit('published-value-changed', diff_keys)
def get_name(self):
return self._props['name']
def get_name(self):
return self._props['name']
def get_type(self):
return self._props['type']
def get_type(self):
return self._props['type']
def get_domain(self):
return self._props['domain']
def get_domain(self):
return self._props['domain']
def get_address(self):
if self._props.has_key('address'):
return self._props['address']
return None
def get_address(self):
if self._props.has_key('address'):
return self._props['address']
return None
def get_activity_id(self):
if self._props.has_key('activityId'):
return self._props['activityId']
return None
def get_activity_id(self):
if self._props.has_key('activityId'):
return self._props['activityId']
return None
def get_port(self):
if self._props.has_key('port'):
return self._props['port']
return None
def get_port(self):
if self._props.has_key('port'):
return self._props['port']
return None
def get_source_address(self):
if self._props.has_key('sourceAddress'):
return self._props['sourceAddress']
return None
def get_source_address(self):
if self._props.has_key('sourceAddress'):
return self._props['sourceAddress']
return None
+18 -18
View File
@@ -21,34 +21,34 @@ from sugar import env
from sugar.graphics.iconcolor import IconColor
class _Profile(object):
def __init__(self):
self.name = None
self.color = None
self._load()
def __init__(self):
self.name = None
self.color = None
self._load()
def update(self):
self._load()
def update(self):
self._load()
def _load(self):
cp = ConfigParser()
config_path = os.path.join(env.get_profile_path(), 'config')
parsed = cp.read([config_path])
def _load(self):
cp = ConfigParser()
config_path = os.path.join(env.get_profile_path(), 'config')
parsed = cp.read([config_path])
if cp.has_option('Buddy', 'NickName'):
self.name = cp.get('Buddy', 'NickName')
if cp.has_option('Buddy', 'NickName'):
self.name = cp.get('Buddy', 'NickName')
if cp.has_option('Buddy', 'Color'):
self.color = IconColor(cp.get('Buddy', 'Color'))
if cp.has_option('Buddy', 'Color'):
self.color = IconColor(cp.get('Buddy', 'Color'))
del cp
del cp
def get_nick_name():
return _profile.name
return _profile.name
def get_color():
return _profile.color
return _profile.color
def update():
_profile.update()
_profile.update()
_profile = _Profile()
+108 -108
View File
@@ -33,151 +33,151 @@ _PRESENCE_SERVICE_TYPE = "_presence_olpc._tcp"
_activity_refs = {}
class _NameCollection(object):
def __init__(self):
self._names = copy.copy(_nick_names)
def __init__(self):
self._names = copy.copy(_nick_names)
def get_name(self):
i = random.randint(0, len(self._names))
return self._names.pop(i)
def get_name(self):
i = random.randint(0, len(self._names))
return self._names.pop(i)
class _BotService(object):
def __init__(self, bot):
self._bot = bot
def __init__(self, bot):
self._bot = bot
def announce(self):
props = { 'color': self._bot.color.to_string() }
pservice = PresenceService.get_instance()
self._service = pservice.register_service(self._bot.name,
_PRESENCE_SERVICE_TYPE, properties=props)
def announce(self):
props = { 'color': self._bot.color.to_string() }
pservice = PresenceService.get_instance()
self._service = pservice.register_service(self._bot.name,
_PRESENCE_SERVICE_TYPE, properties=props)
self._stream = Stream.Stream.new_from_service(self._service)
self._stream.register_reader_handler(
self._handle_buddy_icon_request, "get_buddy_icon")
self._stream.register_reader_handler(
self._handle_invite, "invite")
self._stream = Stream.Stream.new_from_service(self._service)
self._stream.register_reader_handler(
self._handle_buddy_icon_request, "get_buddy_icon")
self._stream.register_reader_handler(
self._handle_invite, "invite")
def _handle_buddy_icon_request(self):
if self._bot.icon:
fd = open(self._bot.icon, "r")
icon_data = fd.read()
fd.close()
if icon_data:
return base64.b64encode(self._icon)
return ''
def _handle_buddy_icon_request(self):
if self._bot.icon:
fd = open(self._bot.icon, "r")
icon_data = fd.read()
fd.close()
if icon_data:
return base64.b64encode(self._icon)
return ''
def _handle_invite(self, issuer, bundle_id, activity_id):
return ''
def _handle_invite(self, issuer, bundle_id, activity_id):
return ''
def set_current_activity(self, activity_id):
self._service.set_published_value('curact', dbus.String(activity_id))
def set_current_activity(self, activity_id):
self._service.set_published_value('curact', dbus.String(activity_id))
class _JoinActivityAction(object):
def __init__(self, bot, named_ref):
self._bot = bot
self._named_ref = named_ref
def __init__(self, bot, named_ref):
self._bot = bot
self._named_ref = named_ref
def execute(self):
activity_id = _activity_refs[self._named_ref]
def execute(self):
activity_id = _activity_refs[self._named_ref]
pservice = PresenceService.get_instance()
activity = pservice.get_activity(activity_id)
service = activity.get_services()[0]
pservice = PresenceService.get_instance()
activity = pservice.get_activity(activity_id)
service = activity.get_services()[0]
name = "%s [%s]" % (self._bot.name, activity_id)
properties = { 'title' : service.get_published_value('title'),
'color' : service.get_published_value('color') }
name = "%s [%s]" % (self._bot.name, activity_id)
properties = { 'title' : service.get_published_value('title'),
'color' : service.get_published_value('color') }
pservice.register_service(name, service.get_type(),
properties, service.get_address(),
service.get_port())
pservice.register_service(name, service.get_type(),
properties, service.get_address(),
service.get_port())
self._bot._service.set_current_activity(activity_id)
self._bot._service.set_current_activity(activity_id)
class _ChangeActivityAction(object):
def __init__(self, bot, named_ref):
self._bot = bot
self._named_ref = named_ref
def __init__(self, bot, named_ref):
self._bot = bot
self._named_ref = named_ref
def execute(self):
activity_id = _activity_refs[self._named_ref]
self._bot._service.set_current_activity(activity_id)
def execute(self):
activity_id = _activity_refs[self._named_ref]
self._bot._service.set_current_activity(activity_id)
class _ShareChatAction(object):
def __init__(self, bot, named_ref, title):
self._bot = bot
self._title = title
self._id = util.unique_id()
def __init__(self, bot, named_ref, title):
self._bot = bot
self._title = title
self._id = util.unique_id()
_activity_refs[named_ref] = self._id
_activity_refs[named_ref] = self._id
def execute(self):
name = "%s [%s]" % (self._bot.name, self._id)
stype = '_GroupChatActivity_Sugar_redhat_com._udp'
properties = { 'title' : self._title,
'color' : self._bot.color.to_string() }
address = u"232.%d.%d.%d" % (random.randint(0, 254),
random.randint(1, 254),
random.randint(1, 254))
def execute(self):
name = "%s [%s]" % (self._bot.name, self._id)
stype = '_GroupChatActivity_Sugar_redhat_com._udp'
properties = { 'title' : self._title,
'color' : self._bot.color.to_string() }
address = u"232.%d.%d.%d" % (random.randint(0, 254),
random.randint(1, 254),
random.randint(1, 254))
pservice = PresenceService.get_instance()
pservice.register_service(name, stype, properties, address)
pservice = PresenceService.get_instance()
pservice.register_service(name, stype, properties, address)
class _WaitAction(object):
def __init__(self, bot, seconds):
self._bot = bot
self._seconds = seconds
def execute(self):
self._bot._pause_queue(self._seconds)
def __init__(self, bot, seconds):
self._bot = bot
self._seconds = seconds
def execute(self):
self._bot._pause_queue(self._seconds)
class Bot(object):
_name_collection = _NameCollection()
_name_collection = _NameCollection()
def __init__(self):
self.name = Bot._name_collection.get_name()
self.color = IconColor()
self.icon = None
def __init__(self):
self.name = Bot._name_collection.get_name()
self.color = IconColor()
self.icon = None
self._queue = []
self._queue = []
def wait(self, seconds):
action = _WaitAction(self, seconds)
self._queue.append(action)
def wait(self, seconds):
action = _WaitAction(self, seconds)
self._queue.append(action)
def share_chat(self, activity_id, title):
action = _ShareChatAction(self, activity_id, title)
self._queue.append(action)
def share_chat(self, activity_id, title):
action = _ShareChatAction(self, activity_id, title)
self._queue.append(action)
def change_activity(self, activity_id):
action = _ChangeActivityAction(self, activity_id)
self._queue.append(action)
def change_activity(self, activity_id):
action = _ChangeActivityAction(self, activity_id)
self._queue.append(action)
def join_activity(self, activity_id):
action = _JoinActivityAction(self, activity_id)
self._queue.append(action)
def join_activity(self, activity_id):
action = _JoinActivityAction(self, activity_id)
self._queue.append(action)
def start(self):
self._service = _BotService(self)
self._service.announce()
def start(self):
self._service = _BotService(self)
self._service.announce()
self._start_queue()
self._start_queue()
def _idle_cb(self):
self._next_action()
return True
def _idle_cb(self):
self._next_action()
return True
def _pause_done_cb(self):
self._start_queue()
return False
def _pause_done_cb(self):
self._start_queue()
return False
def _start_queue(self):
self._queue_sid = gobject.idle_add(self._idle_cb)
def _start_queue(self):
self._queue_sid = gobject.idle_add(self._idle_cb)
def _pause_queue(self, seconds):
gobject.source_remove(self._queue_sid)
gobject.timeout_add(int(seconds * 1000), self._pause_done_cb)
def _pause_queue(self, seconds):
gobject.source_remove(self._queue_sid)
gobject.timeout_add(int(seconds * 1000), self._pause_done_cb)
def _next_action(self):
if len(self._queue) > 0:
action = self._queue.pop(0)
action.execute()
def _next_action(self):
if len(self._queue) > 0:
action = self._queue.pop(0)
action.execute()
+31 -31
View File
@@ -25,50 +25,50 @@ from ConfigParser import ConfigParser
from ConfigParser import NoOptionError
def printable_hash(in_hash):
"""Convert binary hash data into printable characters."""
printable = ""
for char in in_hash:
printable = printable + binascii.b2a_hex(char)
return printable
"""Convert binary hash data into printable characters."""
printable = ""
for char in in_hash:
printable = printable + binascii.b2a_hex(char)
return printable
def _sha_data(data):
"""sha1 hash some bytes."""
sha_hash = sha.new()
sha_hash.update(data)
return sha_hash.digest()
"""sha1 hash some bytes."""
sha_hash = sha.new()
sha_hash.update(data)
return sha_hash.digest()
def unique_id(data = ''):
data_string = "%s%s%s" % (time.time(), random.randint(10000, 100000), data)
return printable_hash(_sha_data(data_string))
data_string = "%s%s%s" % (time.time(), random.randint(10000, 100000), data)
return printable_hash(_sha_data(data_string))
ACTIVITY_ID_LEN = 40
def is_hex(s):
return s.strip(string.hexdigits) == ''
return s.strip(string.hexdigits) == ''
def validate_activity_id(actid):
"""Validate an activity ID."""
if not isinstance(actid, str) and not isinstance(actid, unicode):
return False
if len(actid) != ACTIVITY_ID_LEN:
return False
if not is_hex(actid):
return False
return True
"""Validate an activity ID."""
if not isinstance(actid, str) and not isinstance(actid, unicode):
return False
if len(actid) != ACTIVITY_ID_LEN:
return False
if not is_hex(actid):
return False
return True
class _ServiceParser(ConfigParser):
def optionxform(self, option):
return option
def optionxform(self, option):
return option
def write_service(name, bin, path):
service_cp = _ServiceParser()
section = 'D-BUS Service'
service_cp.add_section(section)
service_cp.set(section, 'Name', name)
service_cp.set(section, 'Exec', bin)
service_cp = _ServiceParser()
section = 'D-BUS Service'
service_cp.add_section(section)
service_cp.set(section, 'Name', name)
service_cp.set(section, 'Exec', bin)
dest_filename = os.path.join(path, name + '.service')
fileobject = open(dest_filename, 'w')
service_cp.write(fileobject)
fileobject.close()
dest_filename = os.path.join(path, name + '.service')
fileobject = open(dest_filename, 'w')
service_cp.write(fileobject)
fileobject.close()