Merge branch 'master' of git://dev.laptop.org/sugar-toolkit

This commit is contained in:
Eben Eliason 2008-08-15 05:32:14 -04:00
commit a73cbc351d
24 changed files with 297 additions and 477 deletions

View File

@ -10,6 +10,8 @@ AM_INIT_AUTOMAKE([1.9 foreign dist-bzip2 no-dist-gzip])
AC_DISABLE_STATIC
AC_PROG_LIBTOOL
GNOME_COMPILE_WARNINGS(maximum)
AC_PATH_PROG([GLIB_GENMARSHAL], [glib-genmarshal])
AM_PATH_PYTHON
@ -17,7 +19,7 @@ AM_CHECK_PYTHON_HEADERS(,[AC_MSG_ERROR(could not find Python headers)])
AC_PATH_PROG(PYGTK_CODEGEN, pygtk-codegen-2.0, no)
PKG_CHECK_MODULES(EXT, pygtk-2.0 gtk+-2.0)
PKG_CHECK_MODULES(EXT, pygtk-2.0 gtk+-2.0, sm, ice)
PYGTK_DEFSDIR=`$PKG_CONFIG --variable=defsdir pygtk-2.0`
AC_SUBST(PYGTK_DEFSDIR)

141
m4/gnome-compiler-flags.m4 Normal file
View File

@ -0,0 +1,141 @@
dnl GNOME_COMPILE_WARNINGS
dnl Turn on many useful compiler warnings
dnl For now, only works on GCC
AC_DEFUN([GNOME_COMPILE_WARNINGS],[
dnl ******************************
dnl More compiler warnings
dnl ******************************
AC_ARG_ENABLE(compile-warnings,
AC_HELP_STRING([--enable-compile-warnings=@<:@no/minimum/yes/maximum/error@:>@],
[Turn on compiler warnings]),,
[enable_compile_warnings="m4_default([$1],[yes])"])
warnCFLAGS=
if test "x$GCC" != xyes; then
enable_compile_warnings=no
fi
warning_flags=
realsave_CFLAGS="$CFLAGS"
case "$enable_compile_warnings" in
no)
warning_flags=
;;
minimum)
warning_flags="-Wall"
;;
yes)
warning_flags="-Wall -Wmissing-prototypes"
;;
maximum|error)
warning_flags="-Wall -Wmissing-prototypes -Wnested-externs -Wpointer-arith"
CFLAGS="$warning_flags $CFLAGS"
for option in -Wno-sign-compare; do
SAVE_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $option"
AC_MSG_CHECKING([whether gcc understands $option])
AC_TRY_COMPILE([], [],
has_option=yes,
has_option=no,)
CFLAGS="$SAVE_CFLAGS"
AC_MSG_RESULT($has_option)
if test $has_option = yes; then
warning_flags="$warning_flags $option"
fi
unset has_option
unset SAVE_CFLAGS
done
unset option
if test "$enable_compile_warnings" = "error" ; then
warning_flags="$warning_flags -Werror"
fi
;;
*)
AC_MSG_ERROR(Unknown argument '$enable_compile_warnings' to --enable-compile-warnings)
;;
esac
CFLAGS="$realsave_CFLAGS"
AC_MSG_CHECKING(what warning flags to pass to the C compiler)
AC_MSG_RESULT($warning_flags)
AC_ARG_ENABLE(iso-c,
AC_HELP_STRING([--enable-iso-c],
[Try to warn if code is not ISO C ]),,
[enable_iso_c=no])
AC_MSG_CHECKING(what language compliance flags to pass to the C compiler)
complCFLAGS=
if test "x$enable_iso_c" != "xno"; then
if test "x$GCC" = "xyes"; then
case " $CFLAGS " in
*[\ \ ]-ansi[\ \ ]*) ;;
*) complCFLAGS="$complCFLAGS -ansi" ;;
esac
case " $CFLAGS " in
*[\ \ ]-pedantic[\ \ ]*) ;;
*) complCFLAGS="$complCFLAGS -pedantic" ;;
esac
fi
fi
AC_MSG_RESULT($complCFLAGS)
WARN_CFLAGS="$warning_flags $complCFLAGS"
AC_SUBST(WARN_CFLAGS)
])
dnl For C++, do basically the same thing.
AC_DEFUN([GNOME_CXX_WARNINGS],[
AC_ARG_ENABLE(cxx-warnings,
AC_HELP_STRING([--enable-cxx-warnings=@<:@no/minimum/yes@:>@]
[Turn on compiler warnings.]),,
[enable_cxx_warnings="m4_default([$1],[minimum])"])
AC_MSG_CHECKING(what warning flags to pass to the C++ compiler)
warnCXXFLAGS=
if test "x$GXX" != xyes; then
enable_cxx_warnings=no
fi
if test "x$enable_cxx_warnings" != "xno"; then
if test "x$GXX" = "xyes"; then
case " $CXXFLAGS " in
*[\ \ ]-Wall[\ \ ]*) ;;
*) warnCXXFLAGS="-Wall -Wno-unused" ;;
esac
## -W is not all that useful. And it cannot be controlled
## with individual -Wno-xxx flags, unlike -Wall
if test "x$enable_cxx_warnings" = "xyes"; then
warnCXXFLAGS="$warnCXXFLAGS -Wshadow -Woverloaded-virtual"
fi
fi
fi
AC_MSG_RESULT($warnCXXFLAGS)
AC_ARG_ENABLE(iso-cxx,
AC_HELP_STRING([--enable-iso-cxx],
[Try to warn if code is not ISO C++ ]),,
[enable_iso_cxx=no])
AC_MSG_CHECKING(what language compliance flags to pass to the C++ compiler)
complCXXFLAGS=
if test "x$enable_iso_cxx" != "xno"; then
if test "x$GXX" = "xyes"; then
case " $CXXFLAGS " in
*[\ \ ]-ansi[\ \ ]*) ;;
*) complCXXFLAGS="$complCXXFLAGS -ansi" ;;
esac
case " $CXXFLAGS " in
*[\ \ ]-pedantic[\ \ ]*) ;;
*) complCXXFLAGS="$complCXXFLAGS -pedantic" ;;
esac
fi
fi
AC_MSG_RESULT($complCXXFLAGS)
WARN_CXXFLAGS="$CXXFLAGS $warnCXXFLAGS $complCXXFLAGS"
AC_SUBST(WARN_CXXFLAGS)
])

View File

@ -7,7 +7,7 @@ msgstr ""
"Project-Id-Version: sugar\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2008-06-24 00:07+0530\n"
"PO-Revision-Date: 2008-08-07 09:05-0400\n"
"PO-Revision-Date: 2008-08-07 17:03-0400\n"
"Last-Translator: Khaled Hosny <khaledhosny@eglug.org>\n"
"Language-Team: Arabic <doc@arabeyes.org>\n"
"MIME-Version: 1.0\n"
@ -133,8 +133,8 @@ msgstr[5] "%d سنة"
msgid "%d month"
msgid_plural "%d months"
msgstr[0] "%d شهر"
msgstr[1] "%.sشهر"
msgstr[2] "%.sشهرين"
msgstr[1] "%.0هر"
msgstr[2] "%.0هرين"
msgstr[3] "%d شهور"
msgstr[4] "%d شهرا"
msgstr[5] "%d شهر"
@ -144,8 +144,8 @@ msgstr[5] "%d شهر"
msgid "%d week"
msgid_plural "%d weeks"
msgstr[0] "%d أسبوع"
msgstr[1] "%.sأسبوع"
msgstr[2] "%.sأسبوعين"
msgstr[1] "%.0sأسبوع"
msgstr[2] "%.0sأسبوعين"
msgstr[3] "%d أسابيع"
msgstr[4] "%d أسبوعا"
msgstr[5] "%d أسبوع"
@ -155,8 +155,8 @@ msgstr[5] "%d أسبوع"
msgid "%d day"
msgid_plural "%d days"
msgstr[0] "%d يوم"
msgstr[1] "%.sيوم"
msgstr[2] "%.sيومين"
msgstr[1] "%.0sيوم"
msgstr[2] "%.0sيومين"
msgstr[3] "%d أيام"
msgstr[4] "%d يوما"
msgstr[5] "%d يوم"
@ -166,8 +166,8 @@ msgstr[5] "%d يوم"
msgid "%d hour"
msgid_plural "%d hours"
msgstr[0] "%d ساعة"
msgstr[1] "%.sساعة"
msgstr[2] "%.sساعتين"
msgstr[1] "%.0اعة"
msgstr[2] "%.0اعتين"
msgstr[3] "%d ساعات"
msgstr[4] "%d ساعة"
msgstr[5] "%d ساعة"
@ -177,8 +177,8 @@ msgstr[5] "%d ساعة"
msgid "%d minute"
msgid_plural "%d minutes"
msgstr[0] "%d دقيقة"
msgstr[1] "%.sدقيقة"
msgstr[2] "%.sدقيقتين"
msgstr[1] "%.0sدقيقة"
msgstr[2] "%.0sدقيقتين"
msgstr[3] "%d دقائق"
msgstr[4] "%d دقيقة"
msgstr[5] "%d دقيقة"

View File

@ -14,6 +14,7 @@ pkgpyexecdir = $(pythondir)/sugar
pkgpyexec_LTLIBRARIES = _sugarext.la
_sugarext_la_CFLAGS = \
$(WARN_CFLAGS) \
$(EXT_CFLAGS) \
$(PYTHON_INCLUDES)

View File

@ -10,8 +10,8 @@ headers
#include "sugar-preview.h"
#include "sexy-icon-entry.h"
#include "gsm-session.h"
#include "gsm-xsmp.h"
#define EGG_SM_CLIENT_BACKEND_XSMP
#include "eggsmclient.h"
#include "eggsmclient-private.h"

View File

@ -425,13 +425,6 @@ class Activity(Window, gtk.Container):
'joined': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([]))
}
__gproperties__ = {
'active' : (bool, None, None, False,
gobject.PARAM_READWRITE),
'max-participants': (int, None, None, 0, 1000, 0,
gobject.PARAM_READWRITE)
}
def __init__(self, handle, create_jobject=True):
"""Initialise the Activity
@ -570,24 +563,27 @@ class Activity(Window, gtk.Container):
# https://dev.laptop.org/ticket/3071
datastore.write(self._jobject)
def do_set_property(self, pspec, value):
if pspec.name == 'active':
if self._active != value:
self._active = value
if not self._active and self._jobject:
self.save()
elif pspec.name == 'max-participants':
self._max_participants = value
else:
Window.do_set_property(self, pspec, value)
def get_active(self):
return self._active
def do_get_property(self, pspec):
if pspec.name == 'active':
return self._active
elif pspec.name == 'max-participants':
return self._max_participants
else:
return Window.do_get_property(self, pspec)
def set_active(self, active):
if self._active != active:
self._active = active
if not self._active and self._jobject:
self.save()
active = gobject.property(
type=bool, default=False, getter=get_active, setter=set_active)
def get_max_participants(self):
return self._max_participants
def set_max_participants(self, participants):
self._max_participants = participants
max_participants = gobject.property(
type=int, default=0, getter=get_max_participants,
setter=set_max_participants)
def get_id(self):
"""Returns the activity id of the current instance of your activity.

View File

@ -291,7 +291,7 @@ class ActivityBundle(Bundle):
# List installed files
manifestfiles = self.get_files(self._raw_manifest())
paths = []
for root, dirs, files in os.walk(install_path):
for root, dirs_, files in os.walk(install_path):
rel_path = root[len(install_path) + 1:]
for f in files:
paths.append(os.path.join(rel_path, f))

View File

@ -49,6 +49,7 @@ class ContentBundle(Bundle):
self._category_icon = None
self._library_version = None
self._bundle_class = None
self._activity_start = None
info_file = self.get_file('library/library.info')
if info_file is None:

View File

@ -278,11 +278,14 @@ def delete(object_id):
logging.debug('datastore.delete')
dbus_helpers.delete(object_id)
def find(query, sorting=None, limit=None, offset=None, properties=[],
def find(query, sorting=None, limit=None, offset=None, properties=None,
reply_handler=None, error_handler=None):
query = query.copy()
if properties is None:
properties = []
if sorting:
query['order_by'] = sorting
if limit:

View File

@ -25,6 +25,8 @@
G_BEGIN_DECLS
#define EGG_SM_CLIENT_BACKEND_XSMP
GKeyFile *egg_sm_client_save_state (EggSMClient *client);
void egg_sm_client_quit_requested (EggSMClient *client);
void egg_sm_client_quit_cancelled (EggSMClient *client);

View File

@ -85,7 +85,7 @@ class Alert(gtk.EventBox):
self._buttons_box.set_spacing(style.DEFAULT_SPACING)
self._hbox.pack_start(self._buttons_box)
gtk.EventBox.__init__(self, **kwargs)
gobject.GObject.__init__(self, **kwargs)
self.set_visible_window(True)
self.add(self._hbox)
@ -105,6 +105,10 @@ class Alert(gtk.EventBox):
if self._msg != value:
self._msg = value
self._msg_label.set_markup(self._msg)
width, height_ = self._msg_label.size_request()
self._msg_label.set_size_request(width-style.DEFAULT_SPACING,
-1)
self._msg_label.set_line_wrap(True)
elif pspec.name == 'icon':
if self._icon != value:
self._icon = value

View File

@ -21,10 +21,6 @@ import gtk
class ComboBox(gtk.ComboBox):
__gtype_name__ = 'SugarComboBox'
__gproperties__ = {
'value' : (object, None, None,
gobject.PARAM_READABLE)
}
def __init__(self):
gtk.ComboBox.__init__(self)
@ -39,14 +35,14 @@ class ComboBox(gtk.ComboBox):
self.set_row_separator_func(self._is_separator)
def do_get_property(self, pspec):
if pspec.name == 'value':
row = self.get_active_item()
if not row:
return None
return row[0]
else:
return gtk.ComboBox.do_get_property(self, pspec)
def get_value(self):
row = self.get_active_item()
if not row:
return None
return row[0]
value = gobject.property(
type=object, getter=get_value, setter=None)
def _get_real_name_from_theme(self, name, size):
icon_theme = gtk.icon_theme_get_default()

View File

@ -293,17 +293,6 @@ class _IconBuffer(object):
class Icon(gtk.Image):
__gtype_name__ = 'SugarIcon'
__gproperties__ = {
'xo-color' : (object, None, None,
gobject.PARAM_WRITABLE),
'fill-color' : (object, None, None,
gobject.PARAM_READWRITE),
'stroke-color' : (object, None, None,
gobject.PARAM_READWRITE),
'badge-name' : (str, None, None, None,
gobject.PARAM_READWRITE)
}
def __init__(self, **kwargs):
self._buffer = _IconBuffer()
@ -368,35 +357,46 @@ class Icon(gtk.Image):
cr.set_source_surface(surface, x, y)
cr.paint()
def do_set_property(self, pspec, value):
if pspec.name == 'xo-color':
if self._buffer.xo_color != value:
self._buffer.xo_color = value
self.queue_draw()
elif pspec.name == 'fill-color':
if self._buffer.fill_color != value:
self._buffer.fill_color = value
self.queue_draw()
elif pspec.name == 'stroke-color':
if self._buffer.stroke_color != value:
self._buffer.stroke_color = value
self.queue_draw()
elif pspec.name == 'badge-name':
if self._buffer.badge_name != value:
self._buffer.badge_name = value
self.queue_resize()
else:
gtk.Image.do_set_property(self, pspec, value)
def set_xo_color(self, value):
if self._buffer.xo_color != value:
self._buffer.xo_color = value
self.queue_draw()
def do_get_property(self, pspec):
if pspec.name == 'fill-color':
return self._buffer.fill_color
elif pspec.name == 'stroke-color':
return self._buffer.stroke_color
elif pspec.name == 'badge-name':
return self._buffer.badge_name
else:
return gtk.Image.do_get_property(self, pspec)
xo_color = gobject.property(
type=object, getter=None, setter=set_xo_color)
def set_fill_color(self, value):
if self._buffer.fill_color != value:
self._buffer.fill_color = value
self.queue_draw()
def get_fill_color(self):
return self._buffer.fill_color
fill_color = gobject.property(
type=object, getter=get_fill_color, setter=set_fill_color)
def set_stroke_color(self, value):
if self._buffer.stroke_color != value:
self._buffer.stroke_color = value
self.queue_draw()
def get_stroke_color(self):
return self._buffer.stroke_color
stroke_color = gobject.property(
type=object, getter=get_stroke_color, setter=set_stroke_color)
def set_badge_name(self, value):
if self._buffer.badge_name != value:
self._buffer.badge_name = value
self.queue_resize()
def get_badge_name(self):
return self._buffer.badge_name
badge_name = gobject.property(
type=str, getter=get_badge_name, setter=set_badge_name)
class CanvasIcon(hippo.CanvasBox, hippo.CanvasItem):
__gtype_name__ = 'CanvasIcon'

View File

@ -244,9 +244,7 @@ class Palette(gtk.Window):
self._menu_box = None
self._content = None
self._palette_popup_sid = None
self._enter_invoker_hid = None
self._leave_invoker_hid = None
self._right_click_invoker_hid = None
self._invoker_hids = []
self.set_group_id("default")
@ -312,21 +310,27 @@ class Palette(gtk.Window):
return gtk.gdk.Rectangle(x, y, width, height)
def _set_invoker(self, invoker):
if self._invoker is not None:
self._invoker.disconnect(self._enter_invoker_hid)
self._invoker.disconnect(self._leave_invoker_hid)
self._invoker.disconnect(self._right_click_invoker_hid)
for hid in self._invoker_hids[:]:
self._invoker.disconnect(hid)
self._invoker_hids.remove(hid)
self._invoker = invoker
if invoker is not None:
self._enter_invoker_hid = self._invoker.connect(
'mouse-enter', self._invoker_mouse_enter_cb)
self._leave_invoker_hid = self._invoker.connect(
'mouse-leave', self._invoker_mouse_leave_cb)
self._right_click_invoker_hid = self._invoker.connect(
'right-click', self._invoker_right_click_cb)
self._invoker_hids.append(self._invoker.connect(
'mouse-enter', self._invoker_mouse_enter_cb))
self._invoker_hids.append(self._invoker.connect(
'mouse-leave', self._invoker_mouse_leave_cb))
self._invoker_hids.append(self._invoker.connect(
'right-click', self._invoker_right_click_cb))
if hasattr(invoker.props, 'widget'):
self._label.props.accel_widget = invoker.props.widget
self._update_accel_widget()
logging.debug(('Setup widget', invoker.props.widget))
self._invoker_hids.append(self._invoker.connect(
'notify::widget', self._invoker_widget_changed_cb))
def _update_accel_widget(self):
assert self.props.invoker is not None
self._label.props.accel_widget = self.props.invoker.props.widget
def set_primary_text(self, label, accel_path=None):
self._primary_text = label
@ -611,6 +615,9 @@ class Palette(gtk.Window):
self.popup(immediate=immediate)
def _invoker_widget_changed_cb(self, invoker, spec):
self._update_accel_widget()
def _invoker_mouse_enter_cb(self, invoker):
self._mouse_detector.start()
@ -939,6 +946,8 @@ class WidgetInvoker(Invoker):
else:
self._widget = parent
self.notify('widget')
self._enter_hid = self._widget.connect('enter-notify-event',
self.__enter_notify_event_cb)
self._leave_hid = self._widget.connect('leave-notify-event',
@ -1032,6 +1041,7 @@ class CanvasInvoker(Invoker):
self._position_hint = self.AT_CURSOR
self._motion_hid = None
self._release_hid = None
self._item = None
if parent:
self.attach(parent)
@ -1093,7 +1103,7 @@ class ToolInvoker(WidgetInvoker):
def _get_alignments(self):
parent = self._widget.get_parent()
if parent is None:
return WidgetInvoker.get_alignments()
return WidgetInvoker._get_alignments()
if parent.get_orientation() is gtk.ORIENTATION_HORIZONTAL:
return self.BOTTOM + self.TOP

View File

@ -150,53 +150,6 @@ end_phase (GsmSession *session)
start_phase (session);
}
static void
app_condition_changed (GsmApp *app, gboolean condition, gpointer data)
{
GsmSession *session;
GsmClient *client = NULL;
GSList *cl = NULL;
g_return_if_fail (data != NULL);
session = (GsmSession *) data;
/* Check for an existing session client for this app */
for (cl = session->clients; cl; cl = cl->next)
{
GsmClient *c = GSM_CLIENT (cl->data);
if (!strcmp (app->client_id, gsm_client_get_client_id (c)))
client = c;
}
if (condition)
{
GError *error = NULL;
if (app->pid <= 0 && client == NULL)
gsm_app_launch (app, &error);
if (error != NULL)
{
g_warning ("Not able to launch autostart app from its condition: %s",
error->message);
g_error_free (error);
}
}
else
{
/* Kill client in case condition if false and make sure it won't
* be automatically restarted by adding the client to
* condition_clients */
session->condition_clients =
g_slist_prepend (session->condition_clients, client);
gsm_client_die (client);
app->pid = -1;
}
}
static void
app_registered (GsmApp *app, gpointer data)
{
@ -241,10 +194,6 @@ phase_timeout (gpointer data)
static void
start_phase (GsmSession *session)
{
GsmApp *app;
GSList *a;
GError *err = NULL;
g_debug ("starting phase %d\n", session->phase);
g_slist_free (session->pending_apps);
@ -359,8 +308,6 @@ client_saved_state (GsmClient *client, gpointer data)
void
gsm_session_initiate_shutdown (GsmSession *session)
{
gboolean logout_prompt;
if (session->phase == GSM_SESSION_PHASE_SHUTDOWN)
{
/* Already shutting down, nothing more to do */

View File

@ -73,6 +73,8 @@ typedef enum {
GSM_SESSION_LOGOUT_MODE_FORCE
} GsmSessionLogoutMode;
GType gsm_session_get_type (void) G_GNUC_CONST;
void gsm_session_set_name (GsmSession *session,
const char *name);

View File

@ -15,19 +15,13 @@
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
import socket
import os
import threading
import traceback
import xmlrpclib
import sys
import httplib
import urllib
import fcntl
import tempfile
import gobject
import SimpleXMLRPCServer
import SimpleHTTPServer
import SocketServer
@ -299,294 +293,3 @@ class GlibURLDownloader(gobject.GObject):
if remove:
os.remove(self._fname)
self._outf = None
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.
"""
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().
"""
def __init__(self, addr, requestHandler=GlibXMLRPCRequestHandler,
logRequests=0, allow_none=False):
self.logRequests = logRequests
if sys.version_info[:3] >= (2, 5, 0):
SimpleXMLRPCServer.SimpleXMLRPCDispatcher.__init__(
self, allow_none, encoding="utf-8")
else:
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.
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)
# 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))
)
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)
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.
def __init__(self, use_datetime=0):
self.verbose = None
if sys.version_info[:3] >= (2, 5, 0):
xmlrpclib.Transport.__init__(self, use_datetime)
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.
def start_request(self, host, handler, request_body, verbose=0,
reply_handler=None, error_handler=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)
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._conn.sock, gobject.IO_IN, self._finish_request,
h, host, handler, verbose, reply_handler, error_handler, user_data)
def _finish_request(self, source, condition, h, host, handler, verbose,
reply_handler=None, error_handler=None, user_data=None):
"""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:
if error_handler:
gobject.idle_add(error_handler, err, 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._conn.sock)
if reply_handler:
# Coerce to a list so we can append user data
response = response[0]
if not isinstance(response, list):
response = [response]
response.append(user_data)
gobject.idle_add(reply_handler, *response)
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, *args, **kwargs):
return self.__send(self.__name, *args, **kwargs)
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)
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
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, *args, **kwargs):
"""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(args, methodname, encoding=self._encoding,
allow_none=self._allow_none)
reply_hdl = kwargs.get("reply_handler")
err_hdl = kwargs.get("error_handler")
udata = kwargs.get("user_data")
try:
response = self._transport.start_request(
self._host,
self._handler,
request,
verbose=self._verbose,
reply_handler=reply_hdl,
error_handler=err_hdl,
user_data=udata
)
except socket.error, exc:
if err_hdl:
gobject.idle_add(err_hdl, exc, udata)
def __getattr__(self, name):
# magic method dispatcher
return _Method(self.__request, name)
class Test(object):
def test(self, arg1, arg2):
print "Request got %s, %s" % (arg1, arg2)
return "success", "bork"
def xmlrpc_success_cb(response, resp2, loop):
print "Response was %s %s" % (response, resp2)
loop.quit()
def xmlrpc_error_cb(err, loop):
print "Error: %s" % err
loop.quit()
def xmlrpc_test(loop):
client = GlibServerProxy("http://127.0.0.1:8888")
client.test("bar", "baz",
reply_handler=xmlrpc_success_cb,
error_handler=xmlrpc_error_cb,
user_data=loop)
def start_xmlrpc():
server = GlibXMLRPCServer(("", 8888))
inst = Test()
server.register_instance(inst)
gobject.idle_add(xmlrpc_test, loop)
class TestReqHandler(ChunkedGlibHTTPRequestHandler):
def translate_path(self, path):
return "/tmp/foo"
def start_http():
server = GlibTCPServer(("", 8890), TestReqHandler)
def main():
loop = gobject.MainLoop()
# start_xmlrpc()
start_http()
try:
loop.run()
except KeyboardInterrupt:
print 'Ctrl+C pressed, exiting...'
print "Done."
if __name__ == "__main__":
main()

View File

@ -281,8 +281,8 @@ class Activity(gobject.GObject):
def tubes_ready():
if self.telepathy_text_chan is None or \
self.telepathy_tubes_chan is None:
return
self.telepathy_tubes_chan is None:
return
_logger.debug('%r: finished setting up tubes', self)
reply_handler()
@ -303,7 +303,7 @@ class Activity(gobject.GObject):
found_text_channel = False
found_tubes_channel = False
for chan_path, chan_iface, handle_type, handle in chans:
for chan_path, chan_iface, handle_type, handle_ in chans:
if handle_type != telepathy.HANDLE_TYPE_ROOM:
return

View File

@ -178,7 +178,7 @@ class PresenceService(gobject.GObject):
self._del_object, object_path)
try:
# Pre-fill the activity's ID
foo = obj.props.id
activity_id = obj.props.id
except dbus.exceptions.DBusException:
logging.debug('Cannot get the activity ID')
else:
@ -239,9 +239,11 @@ class PresenceService(gobject.GObject):
gobject.idle_add(self._emit_activity_invitation_signal, activity_path,
buddy_path, message)
def _emit_private_invitation_signal(self, bus_name, connection, channel, chan_type):
def _emit_private_invitation_signal(self, bus_name, connection,
channel, chan_type):
"""Emit GObject event with bus_name, connection and channel"""
self.emit('private-invitation', bus_name, connection, channel, chan_type)
self.emit('private-invitation', bus_name, connection,
channel, chan_type)
return False
def _private_invitation_cb(self, bus_name, connection, channel, chan_type):
@ -469,7 +471,7 @@ class PresenceService(gobject.GObject):
(activity.get_id(), err))
self.emit("activity-shared", False, None, err)
def share_activity(self, activity, properties={}, private=True):
def share_activity(self, activity, properties=None, private=True):
"""Ask presence service to ask the activity to share itself publicly.
Uses the AdvertiseActivity method on the service to ask for the
@ -484,6 +486,9 @@ class PresenceService(gobject.GObject):
"""
actid = activity.get_id()
if properties is None:
properties = {}
# Ensure the activity is not already shared/joined
for obj in self._objcache.values():
if not isinstance(object, Activity):
@ -584,7 +589,7 @@ class _MockPresenceService(gobject.GObject):
def get_owner(self):
return None
def share_activity(self, activity, properties={}):
def share_activity(self, activity, properties=None):
return None
_ps = None

View File

@ -19,8 +19,8 @@
from telepathy.constants import (
CHANNEL_GROUP_FLAG_CHANNEL_SPECIFIC_HANDLES)
from tubeconn import TubeConnection
import presenceservice
from sugar.presence.tubeconn import TubeConnection
from sugar.presence import presenceservice
class SugarTubeConnection(TubeConnection):

View File

@ -215,7 +215,7 @@ class Profile(object):
return None
# hash it
key_hash = util._sha_data(key)
key_hash = util.sha_data(key)
return util.printable_hash(key_hash)
def _get_privkey_hash(self):

View File

@ -50,6 +50,7 @@ void sugar_menu_set_active (SugarMenu *menu,
gboolean active);
void sugar_menu_embed (SugarMenu *menu,
GtkContainer *parent);
void sugar_menu_unembed (SugarMenu *menu);
G_END_DECLS

View File

@ -19,6 +19,7 @@
#include <gdk/gdkx.h>
#include <gtk/gtkwindow.h>
#include <X11/extensions/XShm.h>
#include "sugar-preview.h"
@ -37,8 +38,6 @@ sugar_preview_set_size(SugarPreview *preview, int width, int height)
GdkPixbuf *
sugar_preview_get_pixbuf(SugarPreview *preview)
{
GdkPixbuf *pixbuf;
if (preview->pixbuf != NULL) {
return preview->pixbuf;
}
@ -92,7 +91,7 @@ sugar_preview_take_screenshot(SugarPreview *preview, GdkDrawable *drawable)
XShmGetImage(GDK_SCREEN_XDISPLAY(screen),
GDK_DRAWABLE_XID(drawable),
gdk_x11_image_get_ximage(preview->image),
0, 0, AllPlanes, ZPixmap);
0, 0, AllPlanes);
}
static void

View File

@ -20,10 +20,11 @@ import time
import sha
import random
import binascii
import string
from gettext import gettext as _
import gettext
_ = lambda msg: gettext.dgettext('sugar-toolkit', msg)
_ngettext = lambda m1, m2, n: gettext.dngettext('sugar-toolkit', m1, m2, n)
def printable_hash(in_hash):
"""Convert binary hash data into printable characters."""
printable = ""
@ -31,7 +32,7 @@ def printable_hash(in_hash):
printable = printable + binascii.b2a_hex(char)
return printable
def _sha_data(data):
def sha_data(data):
"""sha1 hash some bytes."""
sha_hash = sha.new()
sha_hash.update(data)
@ -52,13 +53,18 @@ def unique_id(data = ''):
perfectly unique values.
"""
data_string = "%s%s%s" % (time.time(), random.randint(10000, 100000), data)
return printable_hash(_sha_data(data_string))
return printable_hash(sha_data(data_string))
ACTIVITY_ID_LEN = 40
def is_hex(s):
return s.strip(string.hexdigits) == ''
try:
int(s, 16)
except ValueError:
return False
return True
def validate_activity_id(actid):
"""Validate an activity ID."""
@ -106,6 +112,7 @@ class LRU:
http://pype.sourceforge.net
Copyright 2003 Josiah Carlson.
"""
# pylint: disable-msg=W0102,W0612
def __init__(self, count, pairs=[]):
self.count = max(count, 1)
self.d = {}
@ -222,8 +229,8 @@ def timestamp_to_elapsed_string(timestamp, max_levels=2):
if levels > 0:
time_period += COMMA
time_period += gettext.ngettext(name_singular, name_plural,
elapsed_units) % elapsed_units
time_period += _ngettext(name_singular, name_plural,
elapsed_units) % elapsed_units
elapsed_seconds -= elapsed_units * factor