From: <svn...@op...> - 2010-09-17 08:08:27
|
Author: deloptes Date: Fri Sep 17 10:08:16 2010 New Revision: 6128 URL: http://www.opensync.org/changeset/6128 Log: akonadi-sync pluging - ported to build with kde 4.5 and libopensync1 (v.0.40) Added: plugins/akonadi-sync/trunk/CMakeLists.txt (contents, props changed) plugins/akonadi-sync/trunk/cmake/ plugins/akonadi-sync/trunk/cmake/modules/ plugins/akonadi-sync/trunk/cmake/modules/FindOpenSync.cmake plugins/akonadi-sync/trunk/cmake/modules/OpenSyncDefaults.cmake plugins/akonadi-sync/trunk/cmake/modules/OpenSyncPackaging.cmake plugins/akonadi-sync/trunk/cmake/modules/OpenSyncPlatforms.cmake plugins/akonadi-sync/trunk/cmake/modules/OpenSyncPlugin.cmake plugins/akonadi-sync/trunk/src/ plugins/akonadi-sync/trunk/src/CMakeLists.txt (contents, props changed) plugins/akonadi-sync/trunk/src/akonadi-sync (contents, props changed) plugins/akonadi-sync/trunk/src/akonadi_opensync.cpp (contents, props changed) plugins/akonadi-sync/trunk/src/akonadisink.cpp (contents, props changed) plugins/akonadi-sync/trunk/src/akonadisink.h (contents, props changed) plugins/akonadi-sync/trunk/src/datasink.cpp (contents, props changed) plugins/akonadi-sync/trunk/src/datasink.h (contents, props changed) plugins/akonadi-sync/trunk/src/sinkbase.cpp (contents, props changed) plugins/akonadi-sync/trunk/src/sinkbase.h (contents, props changed) Added: plugins/akonadi-sync/trunk/CMakeLists.txt ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ plugins/akonadi-sync/trunk/CMakeLists.txt Fri Sep 17 10:08:16 2010 (r6128) @@ -0,0 +1,58 @@ +# +# +# (c) Deloptes del...@ya... +# + +CMAKE_MINIMUM_REQUIRED( VERSION 2.4.4 ) +PROJECT( top-level C CXX ) + +SET( VERSION "0.40" ) +SET ( PROJECT_NAME akonadi_opensync_plugin ) + +# SET ( CMAKE_INSTALL_PREFIX "/opt/testing/opensync" ) + +SET( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/modules" ) +# SET ( OpenSync_DIR "/opt/testing/opensync" ) +SET (PKG_CONFIG_PATH "/opt/testing/opensync/lib/pkgconfig" ) +SET( CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS} ) +# SET( CMAKE_CXX_FLAGS_DEBUG "-DDEBUG -ggdb -g -O2 -Wall -W " ${CMAKE_CXX_FLAGS_DEBUG} ${KDE4_ENABLE_EXCEPTIONS} ) + +#ADD_DEFINITIONS(-g -O2 -fsigned-char -freg-struct-return -Wall -W -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual -Winline -Werror) +# ADD_DEFINITIONS( -DDEBUG -ggdb -g -O2 -Wall -W ) +# -Werror + +FIND_PACKAGE( KdepimLibs REQUIRED ) +FIND_PACKAGE( Akonadi REQUIRED ) +FIND_PACKAGE( GLIB2 REQUIRED ) +FIND_PACKAGE( KDE4 REQUIRED ) +FIND_PACKAGE( OpenSync REQUIRED ) +FIND_PACKAGE( Automoc4 REQUIRED ) + +INCLUDE( CheckIncludeFile ) + +INCLUDE( Documentation ) +INCLUDE( OpenSyncDefaults ) +INCLUDE ( OpenSyncPlugin ) +INCLUDE( OpenSyncInternal ) +INCLUDE( OpenSyncPackaging ) +# INCLUDE( Testing ) + + + +# include_directories( ${KDE4_INCLUDES} "/opt/testing/opensync/include" ) + +# include_directories( ${KDE4_INCLUDES} ${KDE4_INCLUDE_DIR} ${KDEPIMLIBS_INCLUDE_DIR} ${OPENSYNC_INCLUDE_DIR} "/opt/testing/opensync/include" ) +include_directories( ${KDE4_INCLUDES} ${KDE4_INCLUDE_DIR} ${KDEPIMLIBS_INCLUDE_DIR} ${OPENSYNC_INCLUDE_DIR} ${OPENSYNC_INCLUDE_DIR}/helper ${OPENSYNC_INCLUDE_DIR}/plugin ) + +include_directories( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/src ) + +# include_directories( ) + +# link_directories( ${KDE4_LIB_DIR} ${KDEPIMLIBS_LIB_DIR} ${OPENSYNC_LIBRARIES_DIR} "/opt/testing/opensync/lib" ) +link_directories( ${KDE4_LIB_DIR} ${KDEPIMLIBS_LIB_DIR} ${OPENSYNC_LIBRARIES_DIR} ) + + +ADD_SUBDIRECTORY( src ) + + +OPENSYNC_PACKAGE( ${PROJECT_NAME} ${VERSION} ) Added: plugins/akonadi-sync/trunk/cmake/modules/FindOpenSync.cmake ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ plugins/akonadi-sync/trunk/cmake/modules/FindOpenSync.cmake Fri Sep 17 10:08:16 2010 (r6128) @@ -0,0 +1,93 @@ +# - Try to find OpenSync +# Find OpenSync headers, libraries and the answer to all questions. +# +# OPENSYNC_FOUND True if OpenSync got found +# OPENSYNC_INCLUDE_DIRS Location of OpenSync headers +# OPENSYNC_LIBRARIES List of libaries to use OpenSync +# +# Copyright (c) 2007 Daniel Gollub <go...@b1...> +# Copyright (c) 2007 Alban Browaeys <pr...@ya...> +# Copyright (c) 2008 Bjoern Ricks <bjo...@go...> +# +# Redistribution and use is allowed according to the terms of the New +# BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. +# $Id: deloptes$ +# + +# Take care about libopensync.pc settings +INCLUDE( FindPkgConfig ) + +IF ( OpenSync_FIND_REQUIRED ) + SET( _pkgconfig_REQUIRED "REQUIRED" ) +ELSE( OpenSync_FIND_REQUIRED ) + SET( _pkgconfig_REQUIRED "" ) +ENDIF ( OpenSync_FIND_REQUIRED ) + +IF ( OPENSYNC_MIN_VERSION ) + PKG_SEARCH_MODULE( OPENSYNC ${_pkgconfig_REQUIRED} libopensync1 >=${OPENSYNC_MIN_VERSION} ) +ELSE ( OPENSYNC_MIN_VERSION ) + PKG_SEARCH_MODULE( OPENSYNC ${_pkgconfig_REQUIRED} libopensync1 ) +ENDIF ( OPENSYNC_MIN_VERSION ) + +FIND_PROGRAM( PKGCONFIG_EXECUTABLE NAMES pkg-config ) + +IF ( PKGCONFIG_EXECUTABLE ) + EXEC_PROGRAM( ${PKGCONFIG_EXECUTABLE} ARGS libopensync1 --variable=datadir OUTPUT_VARIABLE _opensync_data_DIR ) + STRING( REGEX REPLACE "[\r\n]" " " _opensync_data_DIR "${_opensync_data_DIR}" ) +ENDIF ( PKGCONFIG_EXECUTABLE ) + +FIND_PATH( OPENSYNC_CMAKE_MODULES "OpenSyncInternal.cmake" PATHS "${_opensync_data_DIR}" PATH_SUFFIXES "cmake/modules" NO_DEFAULT_PATH) +FIND_PATH( OPENSYNC_CMAKE_MODULES "OpenSyncInternal.cmake" PATH_SUFFIXES "cmake/modules" ) + +IF ( OPENSYNC_CMAKE_MODULES ) + SET( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${OPENSYNC_CMAKE_MODULES}" ) +ELSE ( OPENSYNC_CMAKE_MODULES ) + IF ( OpenSync_FIND_REQUIRED ) + MESSAGE( FATAL_ERROR "OpenSync cmake modules not found. Have you installed opensync core or did you set your PKG_CONFIG_PATH if installing in a non system directory ?" ) + ENDIF ( OpenSync_FIND_REQUIRED ) +ENDIF ( OPENSYNC_CMAKE_MODULES ) + + +# Look for OpenSync include dir and libraries without pkg-config +IF( NOT OPENSYNC_FOUND AND NOT PKG_CONFIG_FOUND ) + # Fallback if pkg-config doesn't exist + FIND_PATH( OPENSYNC_INCLUDE_DIRS opensync/opensync.h PATH_SUFFIXES libopensync libopensync1 + PATHS + /opt/local/include/ + /sw/include/ + /usr/local/include/ + /usr/include + /opt/testing/opensync/include ) + + FIND_LIBRARY( OPENSYNC_LIBRARIES opensync + PATHS + /opt/local/lib + /sw/lib + /usr/lib + /usr/local/lib + /usr/lib64 + /usr/local/lib64 + /opt/lib64 + /opt/testing/opensync/lib ) + + # Report results + IF ( OPENSYNC_LIBRARIES AND OPENSYNC_INCLUDE_DIRS ) + SET( OPENSYNC_FOUND 1 ) + IF ( NOT OpenSync_FIND_QUIETLY ) + MESSAGE( STATUS "Found OpenSync: ${OPENSYNC_LIBRARIES}" ) + ENDIF ( NOT OpenSync_FIND_QUIETLY ) + ELSE ( OPENSYNC_LIBRARIES AND OPENSYNC_INCLUDE_DIRS ) + IF ( OpenSync_FIND_REQUIRED ) + MESSAGE( SEND_ERROR "Could NOT find OpenSync" ) + ELSE ( OpenSync_FIND_REQUIRED ) + IF ( NOT OpenSync_FIND_QUIETLY ) + MESSAGE( STATUS "Could NOT find OpenSync" ) + ENDIF ( NOT OpenSync_FIND_QUIETLY ) + ENDIF ( OpenSync_FIND_REQUIRED ) + ENDIF ( OPENSYNC_LIBRARIES AND OPENSYNC_INCLUDE_DIRS ) +ENDIF( NOT OPENSYNC_FOUND AND NOT PKG_CONFIG_FOUND ) + +# Hide advanced variables from CMake GUIs +MARK_AS_ADVANCED( OPENSYNC_LIBRARIES OPENSYNC_INCLUDE_DIRS ) + Added: plugins/akonadi-sync/trunk/cmake/modules/OpenSyncDefaults.cmake ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ plugins/akonadi-sync/trunk/cmake/modules/OpenSyncDefaults.cmake Fri Sep 17 10:08:16 2010 (r6128) @@ -0,0 +1,57 @@ +# - OpenSync Internal Definitions and Macros +# Set OpenSync helper macros to build Plugins and internal definitions +# for OpenSync data directories like the locations of capabilities files, +# plugin configuration, ... +# +# OPENSYNC_PLUGINDIR Location of OpenSync plugins +# OPENSYNC_FORMATSDIR Location of OpenSync format plugins +# OPENSYNC_CAPABILITIESDIR Location of OpenSync capabilities files +# OPENSYNC_CONFIGDIR Location of OpenSync plugin default configurations/templates +# OPENSYNC_DESCRIPTIONSDIR Location of OpenSync descriptions files +# OPENSYNC_SCHEMASDIR Location of OpenSync related schema files +# +# OPENSYNC_INCLUDE_DIR Location of OpenSync headers +# OPENSYNC_DATA_DIR Location of OpenSync data directory +# +# OPENSYNC_TRACE True if tracing is enabled (debugging with env. var. OSYNC_TRACE) +# OPENSYNC_DEBUG_MODULES True if modules shouldn't get unloaded by OpenSync, to keep symbols of plugins +# OPENSYNC_UNITTESTS True if unit tests should be build +# +# Copyright (c) 2007-2008 Daniel Gollub <go...@b1...> +# + +INCLUDE( OpenSyncPlatforms ) + +# OpenSync macros and default settings: + +# Installation directories: + +SET( OPENSYNC_API_DIR "libopensync${OPENSYNC_LIBVERSION_SOVERSION}" ) +SET( OPENSYNC_PLUGINDIR "${LIB_INSTALL_DIR}/${OPENSYNC_API_DIR}/plugins" CACHE PATH "OpenSync plugin directory" ) +SET( OPENSYNC_FORMATSDIR "${LIB_INSTALL_DIR}/${OPENSYNC_API_DIR}/formats" CACHE PATH "OpenSync format plugin directory" ) +SET( OPENSYNC_PYTHON_PLUGINDIR "${LIB_INSTALL_DIR}/${OPENSYNC_API_DIR}/python-plugins" CACHE PATH "OpenSync python plugin directory" ) + +SET( OPENSYNC_CAPABILITIESDIR "${SHARE_INSTALL_DIR}/${OPENSYNC_API_DIR}/capabilities" CACHE PATH "OpenSync capabilities directory" ) +SET( OPENSYNC_CONFIGDIR "${SHARE_INSTALL_DIR}/${OPENSYNC_API_DIR}/defaults" CACHE PATH "OpenSync plugin configuration directory" ) +SET( OPENSYNC_DESCRIPTIONSDIR "${SHARE_INSTALL_DIR}/${OPENSYNC_API_DIR}/descriptions" CACHE PATH "OpenSync descriptions directory" ) +SET( OPENSYNC_SCHEMASDIR "${SHARE_INSTALL_DIR}/${OPENSYNC_API_DIR}/schemas" CACHE PATH "OpenSync schemas directory" ) +SET( OPENSYNC_UPDATESDIR "${SHARE_INSTALL_DIR}/${OPENSYNC_API_DIR}/updates" CACHE PATH "OpenSync configuration updates directory" ) + + +SET( OPENSYNC_LIBRARIES_DIR "${LIB_INSTALL_DIR}" CACHE PATH "OpenSync library location" ) +SET( OPENSYNC_LIBEXEC_DIR "${LIBEXEC_INSTALL_DIR}/${OPENSYNC_API_DIR}" CACHE PATH "OpenSync libexec location" ) +SET( OPENSYNC_INCLUDE_DIR "${INCLUDE_INSTALL_DIR}/${OPENSYNC_API_DIR}" CACHE PATH "OpenSync headers location" ) +SET( OPENSYNC_DATA_DIR "${SHARE_INSTALL_DIR}/${OPENSYNC_API_DIR}" CACHE PATH "OpenSync data directory" ) + +# OpenSync build options: + +IF ( NOT CMAKE_BUILD_TYPE ) + SET( CMAKE_BUILD_TYPE RelWithDebInfo ) +ENDIF ( NOT CMAKE_BUILD_TYPE ) + +SET( OPENSYNC_TRACE TRUE CACHE BOOL "Debugging/Trace output of OpenSync" ) +SET( OPENSYNC_DEBUG_MODULES FALSE CACHE BOOL "Debugging modules. Avoid unload of modules." ) +SET( OPENSYNC_UNITTESTS FALSE CACHE BOOL "Build OpenSync unit tests." ) +SET( OPENSYNC_PYTHONBINDINGS TRUE CACHE BOOL "Build OpenSync with Python bindings." ) + + Added: plugins/akonadi-sync/trunk/cmake/modules/OpenSyncPackaging.cmake ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ plugins/akonadi-sync/trunk/cmake/modules/OpenSyncPackaging.cmake Fri Sep 17 10:08:16 2010 (r6128) @@ -0,0 +1,9 @@ +MACRO( OPENSYNC_PACKAGE _name _version ) + + SET( CPACK_GENERATOR "TGZ;TBZ2" ) # This line is need for a CMake (Version 2.4.7) Bug - Fixed in CVS + SET( CPACK_SOURCE_GENERATOR "TGZ;TBZ2") + SET( CPACK_SOURCE_PACKAGE_FILE_NAME "${_name}-${_version}" ) + SET( CPACK_SET_DESTDIR ON ) + INCLUDE( CPack ) + +ENDMACRO( OPENSYNC_PACKAGE ) Added: plugins/akonadi-sync/trunk/cmake/modules/OpenSyncPlatforms.cmake ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ plugins/akonadi-sync/trunk/cmake/modules/OpenSyncPlatforms.cmake Fri Sep 17 10:08:16 2010 (r6128) @@ -0,0 +1,23 @@ +# Copyright (c) 2007 Daniel Gollub <go...@b1...> + +# OpenSync platform macros: + +SET( LIB_SUFFIX "" CACHE STRING "The library directory suffix. 32bit empty string, 64 for 64bit." ) + +IF (NOT WIN32) + SET( LIB_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}" ) + SET( LIBEXEC_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}" ) + SET( LIBDATA_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}" CACHE PATH "The library data directory." ) + SET( BIN_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/bin" ) + SET( SHARE_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/share" ) + SET( INCLUDE_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/include" ) +ELSE (NOT WIN32) + # Windows stuff goes here... + SET( LIB_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}" ) + SET( LIBEXEC_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}" ) + SET( LIBDATA_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}" CACHE PATH "The library data directory." ) + SET( BIN_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/bin" ) + SET( SHARE_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/share" ) + SET( INCLUDE_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/include" ) +ENDIF (NOT WIN32) + Added: plugins/akonadi-sync/trunk/cmake/modules/OpenSyncPlugin.cmake ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ plugins/akonadi-sync/trunk/cmake/modules/OpenSyncPlugin.cmake Fri Sep 17 10:08:16 2010 (r6128) @@ -0,0 +1,50 @@ +## Build OpenSync plugins as module +MACRO( OPENSYNC_PLUGIN_ADD _pluginName ) + + SET( CMAKE_SHARED_MODULE_PREFIX "" ) + ADD_LIBRARY( ${_pluginName} MODULE ${ARGN} ) + +ENDMACRO( OPENSYNC_PLUGIN_ADD ) + +## Build OpenSync format plugins as module +MACRO( OPENSYNC_FORMAT_ADD _formatName ) + + SET( CMAKE_SHARED_MODULE_PREFIX "" ) + ADD_LIBRARY( ${_formatName} MODULE ${ARGN} ) + +ENDMACRO( OPENSYNC_FORMAT_ADD ) + +## Install plugin +MACRO( OPENSYNC_PLUGIN_INSTALL _pluginName ) + INSTALL( TARGETS ${_pluginName} DESTINATION ${OPENSYNC_PLUGINDIR} ) +ENDMACRO( OPENSYNC_PLUGIN_INSTALL ) + +## Install external plugin +### Got introduced to be able in future to move those plugins into +### a seperated directory, without fixing all plugin build environments +MACRO( OPENSYNC_EXTERNAL_PLUGIN_INSTALL _pluginName ) + INSTALL( FILES ${_pluginName} DESTINATION ${OPENSYNC_PLUGINDIR} ) +ENDMACRO( OPENSYNC_EXTERNAL_PLUGIN_INSTALL ) + +## Install format plugin +MACRO( OPENSYNC_FORMAT_INSTALL _pluginName ) + INSTALL( TARGETS ${_pluginName} DESTINATION ${OPENSYNC_FORMATSDIR} ) +ENDMACRO( OPENSYNC_FORMAT_INSTALL ) + +## Install plugin description files +MACRO( OPENSYNC_PLUGIN_DESCRIPTIONS _descFiles ) + INSTALL( FILES ${_descFiles} DESTINATION ${OPENSYNC_DESCRIPTIONSDIR} ) +ENDMACRO( OPENSYNC_PLUGIN_DESCRIPTIONS ) + +## Install plugin capabilities files +MACRO( OPENSYNC_PLUGIN_CAPABILITIES _capFiles ) + INSTALL( FILES ${_capFiles} DESTINATION ${OPENSYNC_CAPABILITIESDIR} ) +ENDMACRO( OPENSYNC_PLUGIN_CAPABILITIES ) + +## Install plugin default configuration +MACRO( OPENSYNC_PLUGIN_CONFIG _pluginConfig ) + + INSTALL( FILES ${_pluginConfig} DESTINATION ${OPENSYNC_CONFIGDIR} ) + +ENDMACRO( OPENSYNC_PLUGIN_CONFIG ) + Added: plugins/akonadi-sync/trunk/src/CMakeLists.txt ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ plugins/akonadi-sync/trunk/src/CMakeLists.txt Fri Sep 17 10:08:16 2010 (r6128) @@ -0,0 +1,40 @@ + +#INCLUDE_DIRECTORIES( ${OPENSYNC_INCLUDE_DIRS} ${GLIB2_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/src ) +# + +SET( AKONADY_OPENSYNC_SRCS + akonadi_opensync.cpp + akonadisink.cpp + datasink.cpp + sinkbase.cpp +) + + +include_directories( ${AKONADI_INCLUDE_DIR} ${KDE4_INCLUDES} ${KDE4_INCLUDE_DIR} ${KDEPIMLIBS_INCLUDE_DIR} ) +include_directories( ${QT_INCLUDE_DIR} ) +# +include_directories( ${OPENSYNC_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR} "${CMAKE_CURRENT_SOURCE_DIR}/src" ${GLIB2_INCLUDE_DIR} ${GLIB2_MAIN_INCLUDE_DIR}) +include_directories( "../build/src") +# +link_directories( ${AKONADI_LIB_DIR} ${KDE4_LIB_DIR} ${KDEPIMLIBS_LIB_DIR} ${OPENSYNC_LIBRARIES_DIR} ${glib2LibDir} ) + +AUTOMOC4( akonadi-sync AKONADY_OPENSYNC_SRCS ) + + +OPENSYNC_PLUGIN_ADD( akonadi-sync ${AKONADY_OPENSYNC_SRCS} ) + +# ADD_DEPENDENCIES( akonadi-opensync akonadi_opensync.o akonadisink.o datasink.o sinkbase.o ) + +TARGET_LINK_LIBRARIES( akonadi-sync + ${OPENSYNC_LIBRARIES} + ${GLIB2_LIBRARIES} + ${KDE4_KDECORE_LIBS} + ${KDEPIMLIBS_AKONADI_LIBS} + ${KDEPIMLIBS_AKONADI_CONTACT_LIBS} + ${KDEPIMLIBS_KCAL_LIBS} +) + +###### INSTALL ################### +OPENSYNC_PLUGIN_INSTALL( akonadi-sync ) +OPENSYNC_PLUGIN_CONFIG( akonadi-sync ) +#INSTALL( FILES akonadi_opensync_plugin DESTINATION "/opt/testing/opensync" ) Added: plugins/akonadi-sync/trunk/src/akonadi-sync ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ plugins/akonadi-sync/trunk/src/akonadi-sync Fri Sep 17 10:08:16 2010 (r6128) @@ -0,0 +1,44 @@ +<?xml version="1.0"?> +<config version="1.0"> + <Resources> + <Resource> + <Enabled>1</Enabled> + <Formats> + <Format> + <Name>vcard30</Name> + </Format> + </Formats> + <ObjType>contact</ObjType> + </Resource> + <Resource> + <Enabled>1</Enabled> + <Formats> + <Format> + <Name>vevent20</Name> + </Format> + </Formats> + <ObjType>event</ObjType> + <Url>default</Url> + </Resource> + <Resource> + <Enabled>1</Enabled> + <Formats> + <Format> + <Name>vtodo20</Name> + </Format> + </Formats> + <ObjType>todo</ObjType> + <Url>default</Url> + </Resource> + <Resource> + <Enabled>1</Enabled> + <Formats> + <Format> + <Name>vjournal</Name> + </Format> + </Formats> + <ObjType>note</ObjType> + <Url>default</Url> + </Resource> + </Resources> +</config> Added: plugins/akonadi-sync/trunk/src/akonadi_opensync.cpp ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ plugins/akonadi-sync/trunk/src/akonadi_opensync.cpp Fri Sep 17 10:08:16 2010 (r6128) @@ -0,0 +1,284 @@ +/* + Copyright (c) 2008 Volker Krause <vk...@kd...> + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU Library 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 Library General Public + License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. +*/ + +#include "akonadisink.h" +#include "datasink.h" + +#include <akonadi/control.h> +#include <akonadi/collection.h> +#include <akonadi/collectionfetchjob.h> +#include <akonadi/mimetypechecker.h> + +#include <kabc/addressee.h> + +#include <KComponentData> +#include <KDebug> +#include <KUrl> +// for different sub mime types +#include <akonadi/kcal/incidencemimetypevisitor.h> + +#include <QCoreApplication> +#include <QStringList> + +#include <opensync/opensync.h> +#include <opensync/opensync-plugin.h> +#include <opensync/opensync-format.h> +#include <opensync/opensync-version.h> + +static KComponentData *kcd = 0; +static QCoreApplication *app = 0; + +static int fakeArgc = 0; +static char** fakeArgv = 0; + +extern "C" +{ + + static void* akonadi_initialize(OSyncPlugin *plugin, OSyncPluginInfo *info, OSyncError **error) + { + osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, plugin, info, error); + + if ( !app ) + app = new QCoreApplication( fakeArgc, fakeArgv ); + if ( !kcd ) + kcd = new KComponentData( "akonadi_opensync" ); + + // main sink + AkonadiSink *mainSink = new AkonadiSink(); + if ( !mainSink->initialize( plugin, info, error ) ) { + delete mainSink; + osync_trace(TRACE_EXIT_ERROR, "%s: NULL", __func__); + return 0; + } + + // object type sinks +// http://www.opensync.org/wiki/devel/pluginPortingGuide-0.40 +// 10) List looping is more standard +// --------------------------------- + + OSyncList *s = NULL, *list = osync_plugin_info_get_objtype_sinks(info); + for ( s = list; s; s = s->next ) { + OSyncObjTypeSink *sink = (OSyncObjTypeSink*) s->data; + QString sinkName( osync_objtype_sink_get_name( sink ) ); + kDebug() << "###" << sinkName; + osync_trace(TRACE_INTERNAL, " EKO %s", osync_objtype_sink_get_name( sink )); + + DataSink *ds = NULL; + if ( sinkName == "event" ) + ds = new DataSink( DataSink::Calendars ); + else if ( sinkName == "contact" ) + ds = new DataSink( DataSink::Contacts ); +// FIXME: implement todos an journal (notes) + else if ( sinkName == "todo" ) + ds = new DataSink( DataSink::Todos ); + else if ( sinkName == "note" ) + ds = new DataSink( DataSink::Notes ); + else + continue; + + if ( !ds->initialize( plugin, info, sink, error ) ) { + delete ds; + delete mainSink; + osync_trace(TRACE_EXIT_ERROR, "EKO %s: NULL", __func__); + return 0; + } + } + osync_trace(TRACE_EXIT, "EKO %s: %p", __func__, mainSink); + return mainSink; + + } + + static osync_bool akonadi_discover(OSyncPluginInfo *info, void *userdata, OSyncError **error ) + { + osync_trace(TRACE_ENTRY, "EKO %s(%p, %p, %p)", __func__, userdata, info, error); + kDebug(); + + if ( !Akonadi::Control::start() ) + return false; + + // fetch all akonadi collections + Akonadi::CollectionFetchJob *job = new Akonadi::CollectionFetchJob( + Akonadi::Collection::root(), Akonadi::CollectionFetchJob::Recursive ); + if ( !job->exec() ) + return false; + + Akonadi::Collection::List cols = job->collections(); + kDebug() << "found" << cols.count() << "collections"; + osync_trace(TRACE_INTERNAL, "EKO objs# %i", cols.count()); + + OSyncPluginConfig *config = osync_plugin_info_get_config( info ); + +// TODO do iteration on subtypes +// akonadi/kcal/incidencemimetypevisitor.h +// IncidenceMimeTypeVisitor *mimeTypeVisitor = new IncidenceMimeTypeVisitor(); + Akonadi::MimeTypeChecker contactMimeChecker; + contactMimeChecker.addWantedMimeType( KABC::Addressee::mimeType() ); +// Akonadi::MimeTypeChecker todoMimeChecker; +// todoMimeChecker.addWantedMimeType( mimeTypeVisitor->todoMimeType() ); + Akonadi::MimeTypeChecker eventMimeTypeChecker; + eventMimeTypeChecker.addWantedMimeType( QLatin1String( "text/calendar" ) ); + +// eventMimeTypeChecker.addWantedMimeType( QString ( mimeTypeVisitor->eventMimeType()) ); //was Latin1String +// Akonadi::MimeTypeChecker journalMimeTypeChecker; +// journalMimeTypeChecker.addWantedMimeType( QString ( mimeTypeVisitor->journalMimeType()) ); //was Latin1String +// Akonadi::MimeTypeChecker busyMimeTypeChecker; +// busyMimeTypeChecker.addWantedMimeType( QString ( mimeTypeVisitor->freeBusyMimeType()) ); //was Latin1String + +// http://www.opensync.org/wiki/devel/pluginPortingGuide-0.40 + OSyncList *s = NULL, *list = osync_plugin_info_get_objtype_sinks(info); + for ( s = list; s; s = s->next ) { + OSyncObjTypeSink *sink = (OSyncObjTypeSink*) s->data; + osync_objtype_sink_set_available( sink, TRUE ); + } + osync_list_free(list); + +//try to replace the resources with akonai native + foreach ( const Akonadi::Collection &col, cols ) { + kDebug() << "creating resource for" << col.name() << col.contentMimeTypes(); +// osync_trace(TRACE_ENTRY, "EKO %s ->mime: %s", col.name(), col.contentMimeTypes() ); + +// if ( !contactMimeChecker.isWantedCollection( col ) ) // ### TODO +// continue; +// if ( col.contentMimeTypes().isEmpty() ) +// continue; +//FIXME here we rather replace the existing ressources and not add new ones + + QString formatName; + OSyncObjTypeSink *sink = 0; + OSyncPluginResource *res = 0; + OSyncObjFormat *format = 0; + OSyncFormatEnv *formatenv = 0; + if ( eventMimeTypeChecker.isWantedCollection( col ) ) { + sink = osync_plugin_info_find_objtype(info, "event"); + res = osync_plugin_config_find_active_resource(config, "event"); + formatName = "vevent20"; //TODO get the Akonadi object format here + } + else if ( contactMimeChecker.isWantedCollection( col ) ) { + sink = osync_plugin_info_find_objtype(info, "contact"); + res = osync_plugin_config_find_active_resource(config, "contact"); + formatName = "vcard30"; + } +// TODO +// else if ( todoMimeChecker.isWantedCollection( col ) ) { +// sink = osync_plugin_info_find_objtype(info, "todo"); +// res = osync_plugin_config_find_active_resource(config, "todo"); +// formatName = "vtodo20"; +// } +// else if ( journalMimeTypeChecker.isWantedCollection( col ) ) { +// sink = osync_plugin_info_find_objtype(info, "note"); +// res = osync_plugin_config_find_active_resource(config, "note"); +// formatName = "vjournal"; +// } +// NOTE is this needed too? +// else if ( busyMimeTypeChecker.isWantedCollection( col ) ) { +// sink = osync_plugin_info_find_objtype(info, "note"); +// res = osync_plugin_config_find_active_resource(config, "note"); +// formatName = "vjournal"; +// } + else + continue; + +// find the object fomat + formatenv = osync_plugin_info_get_format_env( info ); + + OSyncList *objformatsinks = osync_plugin_resource_get_objformat_sinks(res); + for (OSyncList *r = objformatsinks;r;r = r->next) { + OSyncObjFormatSink *objformatsink = (OSyncObjFormatSink *) r->data; + if (strcmp(formatName.toLatin1(), osync_objformat_sink_get_objformat(objformatsink))) { + format = osync_format_env_find_objformat( formatenv, formatName.toLatin1() ); + break; + } + } +// // TODO error handling? + if ( ! osync_plugin_resource_is_enabled(res) ) + osync_plugin_resource_enable( res, TRUE ); + osync_plugin_resource_set_name( res, col.name().toLatin1() ); // TODO: full path instead of the name + osync_plugin_resource_set_url( res, col.url().url().toLatin1() );// FIXME do I need this +// osync_objtype_sink_enable_hashtable(sink, TRUE); +// { FIXME: Autoadding of format into the config magic I suppose +// OSyncObjFormat *format = osync_format_env_find_objformat(formatenv, "vevent20"); +// osync_plugin_resource_add_objformat_sink( res, osync_objformat_sink_new( formatName.toLatin1(), error ) ); +// +// osync_plugin_config_add_resource( config, res ); +// } + if ( sink ) + osync_plugin_resource_set_objtype( res, osync_objtype_sink_get_name( sink ) ); + osync_trace(TRACE_EXIT, "%s", __func__); + } + // set information about the peer (KDE itself) + { + OSyncVersion *version = osync_version_new(error); + osync_version_set_plugin(version, "Akonadi-sync"); + osync_version_set_softwareversion(version, "4.5"); + osync_plugin_info_set_version(info, version); + osync_version_unref(version); + } + return TRUE; + } + + static void akonadi_finalize(void *userdata) + { + osync_trace(TRACE_ENTRY, "%s(%p)", __func__, userdata); + kDebug(); + AkonadiSink *sink = reinterpret_cast<AkonadiSink*>( userdata ); + delete sink; + delete kcd; + kcd = 0; + delete app; + app = 0; + osync_trace(TRACE_EXIT, "%s", __func__); + } + + KDE_EXPORT osync_bool get_sync_info(OSyncPluginEnv *env, OSyncError **error) + { + osync_trace(TRACE_ENTRY, "%s(%p)", __func__, env); + + OSyncPlugin *plugin = osync_plugin_new( error ); + if ( !plugin ) { + osync_trace(TRACE_EXIT_ERROR, "%s: Unable to register: %s", __func__, osync_error_print(error)); + osync_error_unref(error); + return FALSE; + } + + osync_plugin_set_name(plugin, "akonadi-sync"); + osync_plugin_set_longname(plugin, "Akonadi"); + osync_plugin_set_description(plugin, "Plugin to synchronize with Akonadi"); +// osync_plugin_set_config_type(plugin, OSYNC_PLUGIN_NO_CONFIGURATION); + osync_plugin_set_initialize(plugin, akonadi_initialize); + osync_plugin_set_finalize(plugin, akonadi_finalize); + osync_plugin_set_discover(plugin, akonadi_discover); + osync_plugin_set_start_type(plugin, OSYNC_START_TYPE_PROCESS); + + if ( ! osync_plugin_env_register_plugin(env, plugin, error) ) { + osync_error_unref(error); + return FALSE; + } + + osync_plugin_unref(plugin); + osync_trace(TRACE_EXIT, "%s", __func__); + return TRUE; + + } + + KDE_EXPORT int get_version(void) + { + return 1; + } + +}// extern "C" Added: plugins/akonadi-sync/trunk/src/akonadisink.cpp ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ plugins/akonadi-sync/trunk/src/akonadisink.cpp Fri Sep 17 10:08:16 2010 (r6128) @@ -0,0 +1,60 @@ +/* + Copyright (c) 2008 Volker Krause <vk...@kd...> + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU Library 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 Library General Public + License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. +*/ + +#include "akonadisink.h" + +#include <akonadi/control.h> + +#include <KDebug> + +AkonadiSink::AkonadiSink() : + SinkBase( Connect ) +{ +} + +AkonadiSink::~AkonadiSink() +{ +} + +bool AkonadiSink::initialize(OSyncPlugin * plugin, OSyncPluginInfo * info, OSyncError ** error) +{ + Q_ASSERT( plugin ); + kDebug(); + OSyncObjTypeSink *sink = osync_objtype_main_sink_new( error ); + osync_plugin_info_set_main_sink( info, sink ); + wrapSink( sink ); + return true; +} + +void AkonadiSink::connect() +{ + osync_trace(TRACE_ENTRY, "%s(%p, %p)", __PRETTY_FUNCTION__, pluginInfo(), context()); + kDebug(); + + if ( !Akonadi::Control::start() ) { + error( OSYNC_ERROR_NO_CONNECTION, "Could not start Akonadi." ); + osync_trace(TRACE_EXIT_ERROR, "%s: %s", __PRETTY_FUNCTION__, "Could not start Akonadi."); + return; + } + + success(); + osync_trace(TRACE_EXIT, "%s", __PRETTY_FUNCTION__); +} + +#include "akonadisink.moc" Added: plugins/akonadi-sync/trunk/src/akonadisink.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ plugins/akonadi-sync/trunk/src/akonadisink.h Fri Sep 17 10:08:16 2010 (r6128) @@ -0,0 +1,41 @@ +/* + Copyright (c) 2008 Volker Krause <vk...@kd...> + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU Library 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 Library General Public + License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. +*/ + +#ifndef AKONADISINK_H +#define AKONADISINK_H + +#include "sinkbase.h" + +/** + * Main sink, does nothing but ensure Akonadi is running. + */ +class AkonadiSink : public SinkBase +{ + Q_OBJECT + + public: + AkonadiSink(); + ~AkonadiSink(); + + bool initialize( OSyncPlugin *plugin, OSyncPluginInfo *info, OSyncError **error ); + + void connect(); +}; + +#endif Added: plugins/akonadi-sync/trunk/src/datasink.cpp ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ plugins/akonadi-sync/trunk/src/datasink.cpp Fri Sep 17 10:08:16 2010 (r6128) @@ -0,0 +1,465 @@ +/* + Copyright (c) 2008 Volker Krause <vk...@kd...> + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU Library 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 Library General Public + License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. +*/ + +// #include <glib.h> +// #include <glib/ghash.h> + +#include "datasink.h" +// #include "plugin/opensync_plugin_info_internals.h" +// #include "plugin/opensync_objtype_sink_internals.h" +// #include "helper/opensync_hashtable_internals.h" + +#include <opensync/opensync.h> +#include <opensync/opensync-helper.h> +#include <opensync/opensync-plugin.h> +// #include <opensync/helper/opensync_hashtable.h> +// #include <opensync/helper/opensync_sink_state_db.h> +// #include <opensync/helper/opensync_hashtable.h> + +// calendar includes +#include <kcal/incidence.h> +#include <kcal/icalformat.h> + +// contact includes +#include <kabc/vcardconverter.h> +#include <kabc/addressee.h> + +// #include <glib/gtypes.h> +// #include <glib/glist.h> +// notes includes +// TODO + +#include <KDebug> +#include <KLocale> +#include <KUrl> + +using namespace Akonadi; + +typedef boost::shared_ptr<KCal::Incidence> IncidencePtr; + + +DataSink::DataSink( int type ) : + SinkBase( GetChanges | Commit | SyncDone ) +{ + m_type = type; +} + +DataSink::~DataSink() { +// kDebug() << "del ptr to hashtable"; +// if( m_hashtable ) +// delete m_hashtable ; +} + +bool DataSink::initialize(OSyncPlugin * plugin, OSyncPluginInfo * info, OSyncObjTypeSink *sink, OSyncError ** error) +{ + Q_UNUSED(plugin); + bool enabled = osync_objtype_sink_is_enabled( sink ); + if( ! enabled ) { + kDebug() << "sink is not enabled.."; + return false; + } + + OSyncPluginConfig *config = osync_plugin_info_get_config(info); + + if (!config) { + osync_error_set(error, OSYNC_ERROR_GENERIC, "Unable to get config."); + return false; + } + + wrapSink( sink ); + + // TODO do we need this check here - I don't think so + OSyncHashTable *hashtable = osync_objtype_sink_get_hashtable(sink); +// // + if( ! hashtable ) { + osync_trace(TRACE_INTERNAL, "EKO > %s: %s", __PRETTY_FUNCTION__, osync_error_print( error ) ); +// return false; + } +// // + return true; +} + +Akonadi::Collection DataSink::collection() const +{ + OSyncPluginConfig *config = osync_plugin_info_get_config( pluginInfo() ); + Q_ASSERT( config ); + + const char *objtype = osync_objtype_sink_get_name( sink() ); + + OSyncPluginResource *res = osync_plugin_config_find_active_resource( config, objtype ); + + if ( !res ) { + error( OSYNC_ERROR_MISCONFIGURATION, i18n("No active resource for type \"%1\" found", objtype ) ); + return Collection(); + } + + const KUrl url = KUrl( osync_plugin_resource_get_url( res ) ); + if ( url.isEmpty() ) { + error( OSYNC_ERROR_MISCONFIGURATION, i18n("Url for object type \"%1\" is not configured.", objtype ) ); + return Collection(); + } + + return Collection::fromUrl( url ); +} + +void DataSink::getChanges() +{ + OSyncError *oerror = 0; + // ### broken in OpenSync, I don't get valid configuration here! +// #if 1 + Collection col = collection(); + if ( !col.isValid() ) { + osync_trace( TRACE_EXIT_ERROR, "%s: %s", __PRETTY_FUNCTION__, osync_error_print( &oerror ) ); + return; + } +// #else +// Collection col( 409 ); +// #endif + + +// FIXME + if ( getSlowSink() ) { + kDebug() << "we're in the middle of slow-syncing..."; + osync_trace( TRACE_INTERNAL, "EKO Got slow-sync, resetting hashtable" ); + if ( ! osync_hashtable_slowsync( m_hashtable, &oerror ) ) { + warning( oerror ); + osync_trace( TRACE_EXIT_ERROR, "%s: %s", __PRETTY_FUNCTION__, osync_error_print( &oerror ) ); + return; + } + } + + ItemFetchJob *job = new ItemFetchJob( col ); + job->fetchScope().fetchFullPayload(); + osync_trace( TRACE_INTERNAL, "EKO fetchFullPayload" ); + + QObject::connect( job, SIGNAL( itemsReceived( const Akonadi::Item::List & ) ), this, SLOT( slotItemsReceived( const Akonadi::Item::List & ) ) ); + QObject::connect( job, SIGNAL( result( KJob * ) ), this, SLOT( slotGetChangesFinished( KJob * ) ) ); + + // FIXME give me a real eventloop please! + if ( !job->exec() ) { + error( OSYNC_ERROR_IO_ERROR, job->errorText() ); + return; + } +} + +void DataSink::slotItemsReceived( const Item::List &items ) +{ + kDebug() << "retrieved" << items.count() << "items"; + Q_FOREACH( const Item& item, items ) { + kDebug() << item.payloadData(); + reportChange( item ); + } +} + +void DataSink::reportChange( const Item& item ) +{ + OSyncFormatEnv *formatenv = osync_plugin_info_get_format_env( pluginInfo() ); + OSyncObjFormat *format = osync_format_env_find_objformat( formatenv, formatName().toLatin1() ); + + OSyncError *error = 0; + + OSyncChange *change = osync_change_new( &error ); + if ( !change ) { + warning( error ); + return; + } + + osync_change_set_uid( change, QString::number( item.id() ).toLatin1() ); + + error = 0; + + OSyncData *odata = osync_data_new( item.payloadData().data(), item.payloadData().size(), format, &error ); + if ( !odata ) { + osync_change_unref( change ); + warning( error ); + return; + } + osync_data_set_objtype( odata, osync_objtype_sink_get_name( sink() ) ); + + osync_change_set_data( change, odata ); + + kDebug() << item.id() << "DATA:" << osync_data_get_printable( odata , &error) << "\n" << "ORIG:" << item.payloadData().data(); + + osync_data_unref( odata ); + osync_change_set_hash( change, QString::number( item.revision() ).toLatin1() ); + OSyncChangeType changeType = osync_hashtable_get_changetype( m_hashtable, change ); + osync_change_set_changetype( change, changeType ); + + +/* +kDebug() << "changeid:" << osync_change_get_uid( change ) + << "itemid:" << item.id() + << "revision:" << item.revision() + << "changetype:" << changeType + << "hash:" << osync_hashtable_get_hash( m_hashtable, osync_change_get_uid( change ) ) + << "objtype:" << osync_change_get_objtype( change ) + << "objform:" << osync_objformat_get_name( osync_change_get_objformat( change ) ) + << "sinkname:" << osync_objtype_sink_get_name( sink() ); +*/ + + if ( changeType != OSYNC_CHANGE_TYPE_UNMODIFIED ) + osync_context_report_change( context(), change ); + else + // perhaps this should be only called when an error has happened ie. never after _context_report_change()? + osync_change_unref( change ); // if this gets called, we get broken pipes. any ideas? +} + +void DataSink::slotGetChangesFinished( KJob * ) +{ + OSyncFormatEnv *formatenv = osync_plugin_info_get_format_env( pluginInfo() ); + OSyncObjFormat *format = osync_format_env_find_objformat( formatenv, formatName().toLatin1() ); + + // after the items have been processed, see what's been deleted and send them to opensync + OSyncError *error = 0; +// FIXME: + OSyncList *u, *uids = osync_hashtable_get_deleted( m_hashtable ); +// + for( u = uids; u; u = u->next) { + QString uid( (char *)u->data ); + kDebug() << "going to delete with uid:" << uid; + + OSyncChange *change = osync_change_new( &error ); + if( !change ) { + warning( error ); + continue; + } +// + osync_change_set_changetype( change, OSYNC_CHANGE_TYPE_DELETED ); + osync_change_set_uid( change, uid.toLatin1() ); + + error = 0; + OSyncData *data = osync_data_new( 0, 0, format, &error ); + if( !data ) { + osync_change_unref( change ); + warning( error ); + continue; + } +// + osync_data_set_objtype( data, osync_objtype_sink_get_name( sink() ) ); + osync_change_set_data( change, data ); + + osync_hashtable_update_change( m_hashtable, change ); + + osync_change_unref( change ); + } + osync_list_free( uids ); + + kDebug() << "got all changes.."; + success(); +} + +void DataSink::commit(OSyncChange *change) +{ + kDebug() << "change uid:" << osync_change_get_uid( change ); + kDebug() << "objtype:" << osync_change_get_objtype( change ); + kDebug() << "objform:" << osync_objformat_get_name (osync_change_get_objformat( change ) ); + + switch( osync_change_get_changetype( change ) ) { + case OSYNC_CHANGE_TYPE_ADDED: { + const Item item = createItem( change ); + osync_change_set_uid( change, QString::number( item.id() ).toLatin1() ); + osync_change_set_hash( change, QString::number( item.revision() ).toLatin1() ); + kDebug() << "ADDED:" << osync_change_get_uid( change ); + break; } + + case OSYNC_CHANGE_TYPE_MODIFIED: { + const Item item = modifyItem( change ); + osync_change_set_uid( change, QString::number( item.id() ).toLatin1() ); + osync_change_set_hash( change, QString::number( item.revision() ).toLatin1() ); + kDebug() << "MODIFIED:" << osync_change_get_uid( change ); + break; } + + case OSYNC_CHANGE_TYPE_DELETED: { + deleteItem( change ); + kDebug() << "DELETED:" << osync_change_get_uid( change ); + break; } + + case OSYNC_CHANGE_TYPE_UNMODIFIED: { + kDebug() << "UNMODIFIED"; + // should we do something here? + break; } + + default: + kDebug() << "got invalid changetype?"; + } + + osync_hashtable_update_change( m_hashtable, change ); + success(); +} + +const Item DataSink::createItem( OSyncChange *change ) +{ + Collection col = collection(); + if ( !col.isValid() ) // error handling + return Item(); + kDebug() << "cuid:" << osync_change_get_uid( change ); + + ItemCreateJob *job = new Akonadi::ItemCreateJob( createAkonadiItem( change ), col ); + + if( ! job->exec() ) + kDebug() << "creating an item failed"; + + return job->item(); // handle !job->exec in return too.. +} + +const Item DataSink::modifyItem( OSyncChange *change ) +{ + char *plain = 0; + osync_data_get_data( osync_change_get_data( change ), &plain, /*size*/0 ); + QString str = QString::fromUtf8( plain ); + + QString id = QString( osync_change_get_uid( change ) ); + Item item = fetchItem( id ); + if( ! item.isValid() ) // TODO proper error handling + return Item(); + + //event.setMimeType( "application/x-vnd.akonadi.calendar.event" ); + //Item newItem = createAkonadiItem( change ); + setPayload(&item, str); + ItemModifyJob *modifyJob = new Akonadi::ItemModifyJob( item ); + if( modifyJob->exec() ) { + kDebug() << "modification completed"; + return modifyJob->item(); + } + else + kDebug() << "unable to modify"; + + + return Item(); +} + +void DataSink::deleteItem( OSyncChange *change ) +{ + QString id = QString( osync_change_get_uid( change ) ); + Item item = fetchItem( id ); + if( ! item.isValid() ) // TODO proper error handling + return; + + kDebug() << "delete with id: " << item.id(); + /*ItemDeleteJob *job = new ItemDeleteJob( item ); + + if( job->exec() ) { + kDebug() << "item deleted"; + } + else + kDebug() << "unable to delete item";*/ +} + +bool DataSink::setPayload( Item *item, const QString &str ) +{ + switch( m_type ) { + case Calendars: { + KCal::ICalFormat format; + KCal::Incidence *calEntry = format.fromString( str ); + + item->setMimeType( "application/x-vnd.akonadi.calendar.event" ); + item->setPayload<IncidencePtr>( IncidencePtr( calEntry->clone() ) ); + + break; + } + case Contacts: { + KABC::VCardConverter converter; + KABC::Addressee vcard = converter.parseVCard( str.toLatin1() ); + kDebug() << vcard.uid() << vcard.name(); + + item->setMimeType( KABC::Addressee::mimeType() ); + // item->setPayload<KABC::Addressee>( str ); // FIXME + item->setPayloadFromData( str.toLatin1() ); // FIXME + break; + } + case Notes: { + kDebug() << "notes"; + break; + } + case Todos: { + kDebug() << "todos"; + break; + } + default: + // should not happen + return false; + } + + return true; +} + +const Item DataSink::createAkonadiItem( OSyncChange *change ) +{ + char *plain = 0; + osync_data_get_data( osync_change_get_data( change ), &plain, /*size*/0 ); + QString str = QString::fromUtf8( plain ); + Akonadi::Item item; + setPayload(&item, str); + return item; +} + +const QString DataSink::formatName() +{ + // FIXME -- this should be saved somewhere in the config, why settign and checking here: + QString formatName; + switch( m_type ) { + case Calendars: + formatName = "vevent20"; + break; + case Contacts: + formatName = "vcard10"; + break; + case Notes: + formatName = "vjournal"; + break; + case Todos: + formatName = "vtodo20"; + break; + default: + kDebug() << "invalid datasink type"; + return QString(); + } + + return formatName; +} + +const Item DataSink::fetchItem( const QString& id ) +{ + ItemFetchJob *fetchJob = new ItemFetchJob( Item( id ) ); + fetchJob->fetchScope().fetchFullPayload(); + + if( fetchJob->exec() ) { + foreach ( const Item &item, fetchJob->items() ) { + if( QString::number( item.id() ) == id ) { + kDebug() << "got item"; + return item; + } + } + } + + // no such item found? + return Item(); +} + +void DataSink::syncDone() +{ + kDebug(); +// OSyncError *error = 0; +// osync_objtype_sink_sync_done( m_hashtable, &error ); + + //TODO check for errors + success(); +} + +#include "datasink.moc" Added: plugins/akonadi-sync/trunk/src/datasink.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ plugins/akonadi-sync/trunk/src/datasink.h Fri Sep 17 10:08:16 2010 (r6128) @@ -0,0 +1,103 @@ +/* + Copyright (c) 2008 Volker Krause <vk...@kd...> + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU Library 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 Library General Public + License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. +*/ + +#ifndef DATASINK_H +#define DATASINK_H + +#include "sinkbase.h" + +#include <akonadi/collection.h> +#include <akonadi/itemfetchjob.h> +#include <akonadi/itemcreatejob.h> +#include <akonadi/itemmodifyjob.h> +#include <akonadi/itemfetchscope.h> + +#include <opensync/opensync.h> +#include <opensync/opensync-plugin.h> +#include <opensync/opensync-data.h> +#include <opensync/opensync-format.h> + +#include <boost/shared_ptr.hpp> + +using namespace Akonadi; + +/** + * Base class for data sink classes, dealing with the type-independent stuff. + */ +class DataSink : public SinkBase +{ + Q_OBJECT + + public: + enum Type { Calendars = 0, Contacts, Todos, Notes }; + + DataSink( int type ); + ~DataSink(); + + bool initialize( OSyncPlugin *plugin, OSyncPluginInfo *info, OSyncObjTypeSink *sink, OSyncError **error ); + + void getChanges(); + void commit( OSyncChange *change ); + void syncDone(); + + public slots: + void slotGetChangesFinished( KJob * ); + void slotItemsReceived( const Akonadi::Item::List & ); + + protected: + /** + * Returns the collection we are supposed to sync with. + */ + Akonadi::Collection collection() const; + + /** + * This reports the change back to opensync + */ + void reportChange( const Item& item, const QString& format ); + + /** + * Reimplement in subclass to provide data about changes to opensync. Note, that you must call DataSink::reportChange( Item, QString, int ) after you have organized data to be send to opensync. + */ + void reportChange( const Item & item ); + + /** + * Creates a new item based on the data given by opensync. + */ + const Item createItem( OSyncChange *change ); + /** + * Modified an item based on the data given by opensync. + */ + const Item modifyItem( OSyncChange *change ); + /** + * Deletes an item based on the data given by opensync. + */ + void deleteItem( OSyncChange *change ); + + private: + const Item createAkonadiItem( OSyncChange *change ); + const Item fetchItem( const QString& id ); + const QString formatName(); + bool setPayload( Item *item, const QString &str ); + + private: + OSyncHashTable *m_hashtable; + int m_type; +}; + +#endif Added: plugins/akonadi-sync/trunk/src/sinkbase.cpp ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ plugins/akonadi-sync/trunk/src/sinkbase.cpp Fri Sep 17 10:08:16 2010 (r6128) @@ -0,0 +1,241 @@ +/* + Copyright (c) 2008 Volker Krause <vk...@kd...> + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU Library 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 Library General Public + License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. +*/ + +#include "sinkbase.h" +#include <KDebug> + +#define WRAP0(X) \ + osync_trace( TRACE_ENTRY, "%s(%p,%p, %p, %p)", __PRETTY_FUNCTION__, sink, userdata, info, ctx); \ + SinkBase *sb = reinterpret_cast<SinkBase*>(userdata ); \ + sb->setContext( ctx ); \ + sb->setPluginInfo( info ); \ + sb->X; \ + osync_trace( TRACE_EXIT, "%s", __PRETTY_FUNCTION__ ); + +#define WRAP1(X) \ + osync_trace( TRACE_ENTRY, "%s(%p,%p, %p, %p)", __PRETTY_FUNCTION__, sink, userdata, info, ctx); \ + SinkBase *sb = reinterpret_cast<SinkBase*>(userdata ); \ + if ( slow_sync ) sb->setSlowSink(slow_sync); \ + sb->setContext( ctx ); \ + sb->setPluginInfo( info ); \ + sb->X; \ + osync_trace( TRACE_EXIT, "%s", __PRETTY_FUNCTION__ ); + + + +extern "C" +{ + + static void connect_wrapper(OSyncObjTypeSink *sink, OSyncPluginInfo *info, OSyncContext *ctx, void *userdata ) +{ + WRAP0( connect() ) +} + +static void disconnect_wrapper(OSyncObjTypeSink *sink, OSyncPluginInfo *info, OSyncContext *ctx, void *userdata) { + WRAP0( disconnect() ) +} + +static void contact_get_changes_wrapper(OSyncObjTypeSink *sink, OSyncPluginInfo *info, OSyncContext *ctx, osync_bool slow_sync, void *userdata) { + + WRAP1 ( getChanges() ) +} +// + +static void contact_sync_done_wrapper(OSyncObjTypeSink *sink, OSyncPluginInfo *info, OSyncContext *ctx, void *userdata) { + WRAP0( syncDone() ) +} + +static void event_get_changes_wrapper(OSyncObjTypeSink *sink, OSyncPluginInfo *info, OSyncContext *ctx, osync_bool slow_sync, void *userdata) { + WRAP1( getChanges() ) +} +// +static void event_sync_done_wrapper(OSyncObjTypeSink *sink, OSyncPluginInfo *info, OSyncContext *ctx, void *userdata) { + WRAP0( syncDone() ) +} + + +static void todo_get_changes_wrapper(OSyncObjTypeSink *sink, OSyncPluginInfo *info, OSyncContext *ctx, osync_bool slow_sync, void *userdata) { + WRAP1( getChanges() ) +} +// + +static void todo_sync_done_wrapper(OSyncObjTypeSink *sink, OSyncPluginInfo *info, OSyncContext *ctx, void *userdata) { + WRAP0( syncDone() ) +} + +static void journal_get_changes_wrapper(OSyncObjTypeSink *sink, OSyncPluginInfo *info, OSyncContext *ctx, osync_bool slow_sync, void *userdata) { + WRAP1( getChanges() ) +} +// + +static void journal_sync_done_wrapper(OSyncObjTypeSink *sink, OSyncPluginInfo *info, OSyncContext *ctx, void *userdata) { + WRAP0( syncDone() ) +} +// +static void commit_wrapper(OSyncObjTypeSink *sink, OSyncPluginInfo *info, OSyncContext *ctx, OSyncChange *change, void *userdata) { + WRAP0( commit(change) ) +} + +} // extern C + + +SinkBase::SinkBase( int features ) : + mContext( 0 ), + mSink( 0 ), + mPluginInfo( 0 ) +{ + + m_canConnect = ( features & Connect ) ? true : false; + m_canDisconnect = ( features & Disconnect ) ? true : false; + m_canGetChanges = ( features & GetChanges ) ? true : false; + m_canCommit = ( features & Commit ) ? true : false; + m_canWrite = ( features & Write ) ? true : false; + m_canCommitAll = ( features & CommittedAll ) ? true : false; + m_canRead = ( features & Read ) ? true : false; + m_canBatchCommit = ( features & BatchCommit ) ? true : false; + m_canSyncDone = ( features & SyncDone ) ? true : false; + +} + +SinkBase::~SinkBase() +{ + if ( mSink ) + osync_objtype_sink_unref( mSink ); +} + +void SinkBase::connect() +{ + Q_ASSERT( false ); +} + +void SinkBase::setSlowSink(osync_bool s) +{ + Q_ASSERT( m_SlowSync ); + m_SlowSync = s; +} + +osync_bool SinkBase::getSlowSink() +{ + Q_ASSERT( m_SlowSync ); + return m_SlowSync; +} + +void SinkBase::disconnect() +{ + Q_ASSERT( false ); +} + +void SinkBase::getChanges() +{ + Q_ASSERT( false ); +} + +void SinkBase::commit(OSyncChange * chg) +{ + Q_UNUSED( chg ); + Q_ASSERT( false ); +} + +void SinkBase::syncDone() +{ + Q_ASSERT( false ); +} + +void SinkBase::success() const +{ +kDebug(); + Q_ASSERT( mContext ); + osync_context_report_success( mContext ); + mContext = 0; +} + +void SinkBase::error(OSyncErrorType type, const QString &msg) const +{ + kDebug(); + Q_ASSERT( mContext ); + osync_context_report_error(mContext, type, "%s", msg.toLatin1().data() ); + mContext = 0; +} + +void SinkBase::warning(OSyncError * error) const +{ +kDebug(); + Q_ASSERT( mContext ); + osync_context_report_osyncwarning( mContext, error ); + osync_error_unref( &error ); +} + +void SinkBase::wrapSink(OSyncObjTypeSink* sink) +{ + kDebug(); + Q_ASSERT( sink ); + Q_ASSERT( mSink == 0 ); + mSink = sink; + + if ( m_canConnect ) + osync_objtype_sink_set_connect_func(sink, connect_wrapper); + if ( m_canDisconnect ) + osync_objtype_sink_set_disconnect_func(sink, disconnect_wrapper); + + if ( m_canGetChanges && m_hasContact ) + osync_objtype_sink_set_get_changes_func(sink, contact_get_changes_wrapper); + if ( m_canGetChanges && m_hasEvent ) + osync_objtype_sink_set_get_changes_func(sink, event_get_changes_wrapper); + if ( m_canGetChanges && m_hasTodo ) + osync_objtype_sink_set_get_changes_func(sink, todo_get_changes_wrapper); + if ( m_canGetChanges && m_hasNote ) + osync_objtype_sink_set_get_changes_func(sink, journal_get_changes_wrapper); + + if ( m_canCommit ) + osync_objtype_sink_set_commit_func(sink, commit_wrapper); +// TODO: check if relevant for akonadi +// if ( m_canWrite ) +// osync_objtype_sink_set_commit_func(sink, 0); +// if ( m_canCommitAll ) +// osync_objtype_sink_set_commit_func(sink, 0); +// if ( m_canRead ) +// osync_objtype_sink_set_commit_func(sink, 0); +// if ( m_canBatchCommit ) +// osync_objtype_sink_set_commit_func(sink, 0); + if ( m_canSyncDone && m_hasContact ) + osync_objtype_sink_set_sync_done_func(sink, contact_sync_done_wrapper); + if ( m_canSyncDone && m_hasEvent ) + osync_objtype_sink_set_sync_done_func(sink, event_sync_done_wrapper); + if ( m_canSyncDone && m_hasTodo ) + osync_objtype_sink_set_sync_done_func(sink, todo_sync_done_wrapper); + if ( m_canSyncDone && m_hasNote ) + osync_objtype_sink_set_sync_done_func(sink, journal_sync_done_wrapper); + +} + +void SinkBase::setPluginInfo(OSyncPluginInfo * info) +{ + Q_ASSERT( mPluginInfo == 0 || mPluginInfo == info ); + mPluginInfo = info; +} + +void SinkBase::setContext(OSyncContext * context) +{ + Q_ASSERT( mContext == 0 || context == mContext ); + // ### do I need to ref() that here? and then probably deref() the old one somewhere above? + mContext = context; +} + + +#include "sinkbase.moc" Added: plugins/akonadi-sync/trunk/src/sinkbase.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ plugins/akonadi-sync/trunk/src/sinkbase.h Fri Sep 17 10:08:16 2010 (r6128) @@ -0,0 +1,85 @@ +/* + Copyright (c) 2008 Volker Krause <vk...@kd...> + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU Library 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 Library General Public + License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. +*/ + +#ifndef SINKBASE_H +#define SINKBASE_H + +#include <QObject> + +#include <opensync/opensync.h> +#inc... [truncated message content] |