diff --git a/bin/sugar-activity b/bin/sugar-activity old mode 100644 new mode 100755 index ccca503a..12809b10 --- a/bin/sugar-activity +++ b/bin/sugar-activity @@ -35,8 +35,10 @@ DBusGMainLoop(set_as_default=True) from sugar3.activity import activityhandle from sugar3 import config from sugar3.bundle.activitybundle import ActivityBundle +from sugar3.activity.activityfactory import get_environment from sugar3 import logger +from sugar3.bundle.bundle import MalformedBundleException def create_activity_instance(constructor, handle): activity = constructor(handle) @@ -69,7 +71,13 @@ class SingleProcess(dbus.service.Object): def main(): - parser = OptionParser() + usage = 'usage: %prog [options] [activity dir] [python class]' + epilog = 'If you are running from a directory containing an Activity, ' \ + 'the argument may be ommitted. Otherwise please provide either '\ + 'a directory containing a Sugar Activity [activity dir], a '\ + '[python_class], or both.' + + parser = OptionParser(usage=usage, epilog=epilog) parser.add_option('-b', '--bundle-id', dest='bundle_id', help='identifier of the activity bundle') parser.add_option('-a', '--activity-id', dest='activity_id', @@ -89,18 +97,34 @@ def main(): logger.start() - if 'SUGAR_BUNDLE_PATH' not in os.environ: - print 'SUGAR_BUNDLE_PATH is not defined in the environment.' - sys.exit(1) + activity_class = None + if len(args) == 2: + activity_class = args[1] + os.chdir(args[0]) + elif len(args) == 1: + if os.path.isdir(args[0]): + os.chdir(args[0]) + else: + activity_class = args[0] - if len(args) == 0: - print 'A python class must be specified as first argument.' - sys.exit(1) + os.environ['SUGAR_BUNDLE_PATH'] = os.path.abspath(os.curdir) bundle_path = os.environ['SUGAR_BUNDLE_PATH'] sys.path.append(bundle_path) - bundle = ActivityBundle(bundle_path) + try: + bundle = ActivityBundle(bundle_path) + except MalformedBundleException: + parser.print_help() + exit(0) + + if not activity_class: + if bundle.get_command().startswith('sugar-activity'): + print 'Guessing python class from activity.info!' + activity_class = bundle.get_command().split(" ")[1] + + if 'SUGAR_VERSION' not in os.environ: + environ = get_environment(bundle) os.environ['SUGAR_BUNDLE_ID'] = bundle.get_bundle_id() os.environ['SUGAR_BUNDLE_NAME'] = bundle.get_name() @@ -114,7 +138,7 @@ def main(): gettext.bindtextdomain('sugar-toolkit-gtk3', config.locale_path) gettext.textdomain(bundle.get_bundle_id()) - splitted_module = args[0].rsplit('.', 1) + splitted_module = activity_class.rsplit('.', 1) module_name = splitted_module[0] class_name = splitted_module[1] @@ -123,6 +147,11 @@ def main(): module = getattr(module, comp) activity_constructor = getattr(module, class_name) + + if not options.activity_id: + options.activity_id = bundle.get_name() + options.bundle_id = bundle.get_bundle_id() + activity_handle = activityhandle.ActivityHandle( activity_id=options.activity_id, object_id=options.object_id, uri=options.uri, diff --git a/src/sugar3/activity/activity.py b/src/sugar3/activity/activity.py index 9d68880e..2d2d5377 100644 --- a/src/sugar3/activity/activity.py +++ b/src/sugar3/activity/activity.py @@ -67,7 +67,6 @@ import json from gi.repository import Gtk from gi.repository import Gdk from gi.repository import GObject -from gi.repository import Gio import dbus import dbus.service from dbus import PROPERTIES_IFACE @@ -81,6 +80,7 @@ from telepathy.constants import CONNECTION_HANDLE_TYPE_ROOM from sugar3 import util from sugar3 import power +from sugar3.profile import get_nick_name, get_color from sugar3.presence import presenceservice from sugar3.activity.activityservice import ActivityService from sugar3.graphics import style @@ -90,6 +90,9 @@ from sugar3.graphics.icon import Icon from sugar3.datastore import datastore from sugar3.bundle.activitybundle import get_bundle_instance from sugar3.bundle.helpers import bundle_from_dir +from sugar3 import env +from errno import EEXIST + from gi.repository import SugarExt _ = lambda msg: gettext.dgettext('sugar-toolkit-gtk3', msg) @@ -436,13 +439,18 @@ class Activity(Window, Gtk.Container): self.__jobject_updated_cb) self.set_title(self._jobject.metadata['title']) + if 'SUGAR_VERSION' not in os.environ: + bundle = get_bundle_instance(get_bundle_path()) + self.set_icon_from_file(bundle.get_icon()) + + def run_main_loop(self): Gtk.main() def _initialize_journal_object(self): title = _('%s Activity') % get_bundle_name() - settings = Gio.Settings('org.sugarlabs.user') - icon_color = settings.get_string('color') + + icon_color = get_color().to_string() jobject = datastore.create() jobject.metadata['title'] = title @@ -613,11 +621,12 @@ class Activity(Window, Gtk.Container): def _adapt_window_to_screen(self): screen = Gdk.Screen.get_default() + workarea = screen.get_monitor_workarea(screen.get_number()) geometry = Gdk.Geometry() geometry.max_width = geometry.base_width = geometry.min_width = \ - screen.get_width() + workarea.width geometry.max_height = geometry.base_height = geometry.min_height = \ - screen.get_height() + workarea.height geometry.width_inc = geometry.height_inc = geometry.min_aspect = \ geometry.max_aspect = 1 hints = Gdk.WindowHints(Gdk.WindowHints.ASPECT | @@ -671,7 +680,7 @@ class Activity(Window, Gtk.Container): if os.environ.get('SUGAR_ACTIVITY_ROOT'): return os.environ['SUGAR_ACTIVITY_ROOT'] else: - return '/' + return get_activity_root() def read_file(self, file_path): ''' @@ -876,7 +885,7 @@ class Activity(Window, Gtk.Container): if not self.metadata.get('activity_id', ''): self.metadata['activity_id'] = self.get_id() - file_path = os.path.join(self.get_activity_root(), 'instance', + file_path = os.path.join(get_activity_root(), 'instance', '%i' % time.time()) try: self.write_file(file_path) @@ -1251,7 +1260,13 @@ def get_activity_root(): if os.environ.get('SUGAR_ACTIVITY_ROOT'): return os.environ['SUGAR_ACTIVITY_ROOT'] else: - raise RuntimeError('No SUGAR_ACTIVITY_ROOT set.') + activity_root = env.get_profile_path(os.environ['SUGAR_BUNDLE_ID']) + try: + os.mkdir(activity_root) + except OSError, e: + if e.errno != EEXIST: + raise e + return activity_root def show_object_in_journal(object_id): diff --git a/src/sugar3/datastore/datastore.py b/src/sugar3/datastore/datastore.py index 38012642..52744065 100644 --- a/src/sugar3/datastore/datastore.py +++ b/src/sugar3/datastore/datastore.py @@ -32,6 +32,7 @@ import dbus from sugar3 import env from sugar3 import mime from sugar3 import dispatch +from sugar3.profile import get_color DS_DBUS_SERVICE = 'org.laptop.sugar.DataStore' DS_DBUS_INTERFACE = 'org.laptop.sugar.DataStore' @@ -222,7 +223,6 @@ class RawObject(object): def __init__(self, file_path): stat = os.stat(file_path) - settings = Gio.Settings('org.sugarlabs.user') metadata = { 'uid': file_path, 'title': os.path.basename(file_path), @@ -230,7 +230,7 @@ class RawObject(object): 'mime_type': Gio.content_type_guess(file_path, None)[0], 'activity': '', 'activity_id': '', - 'icon-color': settings.get_string('color'), + 'icon-color': get_color().to_string(), 'description': file_path, } diff --git a/src/sugar3/graphics/style.py b/src/sugar3/graphics/style.py index d8d85898..8af2968e 100644 --- a/src/sugar3/graphics/style.py +++ b/src/sugar3/graphics/style.py @@ -116,9 +116,13 @@ MEDIUM_ICON_SIZE = zoom(55 * 1.5) LARGE_ICON_SIZE = zoom(55 * 2.0) XLARGE_ICON_SIZE = zoom(55 * 2.75) -settings = Gio.Settings('org.sugarlabs.font') -FONT_SIZE = settings.get_double('default-size') -FONT_FACE = settings.get_string('default-face') +if 'org.sugarlabs.font' in Gio.Settings.list_schemas(): + settings = Gio.Settings('org.sugarlabs.font') + FONT_SIZE = settings.get_double('default-size') + FONT_FACE = settings.get_string('default-face') +else: + FONT_SIZE = 10 + FONT_FACE = 'Sans Serif' FONT_NORMAL = Font('%s %f' % (FONT_FACE, FONT_SIZE)) FONT_BOLD = Font('%s bold %f' % (FONT_FACE, FONT_SIZE)) diff --git a/src/sugar3/graphics/xocolor.py b/src/sugar3/graphics/xocolor.py index 2c4ef033..4c6e33a8 100644 --- a/src/sugar3/graphics/xocolor.py +++ b/src/sugar3/graphics/xocolor.py @@ -244,8 +244,9 @@ class XoColor: parsed_color = None if color_string is None: - settings = Gio.Settings('org.sugarlabs.user') - color_string = settings.get_string('color') + if 'org.sugarlabs.user' in Gio.Settings.list_schemas(): + settings = Gio.Settings('org.sugarlabs.user') + color_string = settings.get_string('color') if color_string is not None: parsed_color = _parse_string(color_string) diff --git a/src/sugar3/presence/buddy.py b/src/sugar3/presence/buddy.py index 46051625..2533a3d5 100644 --- a/src/sugar3/presence/buddy.py +++ b/src/sugar3/presence/buddy.py @@ -24,7 +24,6 @@ STABLE. import logging from gi.repository import GObject -from gi.repository import Gio import dbus from telepathy.interfaces import CONNECTION, \ CONNECTION_INTERFACE_ALIASING, \ @@ -32,6 +31,7 @@ from telepathy.interfaces import CONNECTION, \ from telepathy.constants import HANDLE_TYPE_CONTACT from sugar3.presence.connectionmanager import get_connection_manager +from sugar3.profile import get_color, get_nick_name ACCOUNT_MANAGER_SERVICE = 'org.freedesktop.Telepathy.AccountManager' CONN_INTERFACE_BUDDY_INFO = 'org.laptop.Telepathy.BuddyInfo' @@ -243,6 +243,6 @@ class Owner(BaseBuddy): def __init__(self): BaseBuddy.__init__(self) - settings = Gio.Settings('org.sugarlabs.user') - self.props.nick = settings.get_string('nick') - self.props.color = settings.get_string('color') + self.props.nick = get_nick_name() + self.props.color = get_color().to_string() + diff --git a/src/sugar3/profile.py b/src/sugar3/profile.py index 950b5f8c..d7f92e7d 100644 --- a/src/sugar3/profile.py +++ b/src/sugar3/profile.py @@ -27,6 +27,7 @@ from sugar3 import env from sugar3 import util from sugar3.graphics.xocolor import XoColor +import getpass _profile = None @@ -62,9 +63,8 @@ class Profile(object): privkey_hash = property(fget=_get_privkey_hash) def is_valid(self): - settings = Gio.Settings('org.sugarlabs.user') - nick = settings.get_string('nick') - color = settings.get_string('color') + nick = get_nick_name() + color = get_color() return nick is not '' and \ color is not '' and \ @@ -204,14 +204,20 @@ def get_profile(): def get_nick_name(): - settings = Gio.Settings('org.sugarlabs.user') - return settings.get_string('nick') + if 'org.sugarlabs.user' in Gio.Settings.list_schemas(): + settings = Gio.Settings('org.sugarlabs.user') + return settings.get_string('nick') + else: + return getpass.getuser() def get_color(): - settings = Gio.Settings('org.sugarlabs.user') - color = settings.get_string('color') - return XoColor(color) + if 'org.sugarlabs.user' in Gio.Settings.list_schemas(): + settings = Gio.Settings('org.sugarlabs.user') + color = settings.get_string('color') + return XoColor(color) + else: + return XoColor() def get_pubkey():