Merge branch 'master' of git+ssh://dev.laptop.org/git/sugar

This commit is contained in:
Simon McVittie
2007-05-24 12:26:28 +01:00
97 changed files with 4943 additions and 7509 deletions
+38 -1
View File
@@ -1,4 +1,4 @@
SUBDIRS = activity browser clipboard graphics p2p presence datastore
SUBDIRS = activity clipboard graphics objects presence datastore
sugardir = $(pythondir)/sugar
sugar_PYTHON = \
@@ -9,3 +9,40 @@ sugar_PYTHON = \
ltihooks.py \
profile.py \
util.py
INCLUDES = \
$(LIB_CFLAGS) \
$(LIB_BINDINGS_CFLAGS) \
$(PYTHON_INCLUDES) \
-I$(top_srcdir)/lib \
-I$(top_srcdir)/lib/xdgmime
pkgpyexecdir = $(pythondir)/sugar
pkgpyexec_LTLIBRARIES = _sugarext.la
_sugarext_la_LDFLAGS = -module -avoid-version
_sugarext_la_LIBADD = \
$(LIB_BINDINGS_LIBS) \
$(LIB_LIBS) \
$(top_builddir)/lib/libsugar.la
_sugarext_la_SOURCES = \
_sugarextmodule.c
nodist__sugarext_la_SOURCES = _sugarext.c
_sugarext.c: _sugarext.defs _sugarext.override
CLEANFILES = _sugarext.c
EXTRA_DIST = _sugarext.override _sugarext.defs
.defs.c:
(cd $(srcdir)\
&& $(PYGTK_CODEGEN) \
--register $(PYGTK_DEFSDIR)/gdk-types.defs \
--register $(PYGTK_DEFSDIR)/gtk-types.defs \
--override $*.override \
--prefix py$* $*.defs) > gen-$*.c \
&& cp gen-$*.c $*.c \
&& rm -f gen-$*.c
+152
View File
@@ -0,0 +1,152 @@
/* -- THIS FILE IS GENERATED - DO NOT EDIT *//* -*- Mode: C; c-basic-offset: 4 -*- */
#include <Python.h>
#line 4 "_sugarext.override"
#include <Python.h>
#include "pygobject.h"
#include "sugar-address-entry.h"
#include "xdgmime.h"
#include <pygtk/pygtk.h>
#include <glib.h>
#line 18 "_sugarext.c"
/* ---------- types from other modules ---------- */
static PyTypeObject *_PyGtkEntry_Type;
#define PyGtkEntry_Type (*_PyGtkEntry_Type)
/* ---------- forward type declarations ---------- */
PyTypeObject G_GNUC_INTERNAL PySugarAddressEntry_Type;
#line 29 "_sugarext.c"
/* ----------- SugarAddressEntry ----------- */
PyTypeObject G_GNUC_INTERNAL PySugarAddressEntry_Type = {
PyObject_HEAD_INIT(NULL)
0, /* ob_size */
"_sugarext.AddressEntry", /* tp_name */
sizeof(PyGObject), /* tp_basicsize */
0, /* tp_itemsize */
/* methods */
(destructor)0, /* tp_dealloc */
(printfunc)0, /* tp_print */
(getattrfunc)0, /* tp_getattr */
(setattrfunc)0, /* tp_setattr */
(cmpfunc)0, /* tp_compare */
(reprfunc)0, /* tp_repr */
(PyNumberMethods*)0, /* tp_as_number */
(PySequenceMethods*)0, /* tp_as_sequence */
(PyMappingMethods*)0, /* tp_as_mapping */
(hashfunc)0, /* tp_hash */
(ternaryfunc)0, /* tp_call */
(reprfunc)0, /* tp_str */
(getattrofunc)0, /* tp_getattro */
(setattrofunc)0, /* tp_setattro */
(PyBufferProcs*)0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
NULL, /* Documentation string */
(traverseproc)0, /* tp_traverse */
(inquiry)0, /* tp_clear */
(richcmpfunc)0, /* tp_richcompare */
offsetof(PyGObject, weakreflist), /* tp_weaklistoffset */
(getiterfunc)0, /* tp_iter */
(iternextfunc)0, /* tp_iternext */
(struct PyMethodDef*)NULL, /* tp_methods */
(struct PyMemberDef*)0, /* tp_members */
(struct PyGetSetDef*)0, /* tp_getset */
NULL, /* tp_base */
NULL, /* tp_dict */
(descrgetfunc)0, /* tp_descr_get */
(descrsetfunc)0, /* tp_descr_set */
offsetof(PyGObject, inst_dict), /* tp_dictoffset */
(initproc)0, /* tp_init */
(allocfunc)0, /* tp_alloc */
(newfunc)0, /* tp_new */
(freefunc)0, /* tp_free */
(inquiry)0 /* tp_is_gc */
};
/* ----------- functions ----------- */
static PyObject *
_wrap_sugar_mime_get_mime_type_from_file_name(PyObject *self, PyObject *args, PyObject *kwargs)
{
static char *kwlist[] = { "filename", NULL };
char *filename;
const gchar *ret;
if (!PyArg_ParseTupleAndKeywords(args, kwargs,"s:get_mime_type_from_file_name", kwlist, &filename))
return NULL;
ret = sugar_mime_get_mime_type_from_file_name(filename);
if (ret)
return PyString_FromString(ret);
Py_INCREF(Py_None);
return Py_None;
}
#line 23 "_sugarext.override"
static PyObject *
_wrap_sugar_mime_get_mime_type_for_file(PyObject *self, PyObject *args, PyObject *kwargs)
{
static char *kwlist[] = { "filename", NULL };
char *filename;
const gchar *ret;
if (!PyArg_ParseTupleAndKeywords(args, kwargs,"s:get_mime_type_for_file", kwlist, &filename))
return NULL;
ret = sugar_mime_get_mime_type_for_file(filename, NULL);
if (ret)
return PyString_FromString(ret);
Py_INCREF(Py_None);
return Py_None;
}
#line 120 "_sugarext.c"
const PyMethodDef py_sugarext_functions[] = {
{ "get_mime_type_from_file_name", (PyCFunction)_wrap_sugar_mime_get_mime_type_from_file_name, METH_VARARGS|METH_KEYWORDS,
NULL },
{ "get_mime_type_for_file", (PyCFunction)_wrap_sugar_mime_get_mime_type_for_file, METH_VARARGS|METH_KEYWORDS,
NULL },
{ NULL, NULL, 0, NULL }
};
/* initialise stuff extension classes */
void
py_sugarext_register_classes(PyObject *d)
{
PyObject *module;
if ((module = PyImport_ImportModule("gtk")) != NULL) {
_PyGtkEntry_Type = (PyTypeObject *)PyObject_GetAttrString(module, "Entry");
if (_PyGtkEntry_Type == NULL) {
PyErr_SetString(PyExc_ImportError,
"cannot import name Entry from gtk");
return ;
}
} else {
PyErr_SetString(PyExc_ImportError,
"could not import gtk");
return ;
}
#line 151 "_sugarext.c"
pygobject_register_class(d, "SugarAddressEntry", SUGAR_TYPE_ADDRESS_ENTRY, &PySugarAddressEntry_Type, Py_BuildValue("(O)", &PyGtkEntry_Type));
}
+27
View File
@@ -0,0 +1,27 @@
;; -*- scheme -*-
; object definitions
(define-object AddressEntry
(in-module "Sugar")
(parent "GtkEntry")
(c-name "SugarAddressEntry")
(gtype-id "SUGAR_TYPE_ADDRESS_ENTRY")
)
; functions
(define-function get_mime_type_from_file_name
(c-name "sugar_mime_get_mime_type_from_file_name")
(return-type "const-char*")
(parameters
'("const-char*" "filename")
)
)
(define-function get_mime_type_for_file
(c-name "sugar_mime_get_mime_type_for_file")
(return-type "const-char*")
(parameters
'("const-char*" "filename")
)
)
+40
View File
@@ -0,0 +1,40 @@
/* -*- Mode: C; c-basic-offset: 4 -*- */
%%
headers
#include <Python.h>
#include "pygobject.h"
#include "sugar-address-entry.h"
#include "xdgmime.h"
#include <pygtk/pygtk.h>
#include <glib.h>
%%
modulename _sugarext
%%
import gtk.Entry as PyGtkEntry_Type
%%
ignore-glob
*_get_type
_*
%%
override sugar_mime_get_mime_type_for_file kwargs
static PyObject *
_wrap_sugar_mime_get_mime_type_for_file(PyObject *self, PyObject *args, PyObject *kwargs)
{
static char *kwlist[] = { "filename", NULL };
char *filename;
const gchar *ret;
if (!PyArg_ParseTupleAndKeywords(args, kwargs,"s:get_mime_type_for_file", kwlist, &filename))
return NULL;
ret = sugar_mime_get_mime_type_for_file(filename, NULL);
if (ret)
return PyString_FromString(ret);
Py_INCREF(Py_None);
return Py_None;
}
%%
+27
View File
@@ -0,0 +1,27 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
/* include this first, before NO_IMPORT_PYGOBJECT is defined */
#include <pygobject.h>
void py_sugarext_register_classes (PyObject *d);
extern PyMethodDef py_sugarext_functions[];
DL_EXPORT(void)
init_sugarext(void)
{
PyObject *m, *d;
init_pygobject ();
m = Py_InitModule ("_sugarext", py_sugarext_functions);
d = PyModule_GetDict (m);
py_sugarext_register_classes (d);
if (PyErr_Occurred ()) {
Py_FatalError ("can't initialise module _sugarext");
}
}
+3 -1
View File
@@ -31,6 +31,8 @@ _ACTIVITY_SERVICE_NAME = "org.laptop.Activity"
_ACTIVITY_SERVICE_PATH = "/org/laptop/Activity"
_ACTIVITY_INTERFACE = "org.laptop.Activity"
_ACTIVITY_FACTORY_INTERFACE = "org.laptop.ActivityFactory"
def create_activity_id():
"""Generate a new, unique ID for this activity"""
pservice = presenceservice.get_instance()
@@ -103,7 +105,7 @@ class ActivityCreationHandler(gobject.GObject):
bus = dbus.SessionBus()
proxy_obj = bus.get_object(service_name, bundle.get_object_path(), follow_name_owner_changes=True)
factory = dbus.Interface(proxy_obj, "com.redhat.Sugar.ActivityFactory")
factory = dbus.Interface(proxy_obj, _ACTIVITY_FACTORY_INTERFACE)
factory.create(self._activity_handle.get_dict(),
reply_handler=self._reply_handler,
+3 -1
View File
@@ -34,6 +34,8 @@ from sugar import logger
gobject.threads_init()
dbus.glib.threads_init()
_ACTIVITY_FACTORY_INTERFACE = "org.laptop.ActivityFactory"
class ActivityFactoryService(dbus.service.Object):
"""D-Bus service that creates instances of Python activities
@@ -92,7 +94,7 @@ class ActivityFactoryService(dbus.service.Object):
object_path = '/' + service_name.replace('.', '/')
dbus.service.Object.__init__(self, bus_name, object_path)
@dbus.service.method("com.redhat.Sugar.ActivityFactory", in_signature="a{ss}")
@dbus.service.method("org.laptop.ActivityFactory", in_signature="a{ss}")
def create(self, handle):
"""Create a new instance of this activity
-47
View File
@@ -1,47 +0,0 @@
sugardir = $(pythondir)/sugar/browser
sugar_PYTHON = \
__init__.py
INCLUDES = \
$(PYTHON_INCLUDES) \
$(PYGTK_CFLAGS) \
$(PYCAIRO_CFLAGS) \
$(LIB_CFLAGS) \
$(GECKO_CFLAGS) \
$(NSPR_CFLAGS) \
-I$(MOZILLA_INCLUDE_DIR)/gtkembedmoz \
-I$(top_srcdir)/browser
pkgpyexecdir = $(pythondir)/sugar/browser
pkgpyexec_LTLIBRARIES = _sugarbrowser.la
_sugarbrowser_la_LDFLAGS = -module -avoid-version $(GECKO_LDFLAGS)
_sugarbrowser_la_LIBADD = \
$(LIB_LIBS) \
$(PYCAIRO_LIBS) \
$(GECKO_LIBS) \
$(XPCOMGLUE_LIBS) \
$(top_builddir)/browser/libsugarbrowser.la
_sugarbrowser_la_SOURCES = \
_sugarbrowsermodule.c \
xulrunner.cpp \
xulrunner.h
nodist__sugarbrowser_la_SOURCES = _sugarbrowser.c
_sugar.c: _sugarbrowser.defs gtkmozembed.defs _sugarbrowser.override gtkmozembed.override
CLEANFILES = _sugarbrowser.c
EXTRA_DIST = _sugarbrowser.override _sugarbrowser.defs gtkmozembed.defs gtkmozembed.override
.defs.c:
(cd $(srcdir)\
&& $(PYGTK_CODEGEN) \
--register $(PYGTK_DEFSDIR)/gdk-types.defs \
--register $(PYGTK_DEFSDIR)/gtk-types.defs \
--override $*.override \
--prefix py$* $*.defs) > gen-$*.c \
&& cp gen-$*.c $*.c \
&& rm -f gen-$*.c
-31
View File
@@ -1,31 +0,0 @@
"""Sugar's web-browser activity
XUL Runner and gtkmozembed and is produced by the PyGTK
.defs system.
"""
try:
from sugar.browser import _sugarbrowser
except ImportError:
from sugar import ltihooks
from sugar.browser import _sugarbrowser
from _sugarbrowser import AddressEntry
from _sugarbrowser import startup, shutdown, get_download_manager
class Browser(_sugarbrowser.Browser):
def __init__(self):
_sugarbrowser.Browser.__init__(self)
def get_browser(self):
from xpcom import components
cls = components.classes["@laptop.org/browser/browserhelper;1"]
browser_helper = cls.getService(components.interfaces.nsIBrowserHelper)
print self.get_instance_id()
return browser_helper.getBrowser(self.get_instance_id())
def get_document(self):
return self.browser.contentDOMWindow.document
document = property(get_document)
browser = property(get_browser)
-206
View File
@@ -1,206 +0,0 @@
;; -*- scheme -*-
; object definitions ...
(define-boxed SugarBrowserEvent
(in-module "Sugar")
(c-name "SugarBrowserEvent")
(gtype-id "SUGAR_TYPE_BROWSER_EVENT")
(copy-func "sugar_browser_event_copy")
(release-func "sugar_browser_event_free")
)
(define-boxed SugarBrowserMetadata
(in-module "Sugar")
(c-name "SugarBrowserMetadata")
(gtype-id "SUGAR_TYPE_BROWSER_METADATA")
(copy-func "sugar_browser_metadata_copy")
(release-func "sugar_browser_metadata_free")
)
(define-object AddressEntry
(in-module "Sugar")
(parent "GtkEntry")
(c-name "SugarAddressEntry")
(gtype-id "SUGAR_TYPE_ADDRESS_ENTRY")
)
(define-object Browser
(in-module "Sugar")
(parent "GtkMozEmbed")
(c-name "SugarBrowser")
(gtype-id "SUGAR_TYPE_BROWSER")
)
(define-object DownloadManager
(in-module "Sugar")
(parent "GObject")
(c-name "SugarDownloadManager")
(gtype-id "SUGAR_TYPE_DOWNLOAD_MANAGER")
)
(define-object Download
(in-module "Sugar")
(parent "GObject")
(c-name "SugarDownload")
(gtype-id "SUGAR_TYPE_DOWNLOAD")
)
;; Enumerations and flags ...
;; From sugar-address-entry.h
(define-function sugar_address_entry_get_type
(c-name "sugar_address_entry_get_type")
(return-type "GType")
)
;; From sugar-browser.h
(define-function sugar_browser_get_type
(c-name "sugar_browser_get_type")
(return-type "GType")
)
(define-function startup
(c-name "sugar_browser_startup")
(parameters
'("const-char*" "profile_path")
'("const-char*" "profile_name")
)
(return-type "gboolean")
)
(define-function shutdown
(c-name "sugar_browser_shutdown")
(return-type "none")
)
(define-method grab_focus
(of-object "SugarBrowser")
(c-name "sugar_browser_grab_focus")
(return-type "none")
)
(define-method save_uri
(of-object "SugarBrowser")
(c-name "sugar_browser_save_uri")
(return-type "gboolean")
(parameters
'("const-char*" "uri")
'("const-char*" "filename")
)
)
(define-method save_document
(of-object "SugarBrowser")
(c-name "sugar_browser_save_document")
(return-type "gboolean")
(parameters
'("const-char*" "filename")
)
)
(define-method create_window
(of-object "SugarBrowser")
(c-name "sugar_browser_create_window")
(return-type "SugarBrowser*")
)
(define-virtual create_window
(of-object "SugarBrowser")
(c-name "sugar_browser_create_window")
(return-type "SugarBrowser*")
)
(define-method get_session
(of-object "SugarBrowser")
(c-name "sugar_browser_get_session")
(return-type "char*")
)
(define-method set_session
(of-object "SugarBrowser")
(c-name "sugar_browser_set_session")
(return-type "none")
(parameters
'("const-char*" "session")
)
)
(define-method get_instance_id
(of-object "SugarBrowser")
(c-name "sugar_browser_get_instance_id")
(return-type "int")
)
;; From sugar-key-grabber.h
(define-function sugar_key_grabber_get_type
(c-name "sugar_key_grabber_get_type")
(return-type "GType")
)
(define-method grab
(of-object "SugarKeyGrabber")
(c-name "sugar_key_grabber_grab")
(return-type "none")
(parameters
'("const-char*" "key")
)
)
(define-method get_key
(of-object "SugarKeyGrabber")
(c-name "sugar_key_grabber_get_key")
(return-type "char*")
(parameters
'("guint" "keycode")
'("guint" "state")
)
)
;; From sugar-download-manager.h
(define-function sugar_download_manager_get_type
(c-name "sugar_download_manager_get_type")
(return-type "GType")
)
(define-function get_download_manager
(c-name "sugar_get_download_manager")
(return-type "SugarDownloadManager*")
)
;; From sugar-download.h
(define-function sugar_download_get_type
(c-name "sugar_download_get_type")
(return-type "GType")
)
(define-method get_file_name
(of-object "SugarDownload")
(c-name "sugar_download_get_file_name")
(return-type "const-gchar*")
)
(define-method get_url
(of-object "SugarDownload")
(c-name "sugar_download_get_url")
(return-type "const-gchar*")
)
(define-method get_mime_type
(of-object "SugarDownload")
(c-name "sugar_download_get_mime_type")
(return-type "const-gchar*")
)
(define-method get_percent
(of-object "SugarDownload")
(c-name "sugar_download_get_percent")
(return-type "gint")
)
(include "gtkmozembed.defs")
-80
View File
@@ -1,80 +0,0 @@
/* -*- Mode: C; c-basic-offset: 4 -*- */
%%
headers
#include <Python.h>
#include "pygobject.h"
#include "sugar-browser.h"
#include "sugar-address-entry.h"
#include "sugar-download-manager.h"
#include "sugar-download.h"
#include <pygtk/pygtk.h>
#include <glib.h>
%%
modulename _sugarbrowser
%%
import gobject.GObject as PyGObject_Type
import gtk.Entry as PyGtkEntry_Type
import gtk.gdk.Screen as PyGdkScreen_Type
import gtk.gdk.Pixbuf as PyGdkPixbuf_Type
import hippo.CanvasImage as HippoCanvasImage_Type
%%
ignore-glob
*_get_type
_*
%%
include
gtkmozembed.override
%%
override-slot SugarBrowserMetadata.tp_getattr
static PyObject *
_wrap_sugar_browser_metadata_tp_getattr(PyObject *self, char *attr)
{
SugarBrowserMetadata *metadata = pyg_boxed_get(self, SugarBrowserMetadata);
if (!strcmp(attr, "__members__"))
return Py_BuildValue("[s]", "filename");
else if (!strcmp(attr, "filename")) {
if (metadata->filename) {
return PyString_FromString(metadata->filename);
} else {
Py_INCREF(Py_None);
return Py_None;
}
}
return NULL;
}
%%
override-slot SugarBrowserEvent.tp_getattr
static PyObject *
_wrap_sugar_browser_event_tp_getattr(PyObject *self, char *attr)
{
SugarBrowserEvent *event = pyg_boxed_get(self, SugarBrowserEvent);
if (!strcmp(attr, "__members__"))
return Py_BuildValue("[sss]", "image_uri", "button", "image_name");
else if (!strcmp(attr, "image_uri")) {
if (event->image_uri) {
return PyString_FromString(event->image_uri);
} else {
Py_INCREF(Py_None);
return Py_None;
}
}
else if (!strcmp(attr, "image_name")) {
if (event->image_name) {
return PyString_FromString(event->image_name);
} else {
Py_INCREF(Py_None);
return Py_None;
}
}
else if (!strcmp(attr, "button"))
return PyInt_FromLong(event->button);
return NULL;
}
%%
-32
View File
@@ -1,32 +0,0 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "xulrunner.h"
/* include this first, before NO_IMPORT_PYGOBJECT is defined */
#include <pygobject.h>
void py_sugarbrowser_register_classes (PyObject *d);
extern PyMethodDef py_sugarbrowser_functions[];
DL_EXPORT(void)
init_sugarbrowser(void)
{
PyObject *m, *d;
xulrunner_startup();
init_pygobject ();
m = Py_InitModule ("_sugarbrowser", py_sugarbrowser_functions);
d = PyModule_GetDict (m);
py_sugarbrowser_register_classes (d);
py_sugarbrowser_add_constants(m, "GTK_MOZ_EMBED_");
if (PyErr_Occurred ()) {
Py_FatalError ("can't initialise module _sugarbrowser");
}
}
-1
View File
@@ -1 +0,0 @@
-475
View File
@@ -1,475 +0,0 @@
;; -*- scheme -*-
; object definitions ...
(define-object MozEmbed
(in-module "Gtk")
(parent "GtkBin")
(c-name "GtkMozEmbed")
(gtype-id "GTK_TYPE_MOZ_EMBED")
)
; (define-object MozEmbedSingle
; (in-module "Gtk")
; (parent "GtkObject")
; (c-name "GtkMozEmbedSingle")
; (gtype-id "GTK_TYPE_MOZ_EMBED_SINGLE")
; )
;; Enumerations and flags ...
(define-enum MozEmbedProgressFlags
(in-module "Gtk")
(c-name "GtkMozEmbedProgressFlags")
(values
'("start" "GTK_MOZ_EMBED_FLAG_START")
'("redirecting" "GTK_MOZ_EMBED_FLAG_REDIRECTING")
'("transferring" "GTK_MOZ_EMBED_FLAG_TRANSFERRING")
'("negotiating" "GTK_MOZ_EMBED_FLAG_NEGOTIATING")
'("stop" "GTK_MOZ_EMBED_FLAG_STOP")
'("is-request" "GTK_MOZ_EMBED_FLAG_IS_REQUEST")
'("is-document" "GTK_MOZ_EMBED_FLAG_IS_DOCUMENT")
'("is-network" "GTK_MOZ_EMBED_FLAG_IS_NETWORK")
'("is-window" "GTK_MOZ_EMBED_FLAG_IS_WINDOW")
)
)
(define-enum MozEmbedStatusFlags
(in-module "Gtk")
(c-name "GtkMozEmbedStatusFlags")
(values
'("dns" "GTK_MOZ_EMBED_STATUS_FAILED_DNS")
'("connect" "GTK_MOZ_EMBED_STATUS_FAILED_CONNECT")
'("timeout" "GTK_MOZ_EMBED_STATUS_FAILED_TIMEOUT")
'("usercanceled" "GTK_MOZ_EMBED_STATUS_FAILED_USERCANCELED")
)
)
(define-enum MozEmbedReloadFlags
(in-module "Gtk")
(c-name "GtkMozEmbedReloadFlags")
(values
'("normal" "GTK_MOZ_EMBED_FLAG_RELOADNORMAL")
'("bypasscache" "GTK_MOZ_EMBED_FLAG_RELOADBYPASSCACHE")
'("bypassproxy" "GTK_MOZ_EMBED_FLAG_RELOADBYPASSPROXY")
'("bypassproxyandcache" "GTK_MOZ_EMBED_FLAG_RELOADBYPASSPROXYANDCACHE")
'("charsetchange" "GTK_MOZ_EMBED_FLAG_RELOADCHARSETCHANGE")
)
)
(define-enum MozEmbedChromeFlags
(in-module "Gtk")
(c-name "GtkMozEmbedChromeFlags")
(values
'("defaultchrome" "GTK_MOZ_EMBED_FLAG_DEFAULTCHROME")
'("windowborderson" "GTK_MOZ_EMBED_FLAG_WINDOWBORDERSON")
'("windowcloseon" "GTK_MOZ_EMBED_FLAG_WINDOWCLOSEON")
'("windowresizeon" "GTK_MOZ_EMBED_FLAG_WINDOWRESIZEON")
'("menubaron" "GTK_MOZ_EMBED_FLAG_MENUBARON")
'("toolbaron" "GTK_MOZ_EMBED_FLAG_TOOLBARON")
'("locationbaron" "GTK_MOZ_EMBED_FLAG_LOCATIONBARON")
'("statusbaron" "GTK_MOZ_EMBED_FLAG_STATUSBARON")
'("personaltoolbaron" "GTK_MOZ_EMBED_FLAG_PERSONALTOOLBARON")
'("scrollbarson" "GTK_MOZ_EMBED_FLAG_SCROLLBARSON")
'("titlebaron" "GTK_MOZ_EMBED_FLAG_TITLEBARON")
'("extrachromeon" "GTK_MOZ_EMBED_FLAG_EXTRACHROMEON")
'("allchrome" "GTK_MOZ_EMBED_FLAG_ALLCHROME")
'("windowraised" "GTK_MOZ_EMBED_FLAG_WINDOWRAISED")
'("windowlowered" "GTK_MOZ_EMBED_FLAG_WINDOWLOWERED")
'("centerscreen" "GTK_MOZ_EMBED_FLAG_CENTERSCREEN")
'("dependent" "GTK_MOZ_EMBED_FLAG_DEPENDENT")
'("modal" "GTK_MOZ_EMBED_FLAG_MODAL")
'("openasdialog" "GTK_MOZ_EMBED_FLAG_OPENASDIALOG")
'("openaschrome" "GTK_MOZ_EMBED_FLAG_OPENASCHROME")
)
)
;; From /usr/include/mozilla-1.2b/gtkembedmoz/gtkmozembed.h
(define-function gtk_moz_embed_get_type
(c-name "gtk_moz_embed_get_type")
(return-type "GtkType")
)
(define-function gtk_moz_embed_new
(c-name "gtk_moz_embed_new")
(is-constructor-of "GtkMozEmbed")
(return-type "GtkWidget*")
)
(define-function push_startup
(c-name "gtk_moz_embed_push_startup")
(return-type "none")
)
(define-function pop_startup
(c-name "gtk_moz_embed_pop_startup")
(return-type "none")
)
(define-function gtk_moz_embed_set_comp_path
(c-name "gtk_moz_embed_set_comp_path_deprecated")
(return-type "none")
(parameters
'("char*" "aPath")
)
(deprecated "renamed to gtkmozembed.set_comp_path")
)
(define-function set_comp_path
(c-name "gtk_moz_embed_set_comp_path")
(return-type "none")
(parameters
'("char*" "aPath")
)
)
(define-function gtk_moz_embed_set_profile_path
(c-name "gtk_moz_embed_set_profile_path_deprecated")
(return-type "none")
(parameters
'("char*" "aDir")
'("char*" "aName")
)
(deprecated "renamed to gtkmozembed.set_profile_path")
)
(define-function set_profile_path
(c-name "gtk_moz_embed_set_profile_path")
(return-type "none")
(parameters
'("char*" "aDir")
'("char*" "aName")
)
)
(define-method load_url
(of-object "GtkMozEmbed")
(c-name "gtk_moz_embed_load_url")
(return-type "none")
(parameters
'("const-char*" "url")
)
)
(define-method stop_load
(of-object "GtkMozEmbed")
(c-name "gtk_moz_embed_stop_load")
(return-type "none")
)
(define-method can_go_back
(of-object "GtkMozEmbed")
(c-name "gtk_moz_embed_can_go_back")
(return-type "gboolean")
)
(define-method can_go_forward
(of-object "GtkMozEmbed")
(c-name "gtk_moz_embed_can_go_forward")
(return-type "gboolean")
)
(define-method go_back
(of-object "GtkMozEmbed")
(c-name "gtk_moz_embed_go_back")
(return-type "none")
)
(define-method go_forward
(of-object "GtkMozEmbed")
(c-name "gtk_moz_embed_go_forward")
(return-type "none")
)
(define-method render_data
(of-object "GtkMozEmbed")
(c-name "gtk_moz_embed_render_data")
(return-type "none")
(parameters
'("const-char*" "data")
'("guint32" "len")
'("const-char*" "base_uri")
'("const-char*" "mime_type")
)
)
(define-method open_stream
(of-object "GtkMozEmbed")
(c-name "gtk_moz_embed_open_stream")
(return-type "none")
(parameters
'("const-char*" "base_uri")
'("const-char*" "mime_type")
)
)
(define-method append_data
(of-object "GtkMozEmbed")
(c-name "gtk_moz_embed_append_data")
(return-type "none")
(parameters
'("const-char*" "data")
'("guint32" "len")
)
)
(define-method close_stream
(of-object "GtkMozEmbed")
(c-name "gtk_moz_embed_close_stream")
(return-type "none")
)
(define-method get_link_message
(of-object "GtkMozEmbed")
(c-name "gtk_moz_embed_get_link_message")
(return-type "char*")
)
(define-method get_js_status
(of-object "GtkMozEmbed")
(c-name "gtk_moz_embed_get_js_status")
(return-type "char*")
)
(define-method get_title
(of-object "GtkMozEmbed")
(c-name "gtk_moz_embed_get_title")
(return-type "char*")
)
(define-method get_location
(of-object "GtkMozEmbed")
(c-name "gtk_moz_embed_get_location")
(return-type "char*")
)
(define-method reload
(of-object "GtkMozEmbed")
(c-name "gtk_moz_embed_reload")
(return-type "none")
(parameters
'("gint32" "flags")
)
)
(define-method set_chrome_mask
(of-object "GtkMozEmbed")
(c-name "gtk_moz_embed_set_chrome_mask")
(return-type "none")
(parameters
'("guint32" "flags")
)
)
(define-method get_chrome_mask
(of-object "GtkMozEmbed")
(c-name "gtk_moz_embed_get_chrome_mask")
(return-type "guint32")
)
; (define-function gtk_moz_embed_progress_flags_get_type
; (c-name "gtk_moz_embed_progress_flags_get_type")
; (return-type "GtkType")
; )
; (define-function gtk_moz_embed_status_enums_get_type
; (c-name "gtk_moz_embed_status_enums_get_type")
; (return-type "GtkType")
; )
; (define-function gtk_moz_embed_reload_flags_get_type
; (c-name "gtk_moz_embed_reload_flags_get_type")
; (return-type "GtkType")
; )
; (define-function gtk_moz_embed_chrome_flags_get_type
; (c-name "gtk_moz_embed_chrome_flags_get_type")
; (return-type "GtkType")
; )
(define-function gtk_moz_embed_single_get
(c-name "gtk_moz_embed_single_get")
(return-type "GtkMozEmbedSingle*")
)
(define-virtual link_message
(of-object "GtkMozEmbed")
(return-type "none")
)
(define-virtual js_status
(of-object "GtkMozEmbed")
(return-type "none")
)
(define-virtual location
(of-object "GtkMozEmbed")
(return-type "none")
)
(define-virtual title
(of-object "GtkMozEmbed")
(return-type "none")
)
(define-virtual progress
(of-object "GtkMozEmbed")
(return-type "none")
(parameters
'("gint" "curprogress")
'("gint" "maxprogress")
)
)
(define-virtual progress_all
(of-object "GtkMozEmbed")
(return-type "none")
(parameters
'("const-char*" "aURI")
'("gint" "curprogress")
'("gint" "maxprogress")
)
)
(define-virtual net_state
(of-object "GtkMozEmbed")
(return-type "none")
(parameters
'("gint" "state")
'("guint" "status")
)
)
(define-virtual net_state_all
(of-object "GtkMozEmbed")
(return-type "none")
(parameters
'("const-char*" "aURI")
'("gint" "state")
'("guint" "status")
)
)
(define-virtual net_start
(of-object "GtkMozEmbed")
(return-type "none")
)
(define-virtual net_stop
(of-object "GtkMozEmbed")
(return-type "none")
)
(define-virtual new_window
(of-object "GtkMozEmbed")
(return-type "none")
(parameters
'("GtkMozEmbed**" "newEmbed")
'("guint" "chromemask")
)
)
(define-virtual visibility
(of-object "GtkMozEmbed")
(return-type "none")
(parameters
'("gboolean" "visibility")
)
)
(define-virtual destroy_brsr
(of-object "GtkMozEmbed")
(return-type "none")
)
(define-virtual open_uri
(of-object "GtkMozEmbed")
(return-type "gint")
(parameters
'("const-char*" "aURI")
)
)
(define-virtual size_to
(of-object "GtkMozEmbed")
(return-type "none")
(parameters
'("gint" "width")
'("gint" "height")
)
)
(define-virtual dom_key_down
(of-object "GtkMozEmbed")
(return-type "gint")
(parameters
'("gpointer" "dom_event")
)
)
(define-virtual dom_key_press
(of-object "GtkMozEmbed")
(return-type "gint")
(parameters
'("gpointer" "dom_event")
)
)
(define-virtual dom_key_up
(of-object "GtkMozEmbed")
(return-type "gint")
(parameters
'("gpointer" "dom_event")
)
)
(define-virtual dom_mouse_down
(of-object "GtkMozEmbed")
(return-type "gint")
(parameters
'("gpointer" "dom_event")
)
)
(define-virtual dom_mouse_up
(of-object "GtkMozEmbed")
(return-type "gint")
(parameters
'("gpointer" "dom_event")
)
)
(define-virtual dom_mouse_click
(of-object "GtkMozEmbed")
(return-type "gint")
(parameters
'("gpointer" "dom_event")
)
)
(define-virtual dom_mouse_dbl_click
(of-object "GtkMozEmbed")
(return-type "gint")
(parameters
'("gpointer" "dom_event")
)
)
(define-virtual dom_mouse_over
(of-object "GtkMozEmbed")
(return-type "gint")
(parameters
'("gpointer" "dom_event")
)
)
(define-virtual dom_mouse_out
(of-object "GtkMozEmbed")
(return-type "gint")
(parameters
'("gpointer" "dom_event")
)
)
(define-virtual security_change
(of-object "GtkMozEmbed")
(return-type "none")
(parameters
'("gpointer" "request")
'("guint" "state")
)
)
(define-virtual status_change
(of-object "GtkMozEmbed")
(return-type "none")
(parameters
'("gpointer" "request")
'("gint" "status")
'("gpointer" "message")
)
)
(define-virtual new_window_orphan
(of-object "GtkMozEmbedSingle")
(return-type "none")
(parameters
'("GtkMozEmbed**" "newEmbed")
'("guint" "chromemask")
)
)
-50
View File
@@ -1,50 +0,0 @@
/* -*- Mode: C; c-basic-offset: 4 -*- */
%%
headers
#include <Python.h>
#define NO_IMPORT_PYGOBJECT
#include <pygobject.h>
#include <gtkmozembed.h>
%%
import gobject.GObject as PyGObject_Type
import gtk.Object as PyGtkObject_Type
import gtk.Bin as PyGtkBin_Type
%%
ignore-glob
*_get_type
_*
%%
override gtk_moz_embed_set_comp_path_deprecated kwargs
static PyObject *
_wrap_gtk_moz_embed_set_comp_path_deprecated(PyObject *self, PyObject *args, PyObject *kwargs)
{
static char *kwlist[] = { "aPath", NULL };
char *aPath;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s:gtk_moz_embed_set_comp_path", kwlist, &aPath))
return NULL;
if (PyErr_Warn(PyExc_DeprecationWarning, "renamed to gtkmozembed.set_comp_path") < 0)
return NULL;
gtk_moz_embed_set_comp_path(aPath);
Py_INCREF(Py_None);
return Py_None;
}
%%
override gtk_moz_embed_set_profile_path_deprecated kwargs
static PyObject *
_wrap_gtk_moz_embed_set_profile_path_deprecated(PyObject *self, PyObject *args, PyObject *kwargs)
{
static char *kwlist[] = { "aDir", "aName", NULL };
char *aDir, *aName;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ss:gtk_moz_embed_set_profile_path", kwlist, &aDir, &aName))
return NULL;
if (PyErr_Warn(PyExc_DeprecationWarning, "renamed to gtkmozembed.set_profile_path") < 0)
return NULL;
gtk_moz_embed_set_profile_path(aDir, aName);
Py_INCREF(Py_None);
return Py_None;
}
-60
View File
@@ -1,60 +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.
*/
#include <config.h>
#include <string.h>
#include "gtkmozembed_glue.cpp"
extern "C" int
xulrunner_startup(void)
{
static const GREVersionRange greVersion = {
"1.9a", PR_TRUE,
"2", PR_TRUE
};
char xpcomPath[PATH_MAX];
nsresult rv = GRE_GetGREPathWithProperties(&greVersion, 1, nsnull, 0,
xpcomPath, sizeof(xpcomPath));
if (NS_FAILED(rv)) {
fprintf(stderr, "Couldn't find a compatible GRE.\n");
return 1;
}
rv = XPCOMGlueStartup(xpcomPath);
if (NS_FAILED(rv)) {
fprintf(stderr, "Couldn't start XPCOM.");
return 1;
}
rv = GTKEmbedGlueStartup();
if (NS_FAILED(rv)) {
fprintf(stderr, "Couldn't find GTKMozEmbed symbols.");
return 1;
}
char *lastSlash = strrchr(xpcomPath, '/');
if (lastSlash)
*lastSlash = '\0';
gtk_moz_embed_set_path(xpcomPath);
}
-20
View File
@@ -1,20 +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.
*/
int xulrunner_startup (void);
+31 -6
View File
@@ -25,7 +25,7 @@ class DSObject(gobject.GObject):
([]))
}
def __init__(self, object_id, metadata, file_path):
def __init__(self, object_id, metadata=None, file_path=None):
gobject.GObject.__init__(self)
self.object_id = object_id
self._metadata = metadata
@@ -43,6 +43,8 @@ class DSObject(gobject.GObject):
del self.metadata[key]
def get_metadata(self):
if self._metadata is None and not self.object_id is None:
self.set_metadata(dbus_helpers.get_properties(self.object_id))
return self._metadata
def set_metadata(self, metadata):
@@ -53,6 +55,8 @@ class DSObject(gobject.GObject):
metadata = property(get_metadata, set_metadata)
def get_file_path(self):
if self._file_path is None and not self.object_id is None:
self.set_file_path(dbus_helpers.get_filename(self.object_id))
return self._file_path
def set_file_path(self, file_path):
@@ -88,9 +92,30 @@ def write(ds_object, reply_handler=None, error_handler=None):
# TODO: register the object for updates
logging.debug('Written object %s to the datastore.' % ds_object.object_id)
def find(query, reply_handler=None, error_handler=None):
object_ids = dbus_helpers.find(query, reply_handler, error_handler)
def find(query, sorting=None, limit=None, offset=None, reply_handler=None,
error_handler=None):
if sorting:
query['order_by'] = sorting
if limit:
query['limit'] = limit
if offset:
query['offset'] = offset
props_list, total_count = dbus_helpers.find(query, reply_handler, error_handler)
objects = []
for object_id in object_ids:
objects.append(get(object_id))
return objects
for props in props_list:
if props.has_key('filename') and props['filename']:
file_path = props['filename']
del props['filename']
else:
file_path = None
object_id = props['uid']
del props['uid']
ds_object = DSObject(object_id, props, file_path)
objects.append(ds_object)
return objects, total_count
+7 -1
View File
@@ -1 +1,7 @@
"""Hippo-based graphics/controls for use in Sugar"""
"""Graphics/controls for use in Sugar"""
try:
from sugar._sugarext import AddressEntry
except ImportError:
from sugar import ltihooks
from sugar._sugarext import AddressEntry
+3
View File
@@ -19,6 +19,8 @@ import logging
import gobject
import gtk
from sugar.graphics import units
class ComboBox(gtk.ComboBox):
__gtype_name__ = 'SugarComboBox'
@@ -51,6 +53,7 @@ class ComboBox(gtk.ComboBox):
def append_item(self, action_id, text, icon_name=None):
if not self._icon_renderer and icon_name:
self._icon_renderer = gtk.CellRendererPixbuf()
self._icon_renderer.props.stock_size = units.microgrid_to_pixels(3)
self.pack_start(self._icon_renderer, False)
self.add_attribute(self._icon_renderer, 'icon-name', 2)
+3
View File
@@ -82,6 +82,9 @@ class StderrCatcher:
_log_writer.write(STDERR_LEVEL, txt)
sys.__stderr__.write(txt)
def flush(self):
sys.__stderr__.flush()
def __exception_handler(typ, exc, tb):
trace = StringIO()
traceback.print_exception(typ, exc, tb, None, trace)
+3 -4
View File
@@ -1,5 +1,4 @@
sugardir = $(pythondir)/sugar/objects
sugar_PYTHON = \
__init__.py \
typeregistry.py \
typeinfo.py
sugar_PYTHON = \
__init__.py \
mime.py
+1
View File
@@ -0,0 +1 @@
from sugar.objects import mime
+11
View File
@@ -0,0 +1,11 @@
try:
from sugar import _sugarext
except ImportError:
from sugar import ltihooks
from sugar import _sugarext
def get_for_file(file_name):
return _sugarext.get_mime_type_for_file(file_name)
def get_from_file_name(file_name):
return _sugarext.get_mime_type_from_file_name(file_name)
-58
View File
@@ -1,58 +0,0 @@
# Copyright (C) 2007, 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.
class TypeInfo(object):
def __init__(self, info_dict=None):
self.type_id = None
self.name = None
self.icon = 'theme:stock-missing'
self.parent = None
self.formats = []
if info_dict:
self._read_from_dict(info_dict)
def get_default_activity(self):
return None
def get_activities(self):
return []
def _read_from_config(self, section, items, l_items):
self.type_id = section
for item in items:
if item[0] == 'name':
self.name = item[1]
elif item[0] == 'icon':
self.icon = item[1]
elif item[0] == 'parent':
self.parent = item[1]
elif item[0] == 'formats':
self.formats = item[1].split(';')
for item in litems:
if item[0] == 'name':
self.name = item[1]
return (self.name and self.parent and self.formats)
def _read_from_dict(self, info_dict):
self.type_id = info_dict['type_id']
self.name = info_dict['name']
self.icon = info_dict['icon']
self.formats = info_dict['formats']
-99
View File
@@ -1,99 +0,0 @@
# Copyright (C) 2007, 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 gettext import gettext as _
from ConfigParser import ConfigParser
from sugar.objects.typeinfo import TypeInfo
from sugar.activity import bundleregistry
_text_type = {
'type_id' : 'Text',
'name' : _('Text'),
'icon' : 'theme:object-text',
'formats' : [ 'text/plain', 'application/pdf' ]
}
_image_type = {
'type_id' : 'Image',
'name' : _('Image'),
'icon' : 'theme:object-image',
'formats' : [ 'image/jpeg', 'image/gif', 'image/png' ]
}
class _RootNode(_TypeNode):
def __init__(self):
_TypeNode.__init__('')
def append_primitive(self, info_dict):
self.append(TypeInfo(info_dict))
class _TypeNode(list):
def __init__(self, type_info):
self.type_info = type_info
def get_node_from_type(self, type_id):
for node in self:
if node.type_info.type_id == type_id:
return node
for node in self:
child = node.get_node_from_type()
if child:
return child
return None
class TypeRegistry(object):
def __init__(self):
self._tree = _RootNode()
self._tree.append_primitive(_image_type)
self._tree.append_primitive(_text_type)
self._bundle_registry = bundleregistry.get_registry()
for bundle in self._bundle_registry:
self._read_from_bundle(bundle)
self._bundle_registry.connect('bundle-added', self._bundle_added_cb)
def _bundle_added_cb (self, registry, bundle):
self._read_from_bundle(bundle)
def _read_from_bundle(self, bundle):
cp = ConfigParser()
path = bundle.get_path()
cp.read([os.path.join(path, 'activity', 'object_types.info')])
items = cp.items()
cp = ConfigParser()
path = bundle.get_locale_path()
cp.read([os.path.join(path, 'object_types.linfo')])
l_items = cp.items()
for section in cp.sections():
type_info = TypeInfo()
if type_info.read_from_config(section, items, l_items):
parent_node = self._tree.get_node_from_type(type_info.parent)
if parent_node:
parent_node.append(_TypeNode(type_info))
return True
return False
def get_registry():
return _type_registry
_type_registry = TypeRegistry()
-8
View File
@@ -1,8 +0,0 @@
sugardir = $(pythondir)/sugar/p2p
sugar_PYTHON = \
__init__.py \
NotificationListener.py \
Notifier.py \
Stream.py \
MostlyReliablePipe.py \
network.py
File diff suppressed because it is too large Load Diff
-38
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 logging
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)
-27
View File
@@ -1,27 +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.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)
-160
View File
@@ -1,160 +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 xmlrpclib
import socket
import traceback
import random
import logging
import network
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
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 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 _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 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
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 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 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)
class MulticastStream(Stream):
def __init__(self, service):
Stream.__init__(self, service)
self._service = service
self._internal_start_reader()
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 write(self, data):
self._pipe.send(data)
def _recv_data_cb(self, address, data, user_data=None):
self._recv(address[0], data)
def new_writer(self, service=None):
return self
View File
-579
View File
@@ -1,579 +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.
# pylint: disable-msg = W0221
import socket
import os
import threading
import traceback
import xmlrpclib
import sys
import httplib
import urllib
import fcntl
import gobject
import SimpleXMLRPCServer
import SimpleHTTPServer
import SocketServer
__authinfos = {}
def _add_authinfo(authinfo):
__authinfos[threading.currentThread()] = authinfo
def get_authinfo():
return __authinfos.get(threading.currentThread())
def _del_authinfo():
del __authinfos[threading.currentThread()]
class GlibTCPServer(SocketServer.TCPServer):
"""GlibTCPServer
Integrate socket accept into glib mainloop.
"""
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
# 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
class ChunkedGlibHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
"""RequestHandler class that integrates with Glib mainloop. It writes
the specified file to the client in chunks, returning control to the
mainloop between chunks.
"""
CHUNK_SIZE = 4096
def __init__(self, request, client_address, server):
self._file = None
self._srcid = 0
SimpleHTTPServer.SimpleHTTPRequestHandler.__init__(self, request, client_address, server)
def log_request(self, code='-', size='-'):
pass
def do_GET(self):
"""Serve a GET request."""
self._file = self.send_head()
if self._file:
self._srcid = gobject.io_add_watch(self.wfile, gobject.IO_OUT | gobject.IO_ERR, self._send_next_chunk)
else:
self._file.close()
self._cleanup()
def _send_next_chunk(self, source, condition):
if condition & gobject.IO_ERR:
self._cleanup()
return False
if not (condition & gobject.IO_OUT):
self._cleanup()
return False
data = self._file.read(self.CHUNK_SIZE)
count = os.write(self.wfile.fileno(), data)
if count != len(data) or len(data) != self.CHUNK_SIZE:
self._cleanup()
return False
return True
def _cleanup(self):
if self._file:
self._file.close()
if self._srcid > 0:
gobject.source_remove(self._srcid)
self._srcid = 0
if not self.wfile.closed:
self.wfile.flush()
self.wfile.close()
self.rfile.close()
def finish(self):
"""Close the sockets when we're done, not before"""
pass
def send_head(self):
"""Common code for GET and HEAD commands.
This sends the response code and MIME headers.
Return value is either a file object (which has to be copied
to the outputfile by the caller unless the command was HEAD,
and must be closed by the caller under all circumstances), or
None, in which case the caller has nothing further to do.
** [dcbw] modified to send Content-disposition filename too
"""
path = self.translate_path(self.path)
f = None
if os.path.isdir(path):
for index in "index.html", "index.htm":
index = os.path.join(path, index)
if os.path.exists(index):
path = index
break
else:
return self.list_directory(path)
ctype = self.guess_type(path)
try:
# Always read in binary mode. Opening files in text mode may cause
# newline translations, making the actual size of the content
# transmitted *less* than the content-length!
f = open(path, 'rb')
except IOError:
self.send_error(404, "File not found")
return None
self.send_response(200)
self.send_header("Content-type", ctype)
self.send_header("Content-Length", str(os.fstat(f.fileno())[6]))
self.send_header("Content-Disposition", 'attachment; filename="%s"' % os.path.basename(path))
self.end_headers()
return f
class GlibURLDownloader(gobject.GObject):
"""Grabs a URL in chunks, returning to the mainloop after each chunk"""
__gsignals__ = {
'finished': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT])),
'error': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT]))
}
CHUNK_SIZE = 4096
def __init__(self, url, destdir=None):
self._url = url
if not destdir:
destdir = "/tmp"
self._destdir = destdir
self._srcid = 0
self._fname = None
self._outf = None
gobject.GObject.__init__(self)
def start(self):
self._info = urllib.urlopen(self._url)
self._suggested_fname = self._get_filename_from_headers(self._info.headers)
import tempfile
garbage, path = urllib.splittype(self._url)
garbage, path = urllib.splithost(path or "")
path, garbage = urllib.splitquery(path or "")
path, garbage = urllib.splitattr(path or "")
suffix = os.path.splitext(path)[1]
(self._outf, self._fname) = tempfile.mkstemp(suffix=suffix, dir=self._destdir)
fcntl.fcntl(self._info.fp.fileno(), fcntl.F_SETFD, os.O_NDELAY)
self._srcid = gobject.io_add_watch(self._info.fp.fileno(),
gobject.IO_IN | gobject.IO_ERR,
self._read_next_chunk)
def _get_filename_from_headers(self, headers):
if not headers.has_key("Content-Disposition"):
return None
ftag = "filename="
data = headers["Content-Disposition"]
fidx = data.find(ftag)
if fidx < 0:
return None
fname = data[fidx+len(ftag):]
if fname[0] == '"' or fname[0] == "'":
fname = fname[1:]
if fname[len(fname)-1] == '"' or fname[len(fname)-1] == "'":
fname = fname[:len(fname)-1]
return fname
def _read_next_chunk(self, source, condition):
if condition & gobject.IO_ERR:
self.cleanup()
os.remove(self._fname)
self.emit("error", "Error downloading file.")
return False
elif not (condition & gobject.IO_IN):
# shouldn't get here, but...
return True
try:
data = self._info.fp.read(self.CHUNK_SIZE)
count = os.write(self._outf, data)
if len(data) < self.CHUNK_SIZE:
self.cleanup()
self.emit("finished", self._fname, self._suggested_fname)
return False
if count < len(data):
self.cleanup()
self.emit("error", "Error writing to download file.")
return False
except Exception, err:
self.cleanup()
self.emit("error", "Error downloading file: %s" % err)
return False
return True
def cleanup(self):
if self._srcid > 0:
gobject.source_remove(self._srcid)
self._srcid = 0
del self._info
self._info = None
os.close(self._outf)
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):
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
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, *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 GroupServer(object):
_MAX_MSG_SIZE = 500
def __init__(self, address, port, data_cb):
self._address = address
self._port = port
self._data_cb = data_cb
self._setup_listener()
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)
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)
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
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
def send_msg(self, data):
self._send_sock.sendto(data, (self._address, self._port))
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 main():
loop = gobject.MainLoop()
server = GlibXMLRPCServer(("", 8888))
inst = Test()
server.register_instance(inst)
gobject.idle_add(xmlrpc_test, loop)
try:
loop.run()
except KeyboardInterrupt:
print 'Ctrl+C pressed, exiting...'
print "Done."
if __name__ == "__main__":
main()