diff options
author | Simon Poirier <simpoir@gmail.com> | 2009-03-22 00:26:04 (GMT) |
---|---|---|
committer | Simon Poirier <simpoir@gmail.com> | 2009-03-22 00:26:04 (GMT) |
commit | 625f9bb52eda3215d82d1b76ec6a806459f321ce (patch) | |
tree | 4e1d9a00a5d830fd9f5392980d606e2143d24a30 /sugar-toolkit/src/sugar/datastore |
Initial commit
Diffstat (limited to 'sugar-toolkit/src/sugar/datastore')
-rw-r--r-- | sugar-toolkit/src/sugar/datastore/Makefile.am | 5 | ||||
-rw-r--r-- | sugar-toolkit/src/sugar/datastore/Makefile.in | 432 | ||||
-rw-r--r-- | sugar-toolkit/src/sugar/datastore/__init__.py | 16 | ||||
-rw-r--r-- | sugar-toolkit/src/sugar/datastore/datastore.py | 254 | ||||
-rw-r--r-- | sugar-toolkit/src/sugar/datastore/dbus_helpers.py | 104 |
5 files changed, 811 insertions, 0 deletions
diff --git a/sugar-toolkit/src/sugar/datastore/Makefile.am b/sugar-toolkit/src/sugar/datastore/Makefile.am new file mode 100644 index 0000000..a5f16b7 --- /dev/null +++ b/sugar-toolkit/src/sugar/datastore/Makefile.am @@ -0,0 +1,5 @@ +sugardir = $(pythondir)/sugar/datastore +sugar_PYTHON = \ + __init__.py \ + dbus_helpers.py \ + datastore.py diff --git a/sugar-toolkit/src/sugar/datastore/Makefile.in b/sugar-toolkit/src/sugar/datastore/Makefile.in new file mode 100644 index 0000000..79005a2 --- /dev/null +++ b/sugar-toolkit/src/sugar/datastore/Makefile.in @@ -0,0 +1,432 @@ +# Makefile.in generated by automake 1.10.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = src/sugar/datastore +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(sugar_PYTHON) +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/gnome-compiler-flags.m4 \ + $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/python.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +SOURCES = +DIST_SOURCES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; +am__installdirs = "$(DESTDIR)$(sugardir)" +sugarPYTHON_INSTALL = $(INSTALL_DATA) +py_compile = $(top_srcdir)/py-compile +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALL_LINGUAS = @ALL_LINGUAS@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIRNAME = @DATADIRNAME@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +EXT_CFLAGS = @EXT_CFLAGS@ +EXT_LIBS = @EXT_LIBS@ +FGREP = @FGREP@ +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ +GMOFILES = @GMOFILES@ +GMSGFMT = @GMSGFMT@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INSTOBJEXT = @INSTOBJEXT@ +INTLLIBS = @INTLLIBS@ +INTLTOOL_CAVES_RULE = @INTLTOOL_CAVES_RULE@ +INTLTOOL_DESKTOP_RULE = @INTLTOOL_DESKTOP_RULE@ +INTLTOOL_DIRECTORY_RULE = @INTLTOOL_DIRECTORY_RULE@ +INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ +INTLTOOL_KBD_RULE = @INTLTOOL_KBD_RULE@ +INTLTOOL_KEYS_RULE = @INTLTOOL_KEYS_RULE@ +INTLTOOL_MERGE = @INTLTOOL_MERGE@ +INTLTOOL_OAF_RULE = @INTLTOOL_OAF_RULE@ +INTLTOOL_PERL = @INTLTOOL_PERL@ +INTLTOOL_POLICY_RULE = @INTLTOOL_POLICY_RULE@ +INTLTOOL_PONG_RULE = @INTLTOOL_PONG_RULE@ +INTLTOOL_PROP_RULE = @INTLTOOL_PROP_RULE@ +INTLTOOL_SCHEMAS_RULE = @INTLTOOL_SCHEMAS_RULE@ +INTLTOOL_SERVER_RULE = @INTLTOOL_SERVER_RULE@ +INTLTOOL_SERVICE_RULE = @INTLTOOL_SERVICE_RULE@ +INTLTOOL_SHEET_RULE = @INTLTOOL_SHEET_RULE@ +INTLTOOL_SOUNDLIST_RULE = @INTLTOOL_SOUNDLIST_RULE@ +INTLTOOL_THEME_RULE = @INTLTOOL_THEME_RULE@ +INTLTOOL_UI_RULE = @INTLTOOL_UI_RULE@ +INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ +INTLTOOL_XAM_RULE = @INTLTOOL_XAM_RULE@ +INTLTOOL_XML_NOMERGE_RULE = @INTLTOOL_XML_NOMERGE_RULE@ +INTLTOOL_XML_RULE = @INTLTOOL_XML_RULE@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +MKINSTALLDIRS = @MKINSTALLDIRS@ +MSGFMT = @MSGFMT@ +MSGFMT_OPTS = @MSGFMT_OPTS@ +MSGMERGE = @MSGMERGE@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +POFILES = @POFILES@ +POSUB = @POSUB@ +PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@ +PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@ +PYGTK_CODEGEN = @PYGTK_CODEGEN@ +PYGTK_DEFSDIR = @PYGTK_DEFSDIR@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_INCLUDES = @PYTHON_INCLUDES@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +XGETTEXT = @XGETTEXT@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +sugardir = $(pythondir)/sugar/datastore +sugar_PYTHON = \ + __init__.py \ + dbus_helpers.py \ + datastore.py + +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/sugar/datastore/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign src/sugar/datastore/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-sugarPYTHON: $(sugar_PYTHON) + @$(NORMAL_INSTALL) + test -z "$(sugardir)" || $(MKDIR_P) "$(DESTDIR)$(sugardir)" + @list='$(sugar_PYTHON)'; dlist=''; for p in $$list; do\ + if test -f "$$p"; then b=; else b="$(srcdir)/"; fi; \ + if test -f $$b$$p; then \ + f=$(am__strip_dir) \ + dlist="$$dlist $$f"; \ + echo " $(sugarPYTHON_INSTALL) '$$b$$p' '$(DESTDIR)$(sugardir)/$$f'"; \ + $(sugarPYTHON_INSTALL) "$$b$$p" "$(DESTDIR)$(sugardir)/$$f"; \ + else :; fi; \ + done; \ + if test -n "$$dlist"; then \ + if test -z "$(DESTDIR)"; then \ + PYTHON=$(PYTHON) $(py_compile) --basedir "$(sugardir)" $$dlist; \ + else \ + PYTHON=$(PYTHON) $(py_compile) --destdir "$(DESTDIR)" --basedir "$(sugardir)" $$dlist; \ + fi; \ + else :; fi + +uninstall-sugarPYTHON: + @$(NORMAL_UNINSTALL) + @list='$(sugar_PYTHON)'; dlist=''; for p in $$list; do\ + f=$(am__strip_dir) \ + rm -f "$(DESTDIR)$(sugardir)/$$f"; \ + rm -f "$(DESTDIR)$(sugardir)/$${f}c"; \ + rm -f "$(DESTDIR)$(sugardir)/$${f}o"; \ + done +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile +installdirs: + for dir in "$(DESTDIR)$(sugardir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: install-sugarPYTHON + +install-dvi: install-dvi-am + +install-exec-am: + +install-html: install-html-am + +install-info: install-info-am + +install-man: + +install-pdf: install-pdf-am + +install-ps: install-ps-am + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-sugarPYTHON + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + distclean distclean-generic distclean-libtool distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + install-sugarPYTHON installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + uninstall uninstall-am uninstall-sugarPYTHON + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/sugar-toolkit/src/sugar/datastore/__init__.py b/sugar-toolkit/src/sugar/datastore/__init__.py new file mode 100644 index 0000000..bdb658b --- /dev/null +++ b/sugar-toolkit/src/sugar/datastore/__init__.py @@ -0,0 +1,16 @@ +# Copyright (C) 2007, One Laptop Per Child +# +# 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. diff --git a/sugar-toolkit/src/sugar/datastore/datastore.py b/sugar-toolkit/src/sugar/datastore/datastore.py new file mode 100644 index 0000000..80d5936 --- /dev/null +++ b/sugar-toolkit/src/sugar/datastore/datastore.py @@ -0,0 +1,254 @@ +# Copyright (C) 2007, One Laptop Per Child +# +# 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. + +""" +STABLE. +""" + +import logging +import time +from datetime import datetime +import os + +import gobject + +from sugar.datastore import dbus_helpers +from sugar import mime + +class DSMetadata(gobject.GObject): + __gsignals__ = { + 'updated': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, + ([])) + } + + def __init__(self, props=None): + gobject.GObject.__init__(self) + if not props: + self._props = {} + else: + self._props = props + + default_keys = ['activity', 'activity_id', + 'mime_type', 'title_set_by_user'] + for key in default_keys: + if not self._props.has_key(key): + self._props[key] = '' + + def __getitem__(self, key): + return self._props[key] + + def __setitem__(self, key, value): + if not self._props.has_key(key) or self._props[key] != value: + self._props[key] = value + self.emit('updated') + + def __delitem__(self, key): + del self._props[key] + + def __contains__(self, key): + return self._props.__contains__(key) + + def has_key(self, key): + return self._props.has_key(key) + + def keys(self): + return self._props.keys() + + def get_dictionary(self): + return self._props + + def copy(self): + return DSMetadata(self._props.copy()) + + def get(self, key, default=None): + if self._props.has_key(key): + return self._props[key] + else: + return default + +class DSObject(object): + def __init__(self, object_id, metadata=None, file_path=None): + self.object_id = object_id + self._metadata = metadata + self._file_path = file_path + self._destroyed = False + self._owns_file = False + + def get_metadata(self): + if self._metadata is None and not self.object_id is None: + metadata = DSMetadata(dbus_helpers.get_properties(self.object_id)) + self._metadata = metadata + return self._metadata + + def set_metadata(self, metadata): + if self._metadata != metadata: + self._metadata = metadata + + metadata = property(get_metadata, set_metadata) + + def get_file_path(self, fetch=True): + if fetch and self._file_path is None and not self.object_id is None: + self.set_file_path(dbus_helpers.get_filename(self.object_id)) + self._owns_file = True + return self._file_path + + def set_file_path(self, file_path): + if self._file_path != file_path: + if self._file_path and self._owns_file: + if os.path.isfile(self._file_path): + os.remove(self._file_path) + self._owns_file = False + self._file_path = file_path + + file_path = property(get_file_path, set_file_path) + + def destroy(self): + if self._destroyed: + logging.warning('This DSObject has already been destroyed!.') + return + self._destroyed = True + if self._file_path and self._owns_file: + if os.path.isfile(self._file_path): + os.remove(self._file_path) + self._owns_file = False + self._file_path = None + + def __del__(self): + if not self._destroyed: + logging.warning('DSObject was deleted without cleaning up first. ' \ + 'Call DSObject.destroy() before disposing it.') + self.destroy() + + def copy(self): + return DSObject(None, self._metadata.copy(), self._file_path) + +def get(object_id): + logging.debug('datastore.get') + metadata = dbus_helpers.get_properties(object_id) + + ds_object = DSObject(object_id, DSMetadata(metadata), None) + # TODO: register the object for updates + return ds_object + +def create(): + metadata = DSMetadata() + metadata['mtime'] = datetime.now().isoformat() + metadata['timestamp'] = int(time.time()) + return DSObject(object_id=None, metadata=metadata, file_path=None) + +def write(ds_object, update_mtime=True, transfer_ownership=False, + reply_handler=None, error_handler=None, timeout=-1): + logging.debug('datastore.write') + + properties = ds_object.metadata.get_dictionary().copy() + + if update_mtime: + properties['mtime'] = datetime.now().isoformat() + properties['timestamp'] = int(time.time()) + + file_path = ds_object.get_file_path(fetch=False) + if file_path is None: + file_path = '' + + # FIXME: this func will be sync for creates regardless of the handlers + # supplied. This is very bad API, need to decide what to do here. + if ds_object.object_id: + dbus_helpers.update(ds_object.object_id, + properties, + file_path, + transfer_ownership, + reply_handler=reply_handler, + error_handler=error_handler, + timeout=timeout) + else: + if reply_handler or error_handler: + logging.warning('datastore.write() cannot currently be called' \ + 'async for creates, see ticket 3071') + ds_object.object_id = dbus_helpers.create(properties, + file_path, + transfer_ownership) + ds_object.metadata['uid'] = ds_object.object_id + # TODO: register the object for updates + logging.debug('Written object %s to the datastore.' % ds_object.object_id) + +def delete(object_id): + logging.debug('datastore.delete') + dbus_helpers.delete(object_id) + +def find(query, sorting=None, limit=None, offset=None, properties=None, + reply_handler=None, error_handler=None): + + query = query.copy() + + if properties is None: + properties = [] + + if sorting: + query['order_by'] = sorting + if limit: + query['limit'] = limit + if offset: + query['offset'] = offset + + props_list, total_count = dbus_helpers.find(query, properties, + reply_handler, error_handler) + + objects = [] + for props in props_list: + object_id = props['uid'] + del props['uid'] + + ds_object = DSObject(object_id, DSMetadata(props), None) + objects.append(ds_object) + + return objects, total_count + +def copy(jobject, mount_point): + + new_jobject = jobject.copy() + new_jobject.metadata['mountpoint'] = mount_point + + if jobject.metadata.has_key('title'): + filename = jobject.metadata['title'] + + if jobject.metadata.has_key('mime_type'): + mime_type = jobject.metadata['mime_type'] + extension = mime.get_primary_extension(mime_type) + if extension: + filename += '.' + extension + + new_jobject.metadata['suggested_filename'] = filename + + # this will cause the file be retrieved from the DS + new_jobject.file_path = jobject.file_path + + write(new_jobject) + +def mount(uri, options, timeout=-1): + return dbus_helpers.mount(uri, options, timeout=timeout) + +def unmount(mount_point_id): + dbus_helpers.unmount(mount_point_id) + +def mounts(): + return dbus_helpers.mounts() + +def complete_indexing(): + return dbus_helpers.complete_indexing() + +def get_unique_values(key): + return dbus_helpers.get_unique_values(key) diff --git a/sugar-toolkit/src/sugar/datastore/dbus_helpers.py b/sugar-toolkit/src/sugar/datastore/dbus_helpers.py new file mode 100644 index 0000000..9115382 --- /dev/null +++ b/sugar-toolkit/src/sugar/datastore/dbus_helpers.py @@ -0,0 +1,104 @@ +# Copyright (C) 2006-2007 Red Hat, Inc. +# Copyright (C) 2007, One Laptop Per Child +# +# 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. + +""" +UNSTABLE. Should be internal to the datastore module. +""" + +import logging + +import dbus +import dbus.glib + +DS_DBUS_SERVICE = "org.laptop.sugar.DataStore" +DS_DBUS_INTERFACE = "org.laptop.sugar.DataStore" +DS_DBUS_PATH = "/org/laptop/sugar/DataStore" + +_data_store = None + +def _get_data_store(): + global _data_store + + if not _data_store: + _bus = dbus.SessionBus() + _data_store = dbus.Interface(_bus.get_object(DS_DBUS_SERVICE, + DS_DBUS_PATH), + DS_DBUS_INTERFACE) + return _data_store + +def create(properties, filename, transfer_ownership=False): + object_id = _get_data_store().create(dbus.Dictionary(properties), filename, + transfer_ownership) + logging.debug('dbus_helpers.create: ' + object_id) + return object_id + +def update(uid, properties, filename, transfer_ownership=False, + reply_handler=None, error_handler=None, timeout=-1): + debug_props = properties.copy() + if debug_props.has_key("preview"): + debug_props["preview"] = "<omitted>" + logging.debug('dbus_helpers.update: %s, %s, %s, %s' % + (uid, filename, debug_props, transfer_ownership)) + if reply_handler and error_handler: + _get_data_store().update(uid, dbus.Dictionary(properties), filename, + transfer_ownership, + reply_handler=reply_handler, + error_handler=error_handler, + timeout=timeout) + else: + _get_data_store().update(uid, dbus.Dictionary(properties), + filename, transfer_ownership) + +def delete(uid): + logging.debug('dbus_helpers.delete: %r' % uid) + _get_data_store().delete(uid) + +def get_properties(uid): + logging.debug('dbus_helpers.get_properties: %s' % uid) + return _get_data_store().get_properties(uid, byte_arrays=True) + +def get_filename(uid): + filename = _get_data_store().get_filename(uid) + logging.debug('dbus_helpers.get_filename: %s, %s' % (uid, filename)) + return filename + +def find(query, properties, reply_handler, error_handler): + logging.debug('dbus_helpers.find: %r %r' % (query, properties)) + if reply_handler and error_handler: + return _get_data_store().find(query, properties, + reply_handler=reply_handler, error_handler=error_handler, + byte_arrays=True) + else: + return _get_data_store().find(query, properties, byte_arrays=True) + +def mount(uri, options, timeout=-1): + return _get_data_store().mount(uri, options, timeout=timeout) + +def unmount(mount_point_id): + _get_data_store().unmount(mount_point_id) + +def mounts(): + return _get_data_store().mounts() + +def get_unique_values(key): + return _get_data_store().get_uniquevaluesfor( + key, dbus.Dictionary({}, signature='ss')) + +def complete_indexing(): + return _get_data_store().complete_indexing() + |