Refactor startup. In progress, give me a couple hours.

For now start sugar with "sugar-emulator shell/sugar-shell"
This commit is contained in:
Marco Pesenti Gritti 2006-10-16 13:34:43 +02:00
parent a3be4492b2
commit bc0ee6d34c
22 changed files with 108 additions and 428 deletions

View File

@ -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

View File

@ -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):

View File

@ -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

View File

@ -1,7 +1,7 @@
SUBDIRS = conf data model view
bin_SCRIPTS = \
sugar \
sugar-shell \
sugar-activity \
sugar-activity-factory \
sugar-console

View File

@ -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')

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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()

View File

@ -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()

View File

@ -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())

View File

@ -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 \

View File

@ -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

43
sugar/profile.py Normal file
View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -1,9 +0,0 @@
sugardir = $(pythondir)/sugar/session
sugar_PYTHON = \
__init__.py \
DbusProcess.py \
Emulator.py \
MatchboxProcess.py \
Process.py \
TestSession.py \
UITestSession.py

View File

@ -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'

View File

@ -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]

View File

@ -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()

View File

@ -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()