Merge branch 'master' of git+ssh://dev.laptop.org/git/sugar
This commit is contained in:
+38
-1
@@ -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
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
@@ -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")
|
||||
)
|
||||
)
|
||||
@@ -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;
|
||||
}
|
||||
%%
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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)
|
||||
@@ -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")
|
||||
@@ -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;
|
||||
}
|
||||
%%
|
||||
@@ -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 +0,0 @@
|
||||
|
||||
@@ -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")
|
||||
)
|
||||
)
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
sugardir = $(pythondir)/sugar/objects
|
||||
sugar_PYTHON = \
|
||||
__init__.py \
|
||||
typeregistry.py \
|
||||
typeinfo.py
|
||||
sugar_PYTHON = \
|
||||
__init__.py \
|
||||
mime.py
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
from sugar.objects import mime
|
||||
@@ -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)
|
||||
@@ -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']
|
||||
@@ -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()
|
||||
@@ -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
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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
|
||||
@@ -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()
|
||||
Reference in New Issue
Block a user