diff --git a/configure.ac b/configure.ac index 70685674..98cdefb7 100644 --- a/configure.ac +++ b/configure.ac @@ -73,7 +73,6 @@ sugar/chat/sketchpad/Makefile sugar/graphics/Makefile sugar/p2p/Makefile sugar/presence/Makefile -sugar/session/Makefile po/Makefile.in tools/Makefile tools/sugar-setup-activity diff --git a/services/presence/Buddy.py b/services/presence/Buddy.py index 089f2b75..a98982ef 100644 --- a/services/presence/Buddy.py +++ b/services/presence/Buddy.py @@ -19,7 +19,7 @@ import logging import gobject import dbus, dbus.service -from sugar import env +from sugar import profile PRESENCE_SERVICE_TYPE = "_presence_olpc._tcp" @@ -416,8 +416,8 @@ class Owner(Buddy): portion of the Owner, paired with the server portion in Owner.py.""" def __init__(self, ps, bus_name, object_id, icon_cache): Buddy.__init__(self, bus_name, object_id, None, icon_cache) - self._nick_name = env.get_nick_name() - self._color = env.get_color() + self._nick_name = profile.get_nick_name() + self._color = profile.get_color() self._ps = ps def add_service(self, service): diff --git a/services/presence/PresenceService.py b/services/presence/PresenceService.py index 72404b31..f591ccda 100644 --- a/services/presence/PresenceService.py +++ b/services/presence/PresenceService.py @@ -22,6 +22,7 @@ import random import logging from sugar import util from sugar import env +from sugar import profile import BuddyIconCache @@ -293,6 +294,7 @@ class PresenceServiceDBusHelper(dbus.service.Object): class PresenceService(object): def __init__(self): # interface -> IP address: interfaces we've gotten events on so far + self._started = False self._local_addrs = {} self._next_object_id = 0 @@ -319,7 +321,7 @@ class PresenceService(object): self._icon_cache = BuddyIconCache.BuddyIconCache() # Our owner object - if env.get_nick_name(): + if profile.get_nick_name(): objid = self._get_next_object_id() self._owner = Buddy.Owner(self, self._bus_name, objid, self._icon_cache) @@ -327,8 +329,6 @@ class PresenceService(object): else: self._owner = None - self._started = False - def start(self): if self._started: return diff --git a/shell/Makefile.am b/shell/Makefile.am index a4fd7192..28b76742 100644 --- a/shell/Makefile.am +++ b/shell/Makefile.am @@ -1,7 +1,7 @@ SUBDIRS = conf data model view bin_SCRIPTS = \ - sugar \ + sugar-shell \ sugar-activity \ sugar-activity-factory \ sugar-console diff --git a/shell/conf/Profile.py b/shell/conf/Profile.py deleted file mode 100644 index f81831fd..00000000 --- a/shell/conf/Profile.py +++ /dev/null @@ -1,76 +0,0 @@ -# Copyright (C) 2006, Red Hat, Inc. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -import os -from ConfigParser import ConfigParser - -from sugar.graphics import iconcolor -from sugar import env - -class _Profile: - def __init__(self,): - self._path = env.get_profile_path() - self._nick_name = None - self._color = iconcolor.IconColor() - - self._ensure_dirs() - - cp = ConfigParser() - parsed = cp.read([self._get_config_path()]) - - if cp.has_option('Buddy', 'NickName'): - self._nick_name = cp.get('Buddy', 'NickName') - if cp.has_option('Buddy', 'Color'): - color = cp.get('Buddy', 'Color') - if iconcolor.is_valid(color): - self._color = iconcolor.IconColor(color) - - def _ensure_dirs(self): - try: - os.makedirs(self._path) - except OSError, exc: - if exc[0] != 17: # file exists - print "Could not create user directory." - - def get_color(self): - return self._color - - def set_color(self, color): - self._color = color - - def get_nick_name(self): - return self._nick_name - - def set_nick_name(self, nick_name): - self._nick_name = nick_name - - def get_path(self): - return self._path - - def save(self): - cp = ConfigParser() - - section = 'Buddy' - cp.add_section(section) - cp.set(section, 'NickName', self._nick_name) - cp.set(section, 'Color', self._color.to_string()) - - fileobject = open(self._get_config_path(), 'w') - cp.write(fileobject) - fileobject.close() - - def _get_config_path(self): - return os.path.join(self._path, 'config') diff --git a/shell/conf/__init__.py b/shell/conf/__init__.py index f69dccbd..8842daca 100644 --- a/shell/conf/__init__.py +++ b/shell/conf/__init__.py @@ -1,11 +1,6 @@ from conf.ActivityRegistry import _ActivityRegistry -from conf.Profile import _Profile -__registry = _ActivityRegistry() -__profile = _Profile() +_activity_registry = _ActivityRegistry() def get_activity_registry(): - return __registry - -def get_profile(): - return __profile + return _activity_registry diff --git a/shell/model/Owner.py b/shell/model/Owner.py index 0382e3c9..7d83ab2f 100644 --- a/shell/model/Owner.py +++ b/shell/model/Owner.py @@ -18,15 +18,15 @@ import os import random import base64 import time - -import conf -from sugar import env import logging +import dbus + +from sugar import env +from sugar import profile from sugar.p2p import Stream from sugar.presence import PresenceService from sugar import util from model.Invites import Invites -import dbus PRESENCE_SERVICE_TYPE = "_presence_olpc._tcp" @@ -35,10 +35,8 @@ class ShellOwner(object): runs in the shell and serves up the buddy icon and other stuff. It's the server portion of the Owner, paired with the client portion in Buddy.py.""" def __init__(self): - profile = conf.get_profile() - self._nick = profile.get_nick_name() - user_dir = profile.get_path() + user_dir = env.get_profile_path() self._icon = None self._icon_hash = "" @@ -71,7 +69,7 @@ class ShellOwner(object): def announce(self): # Create and announce our presence - color = conf.get_profile().get_color() + color = profile.get_color() props = {'color': color.to_string(), 'icon-hash': self._icon_hash} self._service = self._pservice.register_service(self._nick, PRESENCE_SERVICE_TYPE, properties=props) diff --git a/shell/sugar b/shell/sugar-shell similarity index 57% rename from shell/sugar rename to shell/sugar-shell index a47bfc72..95deb405 100755 --- a/shell/sugar +++ b/shell/sugar-shell @@ -16,33 +16,27 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -import sys -import os - import pygtk pygtk.require('2.0') +import gtk -curdir = os.path.abspath(os.path.dirname(__file__)) -sourcedir = os.path.dirname(curdir) +from sugar import profile +from sugar import TracebackUtils +from view.FirstTimeDialog import FirstTimeDialog +from view.Shell import Shell +from model.ShellModel import ShellModel -if os.path.isfile(os.path.join(sourcedir, 'sugar/__uninstalled__.py')): - print 'Running sugar from ' + sourcedir + ' ...' - sys.path.insert(0, sourcedir) -else: - print 'Running the installed sugar...' +name = profile.get_nick_name() +if not name or not len(name): + dialog = FirstTimeDialog() + dialog.run() -from sugar import env +model = ShellModel() +shell = Shell(model) -env.setup_system() - -from sugar.session.Emulator import Emulator - -if os.environ.has_key('SUGAR_EMULATOR') and \ - os.environ['SUGAR_EMULATOR'] == 'yes': - emulator = Emulator() - emulator.start() - -from Session import Session - -session = Session() -session.start() +tbh = TracebackUtils.TracebackHelper() +try: + gtk.main() +except KeyboardInterrupt: + print 'Ctrl+C pressed, exiting...' +del tbh diff --git a/shell/view/ActivityHost.py b/shell/view/ActivityHost.py index fe8bc197..4074de22 100644 --- a/shell/view/ActivityHost.py +++ b/shell/view/ActivityHost.py @@ -18,6 +18,7 @@ import gtk import dbus import conf +from sugar import profile from sugar.activity import Activity from sugar.presence import PresenceService from sugar.graphics.iconcolor import IconColor @@ -92,7 +93,7 @@ class ActivityHost: if activity != None: return IconColor(activity.get_color()) else: - return conf.get_profile().get_color() + return profile.get_color() def share(self): self._activity.share() diff --git a/shell/view/FirstTimeDialog.py b/shell/view/FirstTimeDialog.py index 5e878f90..463114a4 100644 --- a/shell/view/FirstTimeDialog.py +++ b/shell/view/FirstTimeDialog.py @@ -14,11 +14,14 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -import gtk +import os +from ConfigParser import ConfigParser +import gtk from gettext import gettext as _ -import conf +from sugar.graphics.iconcolor import IconColor +from sugar import env class FirstTimeDialog(gtk.Dialog): def __init__(self): @@ -37,22 +40,24 @@ class FirstTimeDialog(gtk.Dialog): self._ok = gtk.Button(None, gtk.STOCK_OK) self._ok.set_sensitive(False) self.vbox.pack_start(self._ok) - self._ok.connect('clicked', self.__ok_button_clicked_cb) + self._ok.connect('clicked', self._ok_button_clicked_cb) self._ok.show() def _entry_changed_cb(self, entry): valid = (len(entry.get_text()) > 0) self._ok.set_sensitive(valid) - def __ok_button_clicked_cb(self, button): - profile = conf.get_profile() - profile.set_nick_name(self._entry.get_text()) - self.destroy() + def _ok_button_clicked_cb(self, button): + cp = ConfigParser() -def get_profile(): - profile = conf.get_profile() - if profile.get_nick_name() == None: - dialog = FirstTimeDialog() - dialog.connect('destroy', self.__first_time_dialog_destroy_cb) - dialog.show() - return profile + section = 'Buddy' + cp.add_section(section) + cp.set(section, 'NickName', self._entry.get_text()) + cp.set(section, 'Color', IconColor().to_string()) + + config_path = os.path.join(env.get_profile_path(), 'config') + fileobject = open(config_path, 'w') + cp.write(fileobject) + fileobject.close() + + self.destroy() diff --git a/shell/view/home/MyIcon.py b/shell/view/home/MyIcon.py index 8da16923..df59317e 100644 --- a/shell/view/home/MyIcon.py +++ b/shell/view/home/MyIcon.py @@ -15,10 +15,9 @@ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA from sugar.graphics.canvasicon import CanvasIcon -import conf +from sugar import profile class MyIcon(CanvasIcon): def __init__(self): - profile = conf.get_profile() CanvasIcon.__init__(self, icon_name='stock-buddy', color=profile.get_color()) diff --git a/sugar/Makefile.am b/sugar/Makefile.am index 6f27a08d..7e2b0d29 100644 --- a/sugar/Makefile.am +++ b/sugar/Makefile.am @@ -1,9 +1,10 @@ -SUBDIRS = activity chat graphics p2p presence session +SUBDIRS = activity chat graphics p2p presence sugardir = $(pythondir)/sugar sugar_PYTHON = \ __init__.py \ __installed__.py \ + emulator.py \ env.py \ logger.py \ setup.py \ diff --git a/sugar/env.py b/sugar/env.py index 2d757375..a2dfa457 100644 --- a/sugar/env.py +++ b/sugar/env.py @@ -26,25 +26,8 @@ except ImportError: import sugar.setup -def setup_user(profile): - os.environ['SUGAR_NICK_NAME'] = profile.get_nick_name() - os.environ['SUGAR_COLOR'] = profile.get_color().to_string() - -def get_nick_name(): - if os.environ.has_key('SUGAR_NICK_NAME'): - return os.environ['SUGAR_NICK_NAME'] - else: - return None - -def get_color(): - if os.environ.has_key('SUGAR_COLOR'): - return os.environ['SUGAR_COLOR'] - else: - return None - def setup_python_path(): for path in sugar_python_path: - sys.path.insert(0, path) if os.environ.has_key('PYTHONPATH'): old_path = os.environ['PYTHONPATH'] os.environ['PYTHONPATH'] = path + ':' + old_path @@ -76,9 +59,15 @@ def get_profile_path(): profile_id = os.environ['SUGAR_PROFILE'] else: profile_id = 'default' - path = os.path.expanduser('~/.sugar') - return os.path.join(path, profile_id) + 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 def get_data_dir(): return sugar_data_dir diff --git a/sugar/profile.py b/sugar/profile.py new file mode 100644 index 00000000..12eb08be --- /dev/null +++ b/sugar/profile.py @@ -0,0 +1,43 @@ +# Copyright (C) 2006, Red Hat, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +import os +from ConfigParser import ConfigParser + +from sugar import env +from sugar.graphics.iconcolor import IconColor + +def get_nick_name(): + return _nick_name + +def get_color(): + return _color + +cp = ConfigParser() +config_path = os.path.join(env.get_profile_path(), 'config') +parsed = cp.read([config_path]) + +if cp.has_option('Buddy', 'NickName'): + _nick_name = cp.get('Buddy', 'NickName') +else: + _nick_name = None + +if cp.has_option('Buddy', 'Color'): + _color = IconColor(cp.get('Buddy', 'Color')) +else: + _color = None + +del cp diff --git a/sugar/session/DbusProcess.py b/sugar/session/DbusProcess.py deleted file mode 100644 index fb3246e8..00000000 --- a/sugar/session/DbusProcess.py +++ /dev/null @@ -1,37 +0,0 @@ -# Copyright (C) 2006, Red Hat, Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., 59 Temple Place - Suite 330, -# Boston, MA 02111-1307, USA. - -import os - -from sugar.session.Process import Process -from sugar import env - -class DbusProcess(Process): - def __init__(self): - config = env.get_dbus_config() - cmd = "dbus-daemon --print-address --config-file %s" % config - Process.__init__(self, cmd) - - def get_name(self): - return 'Dbus' - - def start(self): - Process.start(self, True) - dbus_file = os.fdopen(self._stdout) - addr = dbus_file.readline().strip() - dbus_file.close() - os.environ["DBUS_SESSION_BUS_ADDRESS"] = addr diff --git a/sugar/session/Emulator.py b/sugar/session/Emulator.py deleted file mode 100644 index 44685095..00000000 --- a/sugar/session/Emulator.py +++ /dev/null @@ -1,87 +0,0 @@ -# Copyright (C) 2006, Red Hat, Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., 59 Temple Place - Suite 330, -# Boston, MA 02111-1307, USA. - -import os -import socket -import sys - -from sugar.session.Process import Process -import sugar.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 - - 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 - - if display_is_free: - return display_number - else: - logging.error('Cannot find a free display.') - sys.exit(0) - -class XephyrProcess(Process): - def __init__(self): - self._display = get_display_number() - cmd = 'Xephyr :%d -ac -screen 800x600' % (self._display) - Process.__init__(self, cmd) - - def get_name(self): - return 'Xephyr' - - def start(self): - Process.start(self) - os.environ['DISPLAY'] = ":%d" % (self._display) - -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 start(self): - Process.start(self) - os.environ['DISPLAY'] = ":%d" % (self._display) - -class Emulator: - """The OLPC emulator""" - def start(self): - try: - process = XephyrProcess() - process.start() - except: - try: - process = XnestProcess() - process.start() - except: - print 'Cannot run the emulator. You need to install \ - Xephyr or Xnest.' - sys.exit(0) diff --git a/sugar/session/Makefile.am b/sugar/session/Makefile.am deleted file mode 100644 index 8c1e4f71..00000000 --- a/sugar/session/Makefile.am +++ /dev/null @@ -1,9 +0,0 @@ -sugardir = $(pythondir)/sugar/session -sugar_PYTHON = \ - __init__.py \ - DbusProcess.py \ - Emulator.py \ - MatchboxProcess.py \ - Process.py \ - TestSession.py \ - UITestSession.py diff --git a/sugar/session/MatchboxProcess.py b/sugar/session/MatchboxProcess.py deleted file mode 100644 index b6a7e35e..00000000 --- a/sugar/session/MatchboxProcess.py +++ /dev/null @@ -1,35 +0,0 @@ -# Copyright (C) 2006, Red Hat, Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., 59 Temple Place - Suite 330, -# Boston, MA 02111-1307, USA. - -import os - -from sugar.session.Process import Process -from sugar import env - -class MatchboxProcess(Process): - 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 ' - - command = 'matchbox-window-manager %s ' % options - Process.__init__(self, command) - - def get_name(self): - return 'Matchbox' diff --git a/sugar/session/Process.py b/sugar/session/Process.py deleted file mode 100644 index 80bed1ae..00000000 --- a/sugar/session/Process.py +++ /dev/null @@ -1,36 +0,0 @@ -# Copyright (C) 2006, Red Hat, Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., 59 Temple Place - Suite 330, -# Boston, MA 02111-1307, USA. - -import logging - -import gobject - -class Process: - """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._stdout = result[2] diff --git a/sugar/session/TestSession.py b/sugar/session/TestSession.py deleted file mode 100644 index 23815482..00000000 --- a/sugar/session/TestSession.py +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright (C) 2006, Red Hat, Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., 59 Temple Place - Suite 330, -# Boston, MA 02111-1307, USA. - -from sugar.session.DbusProcess import DbusProcess -from sugar import env - -class TestSession: - def start(self): - env.setup_python_path() - - process = DbusProcess() - process.start() diff --git a/sugar/session/UITestSession.py b/sugar/session/UITestSession.py deleted file mode 100644 index 1daf9d0a..00000000 --- a/sugar/session/UITestSession.py +++ /dev/null @@ -1,38 +0,0 @@ -# Copyright (C) 2006, Red Hat, Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., 59 Temple Place - Suite 330, -# Boston, MA 02111-1307, USA. - -import os - -from sugar.session.DbusProcess import DbusProcess -from sugar.session.MatchboxProcess import MatchboxProcess -from sugar.session.Emulator import Emulator -from sugar import env - -class UITestSession: - def start(self): - env.setup_python_path() - - if os.environ.has_key('SUGAR_EMULATOR') and \ - os.environ['SUGAR_EMULATOR'] == 'yes': - emulator = Emulator() - emulator.start() - - process = MatchboxProcess() - process.start() - - process = DbusProcess() - process.start() diff --git a/sugar/session/__init__.py b/sugar/session/__init__.py deleted file mode 100644 index e69de29b..00000000