Create a private sugar lib and put our extensions there.

master
Marco Pesenti Gritti 18 years ago
parent 5cc6ee3235
commit 62a46ff92b

3
.gitignore vendored

@ -46,5 +46,4 @@ depcomp
libtool
ltmain.sh
m4/intltool.m4
bindings/globalkeys/globalkeys.c
bindings/gecko/gecko.c
lib/src/_sugar.c

@ -1,4 +1,4 @@
SUBDIRS = activities bindings po shell sugar services tools
SUBDIRS = activities lib po shell sugar services tools
ACLOCAL_AMFLAGS = -I m4

@ -9,7 +9,7 @@ from sugar.activity.Activity import Activity
from sugar.presence.PresenceService import PresenceService
from sugar.p2p.model.LocalModel import LocalModel
from sugar.p2p.model.RemoteModel import RemoteModel
import gecko
import _sugar
from NotificationBar import NotificationBar
from NavigationToolbar import NavigationToolbar
@ -68,10 +68,10 @@ class PopupCreator(gobject.GObject):
def get_embed(self):
return self._embed
class Browser(gecko.Browser):
class Browser(_sugar.Browser):
__gtype_name__ = "SugarBrowser"
def __init__(self):
gecko.Browser.__init__(self)
_sugar.Browser.__init__(self)
self._popup_creators = []
def do_create_window(self):
@ -205,4 +205,4 @@ class BrowserActivity(Activity):
def start():
gtkmozembed.set_profile_path(env.get_profile_path(), 'gecko')
gtkmozembed.push_startup()
gecko.startup()
_sugar.startup_browser()

@ -1,4 +0,0 @@
SUBDIRS = gecko globalkeys threadframe
bindingsdir = $(pkgdatadir)/bindings
bindings_PYTHON = __init__.py

@ -1,33 +0,0 @@
INCLUDES = \
$(PYTHON_INCLUDES) \
$(PYGTK_CFLAGS) \
$(GECKO_CFLAGS)
geckodir = $(pkgdatadir)/bindings
pkgpyexecdir = $(geckodir)
pkgpyexec_LTLIBRARIES = gecko.la
gecko_la_LDFLAGS = -module -avoid-version
gecko_la_LIBADD = $(GECKO_LIBS)
gecko_la_SOURCES = \
geckomodule.c \
gecko-browser.h \
gecko-browser.cpp
nodist_gecko_la_SOURCES = gecko.c
gecko.c: gecko.defs gecko.override
CLEANFILES = gecko.c
EXTRA_DIST = gecko.override gecko.defs
.defs.c:
(cd $(srcdir)\
&& $(PYGTK_CODEGEN) \
--register $(GNOMEPYTHONEXTRAS_DEFSDIR)/gtkmozembed.defs \
--override $*.override \
--prefix py$* $*.defs) > gen-$*.c \
&& cp gen-$*.c $*.c \
&& rm -f gen-$*.c

@ -1,35 +0,0 @@
INCLUDES = \
$(WARN_CFLAGS) \
$(PYTHON_INCLUDES) \
$(PYGTK_CFLAGS) \
$(GLOBALKEYS_CFLAGS)
globalkeysdir = $(pkgdatadir)/bindings
pkgpyexecdir = $(globalkeysdir)
pkgpyexec_LTLIBRARIES = globalkeys.la
globalkeys_la_LDFLAGS = -module -avoid-version
globalkeys_la_LIBADD = $(GLOBALKEYS_LIBS)
globalkeys_la_SOURCES = \
eggaccelerators.c \
eggaccelerators.h \
globalkeysmodule.c \
sugar-key-grabber.h \
sugar-key-grabber.c
nodist_globalkeys_la_SOURCES = globalkeys.c
globalkeys.c: globalkeys.defs globalkeys.override
CLEANFILES = globalkeys.c
EXTRA_DIST = globalkeys.override globalkeys.defs
.defs.c:
(cd $(srcdir)\
&& $(PYGTK_CODEGEN) \
--override $*.override \
--prefix py$* $*.defs) > gen-$*.c \
&& cp gen-$*.c $*.c \
&& rm -f gen-$*.c

@ -1,26 +0,0 @@
(define-object KeyGrabber
(in-module "globalkeys")
(parent "GObject")
(c-name "SugarKeyGrabber")
(gtype-id "SUGAR_TYPE_KEY_GRABBER")
)
(define-function sugar_key_grabber_get_type
(c-name "sugar_key_grabber_get_type")
(return-type "GType")
)
(define-function sugar_key_grabber_new
(c-name "sugar_key_grabber_new")
(is-constructor-of "SugarKeyGrabber")
(return-type "GObject*")
)
(define-method grab
(of-object "SugarKeyGrabber")
(c-name "sugar_key_grabber_grab")
(return-type "none")
(parameters
'("const-char*" "address")
)
)

@ -1,17 +0,0 @@
/* -*- Mode: C; c-basic-offset: 4 -*- */
%%
headers
#include <Python.h>
#include "pygobject.h"
#include "sugar-key-grabber.h"
%%
modulename globalkeys
%%
import gobject.GObject as PyGObject_Type
%%
ignore-glob
*_get_type
_*
%%

@ -1,27 +0,0 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
/* include this first, before NO_IMPORT_PYGOBJECT is defined */
#include <pygobject.h>
void pyglobalkeys_register_classes (PyObject *d);
extern PyMethodDef pyglobalkeys_functions[];
DL_EXPORT(void)
initglobalkeys(void)
{
PyObject *m, *d;
init_pygobject ();
m = Py_InitModule ("globalkeys", pyglobalkeys_functions);
d = PyModule_GetDict (m);
pyglobalkeys_register_classes (d);
if (PyErr_Occurred ()) {
Py_FatalError ("can't initialise module globalkeys");
}
}

@ -22,8 +22,10 @@ AM_CHECK_PYTHON_HEADERS(,[AC_MSG_ERROR(could not find Python headers)])
AC_PATH_PROG(PYGTK_CODEGEN, pygtk-codegen-2.0, no)
PKG_CHECK_MODULES(PYGTK, pygtk-2.0)
PKG_CHECK_MODULES(GLOBALKEYS, gdk-2.0)
PKG_CHECK_MODULES(GECKO, gtk+-2.0 xulrunner-gtkmozembed)
PKG_CHECK_MODULES(LIB, gtk+-2.0 xulrunner-gtkmozembed)
MOZILLA_HOME="`$PKG_CONFIG --variable=libdir xulrunner-gtkmozembed`"
AC_SUBST(MOZILLA_HOME)
GNOMEPYTHONEXTRAS_DEFSDIR=`$PKG_CONFIG --variable=defsdir pygtk-2.0`
AC_SUBST(GNOMEPYTHONEXTRAS_DEFSDIR)
@ -46,10 +48,10 @@ activities/browser/Makefile
activities/chat/Makefile
activities/groupchat/Makefile
activities/terminal/Makefile
bindings/Makefile
bindings/gecko/Makefile
bindings/globalkeys/Makefile
bindings/threadframe/Makefile
lib/Makefile
lib/src/Makefile
lib/python/Makefile
lib/threadframe/Makefile
services/Makefile
services/presence/Makefile
shell/Makefile

@ -0,0 +1 @@
SUBDIRS = src python

@ -0,0 +1,33 @@
INCLUDES = \
$(PYTHON_INCLUDES) \
$(PYGTK_CFLAGS) \
$(LIB_CFLAGS) \
-I $(top_srcdir)/lib/src
pkgpyexecdir = $(pythondir)
pkgpyexec_LTLIBRARIES = _sugar.la
_sugar_la_LDFLAGS = -module -avoid-version -R$(MOZILLA_HOME)
_sugar_la_LIBADD = \
$(LIB_LIBS) \
$(top_builddir)/lib/src/libsugarprivate.la
_sugar_la_SOURCES = \
_sugarmodule.c
nodist__sugar_la_SOURCES = _sugar.c
_sugar.c: _sugar.defs _sugar.override
CLEANFILES = _sugar.c
EXTRA_DIST = _sugar.override _sugar.defs
.defs.c:
(cd $(srcdir)\
&& $(PYGTK_CODEGEN) \
--register $(GNOMEPYTHONEXTRAS_DEFSDIR)/gtkmozembed.defs \
--override $*.override \
--prefix py$* $*.defs) > gen-$*.c \
&& cp gen-$*.c $*.c \
&& rm -f gen-$*.c

@ -0,0 +1,365 @@
/* -- THIS FILE IS GENERATED - DO NOT EDIT *//* -*- Mode: C; c-basic-offset: 4 -*- */
#include <Python.h>
#line 4 "_sugar.override"
#include <Python.h>
#include "pygobject.h"
#include "gecko-browser.h"
#include "sugar-key-grabber.h"
#line 15 "_sugar.c"
/* ---------- types from other modules ---------- */
static PyTypeObject *_PyGObject_Type;
#define PyGObject_Type (*_PyGObject_Type)
static PyTypeObject *_PyGtkMozEmbed_Type;
#define PyGtkMozEmbed_Type (*_PyGtkMozEmbed_Type)
/* ---------- forward type declarations ---------- */
PyTypeObject G_GNUC_INTERNAL PyGeckoBrowser_Type;
PyTypeObject G_GNUC_INTERNAL PySugarKeyGrabber_Type;
#line 29 "_sugar.c"
/* ----------- GeckoBrowser ----------- */
static int
_wrap_gecko_browser_new(PyGObject *self, PyObject *args, PyObject *kwargs)
{
static char* kwlist[] = { NULL };
if (!PyArg_ParseTupleAndKeywords(args, kwargs,
":gecko.Browser.__init__",
kwlist))
return -1;
pygobject_constructv(self, 0, NULL);
if (!self->obj) {
PyErr_SetString(
PyExc_RuntimeError,
"could not create gecko.Browser object");
return -1;
}
return 0;
}
static PyObject *
_wrap_gecko_browser_create_window(PyGObject *self)
{
GeckoBrowser *ret;
ret = gecko_browser_create_window(GECKO_BROWSER(self->obj));
/* pygobject_new handles NULL checking */
return pygobject_new((GObject *)ret);
}
static PyObject *
_wrap_GeckoBrowser__do_create_window(PyObject *cls, PyObject *args, PyObject *kwargs)
{
gpointer klass;
static char *kwlist[] = { "self", NULL };
PyGObject *self;
GeckoBrowser *ret;
if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O!:GeckoBrowser.create_window", kwlist, &PyGeckoBrowser_Type, &self))
return NULL;
klass = g_type_class_ref(pyg_type_from_object(cls));
if (GECKO_BROWSER_CLASS(klass)->create_window)
ret = GECKO_BROWSER_CLASS(klass)->create_window(GECKO_BROWSER(self->obj));
else {
PyErr_SetString(PyExc_NotImplementedError, "virtual method GeckoBrowser.create_window not implemented");
g_type_class_unref(klass);
return NULL;
}
g_type_class_unref(klass);
/* pygobject_new handles NULL checking */
return pygobject_new((GObject *)ret);
}
static const PyMethodDef _PyGeckoBrowser_methods[] = {
{ "create_window", (PyCFunction)_wrap_gecko_browser_create_window, METH_NOARGS,
NULL },
{ "do_create_window", (PyCFunction)_wrap_GeckoBrowser__do_create_window, METH_VARARGS|METH_KEYWORDS|METH_CLASS,
NULL },
{ NULL, NULL, 0, NULL }
};
PyTypeObject G_GNUC_INTERNAL PyGeckoBrowser_Type = {
PyObject_HEAD_INIT(NULL)
0, /* ob_size */
"gecko.Browser", /* 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*)_PyGeckoBrowser_methods, /* 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)_wrap_gecko_browser_new, /* tp_init */
(allocfunc)0, /* tp_alloc */
(newfunc)0, /* tp_new */
(freefunc)0, /* tp_free */
(inquiry)0 /* tp_is_gc */
};
static GeckoBrowser*
_wrap_GeckoBrowser__proxy_do_create_window(GeckoBrowser *self)
{
PyGILState_STATE __py_state;
PyObject *py_self;
GeckoBrowser* retval;
PyObject *py_retval;
PyObject *py_method;
__py_state = pyg_gil_state_ensure();
py_self = pygobject_new((GObject *) self);
if (!py_self) {
if (PyErr_Occurred())
PyErr_Print();
pyg_gil_state_release(__py_state);
return NULL;
}
py_method = PyObject_GetAttrString(py_self, "do_create_window");
if (!py_method) {
if (PyErr_Occurred())
PyErr_Print();
Py_DECREF(py_self);
pyg_gil_state_release(__py_state);
return NULL;
}
py_retval = PyObject_CallObject(py_method, NULL);
if (!py_retval) {
if (PyErr_Occurred())
PyErr_Print();
Py_DECREF(py_method);
Py_DECREF(py_self);
pyg_gil_state_release(__py_state);
return NULL;
}
if (!PyObject_TypeCheck(py_retval, &PyGObject_Type)) {
PyErr_SetString(PyExc_TypeError, "retval should be a GObject");
PyErr_Print();
Py_DECREF(py_retval);
Py_DECREF(py_method);
Py_DECREF(py_self);
pyg_gil_state_release(__py_state);
return NULL;
}
retval = (GeckoBrowser*) pygobject_get(py_retval);
g_object_ref((GObject *) retval);
Py_DECREF(py_retval);
Py_DECREF(py_method);
Py_DECREF(py_self);
pyg_gil_state_release(__py_state);
return retval;
}
static int
__GeckoBrowser_class_init(gpointer gclass, PyTypeObject *pyclass)
{
PyObject *o;
GeckoBrowserClass *klass = GECKO_BROWSER_CLASS(gclass);
PyObject *gsignals = PyDict_GetItemString(pyclass->tp_dict, "__gsignals__");
o = PyObject_GetAttrString((PyObject *) pyclass, "do_create_window");
if (o == NULL)
PyErr_Clear();
else {
if (!PyObject_TypeCheck(o, &PyCFunction_Type)
&& !(gsignals && PyDict_GetItemString(gsignals, "create_window")))
klass->create_window = _wrap_GeckoBrowser__proxy_do_create_window;
Py_DECREF(o);
}
return 0;
}
/* ----------- SugarKeyGrabber ----------- */
static int
_wrap_sugar_key_grabber_new(PyGObject *self, PyObject *args, PyObject *kwargs)
{
static char* kwlist[] = { NULL };
if (!PyArg_ParseTupleAndKeywords(args, kwargs,
":gecko.KeyGrabber.__init__",
kwlist))
return -1;
pygobject_constructv(self, 0, NULL);
if (!self->obj) {
PyErr_SetString(
PyExc_RuntimeError,
"could not create gecko.KeyGrabber object");
return -1;
}
return 0;
}
static PyObject *
_wrap_sugar_key_grabber_grab(PyGObject *self, PyObject *args, PyObject *kwargs)
{
static char *kwlist[] = { "address", NULL };
char *address;
if (!PyArg_ParseTupleAndKeywords(args, kwargs,"s:SugarKeyGrabber.grab", kwlist, &address))
return NULL;
sugar_key_grabber_grab(SUGAR_KEY_GRABBER(self->obj), address);
Py_INCREF(Py_None);
return Py_None;
}
static const PyMethodDef _PySugarKeyGrabber_methods[] = {
{ "grab", (PyCFunction)_wrap_sugar_key_grabber_grab, METH_VARARGS|METH_KEYWORDS,
NULL },
{ NULL, NULL, 0, NULL }
};
PyTypeObject G_GNUC_INTERNAL PySugarKeyGrabber_Type = {
PyObject_HEAD_INIT(NULL)
0, /* ob_size */
"gecko.KeyGrabber", /* 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*)_PySugarKeyGrabber_methods, /* 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)_wrap_sugar_key_grabber_new, /* tp_init */
(allocfunc)0, /* tp_alloc */
(newfunc)0, /* tp_new */
(freefunc)0, /* tp_free */
(inquiry)0 /* tp_is_gc */
};
/* ----------- functions ----------- */
static PyObject *
_wrap_gecko_browser_startup(PyObject *self)
{
gecko_browser_startup();
Py_INCREF(Py_None);
return Py_None;
}
const PyMethodDef py_sugar_functions[] = {
{ "startup_browser", (PyCFunction)_wrap_gecko_browser_startup, METH_NOARGS,
NULL },
{ NULL, NULL, 0, NULL }
};
/* initialise stuff extension classes */
void
py_sugar_register_classes(PyObject *d)
{
PyObject *module;
if ((module = PyImport_ImportModule("gobject")) != NULL) {
_PyGObject_Type = (PyTypeObject *)PyObject_GetAttrString(module, "GObject");
if (_PyGObject_Type == NULL) {
PyErr_SetString(PyExc_ImportError,
"cannot import name GObject from gobject");
return ;
}
} else {
PyErr_SetString(PyExc_ImportError,
"could not import gobject");
return ;
}
if ((module = PyImport_ImportModule("gtkmozembed")) != NULL) {
_PyGtkMozEmbed_Type = (PyTypeObject *)PyObject_GetAttrString(module, "MozEmbed");
if (_PyGtkMozEmbed_Type == NULL) {
PyErr_SetString(PyExc_ImportError,
"cannot import name MozEmbed from gtkmozembed");
return ;
}
} else {
PyErr_SetString(PyExc_ImportError,
"could not import gtkmozembed");
return ;
}
#line 360 "_sugar.c"
pygobject_register_class(d, "GeckoBrowser", GECKO_TYPE_BROWSER, &PyGeckoBrowser_Type, Py_BuildValue("(O)", &PyGtkMozEmbed_Type));
pyg_set_object_has_new_constructor(GECKO_TYPE_BROWSER);
pyg_register_class_init(GECKO_TYPE_BROWSER, __GeckoBrowser_class_init);
pygobject_register_class(d, "SugarKeyGrabber", SUGAR_TYPE_KEY_GRABBER, &PySugarKeyGrabber_Type, Py_BuildValue("(O)", &PyGObject_Type));
pyg_set_object_has_new_constructor(SUGAR_TYPE_KEY_GRABBER);
}

@ -17,7 +17,7 @@
(return-type "GType")
)
(define-function startup
(define-function startup_browser
(c-name "gecko_browser_startup")
(return-type "none")
)
@ -38,3 +38,29 @@
(of-object "GeckoBrowser")
(return-type "GeckoBrowser*")
)
(define-object KeyGrabber
(in-module "globalkeys")
(parent "GObject")
(c-name "SugarKeyGrabber")
(gtype-id "SUGAR_TYPE_KEY_GRABBER")
)
(define-function sugar_key_grabber_get_type
(c-name "sugar_key_grabber_get_type")
(return-type "GType")
)
(define-function sugar_key_grabber_new
(c-name "sugar_key_grabber_new")
(is-constructor-of "SugarKeyGrabber")
(return-type "GObject*")
)
(define-method grab
(of-object "SugarKeyGrabber")
(c-name "sugar_key_grabber_grab")
(return-type "none")
(parameters
'("const-char*" "address")
)
)

@ -5,6 +5,7 @@ headers
#include "pygobject.h"
#include "gecko-browser.h"
#include "sugar-key-grabber.h"
%%
modulename gecko

@ -5,21 +5,21 @@
/* include this first, before NO_IMPORT_PYGOBJECT is defined */
#include <pygobject.h>
void pygecko_register_classes (PyObject *d);
void py_sugar_register_classes (PyObject *d);
extern PyMethodDef pygecko_functions[];
extern PyMethodDef py_sugar_functions[];
DL_EXPORT(void)
initgecko(void)
init_sugar(void)
{
PyObject *m, *d;
init_pygobject ();
m = Py_InitModule ("gecko", pygecko_functions);
m = Py_InitModule ("_sugar", py_sugar_functions);
d = PyModule_GetDict (m);
pygecko_register_classes (d);
py_sugar_register_classes (d);
if (PyErr_Occurred ()) {
Py_FatalError ("can't initialise module globalkeys");

@ -0,0 +1,14 @@
INCLUDES = \
$(LIB_CFLAGS)
noinst_LTLIBRARIES = libsugarprivate.la
libsugarprivate_la_LIBADD = $(GECKO_LIBS)
libsugarprivate_la_SOURCES = \
eggaccelerators.h \
eggaccelerators.c \
gecko-browser.h \
gecko-browser.cpp \
sugar-key-grabber.h \
sugar-key-grabber.c

@ -10,7 +10,7 @@ from view.ActivityHost import ActivityHost
from sugar.activity import ActivityFactory
from sugar.activity import Activity
from view.frame.Frame import Frame
from globalkeys import KeyGrabber
from _sugar import KeyGrabber
import sugar
class Shell(gobject.GObject):

@ -5,7 +5,6 @@ sugar_services_dir = '@prefix@/share/sugar/services'
sugar_dbus_config = '@prefix@/share/sugar/dbus-installed.conf'
sugar_python_path = ['@prefix@/share/sugar/shell',
'@prefix@/share/sugar/bindings',
'@prefix@/share/sugar/activities',
'@prefix@/share/sugar/services']
sugar_bin_path = []

@ -10,7 +10,7 @@ sugar_service_dir = __tmpdir
sugar_dbus_config = os.path.join(sugar_source_dir, 'dbus-uninstalled.conf')
sugar_python_path = ['@prefix@/share/sugar/bindings']
sugar_python_path = []
sugar_python_path.append(sugar_source_dir)
sugar_python_path.append(os.path.join(sugar_source_dir, 'shell'))
sugar_python_path.append(os.path.join(sugar_source_dir, 'activities'))

Loading…
Cancel
Save