Hello community,

here is the log from the commit of package libkolab for openSUSE:Factory 
checked in at 2013-01-17 11:16:32
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/libkolab (Old)
 and      /work/SRC/openSUSE:Factory/.libkolab.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "libkolab", Maintainer is ""

Changes:
--------
--- /work/SRC/openSUSE:Factory/libkolab/libkolab.changes        2012-12-07 
14:40:04.000000000 +0100
+++ /work/SRC/openSUSE:Factory/.libkolab.new/libkolab.changes   2013-01-17 
13:18:19.000000000 +0100
@@ -1,0 +2,14 @@
+Thu Jan  3 15:10:15 UTC 2013 - [email protected]
+
+- New upstream version 0.4.1
+  * Timezone handling bugfixes
+  * Distributions list bugfixes
+- Added Patch: fix_php5_bindings.diff to fix php bindings
+  * Patch to hack SWIGUtils.cmake to find PHP5 on openSUSE
+
+-------------------------------------------------------------------
+Thu Dec 20 00:46:35 UTC 2012 - [email protected]
+
+- Added php and python bindings
+
+-------------------------------------------------------------------

Old:
----
  libkolab-0.4.0.tar.gz

New:
----
  fix_php5_bindings.diff
  libkolab-0.4.1.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ libkolab.spec ++++++
--- /var/tmp/diff_new_pack.WF0uud/_old  2013-01-17 13:18:20.000000000 +0100
+++ /var/tmp/diff_new_pack.WF0uud/_new  2013-01-17 13:18:20.000000000 +0100
@@ -16,19 +16,27 @@
 #
 
 
-#
-%define SONAME 0
+%global phpdir php5
+%global php_extdir %{_libdir}/%{phpdir}/extensions
+%global php_inidir %{_sysconfdir}/%{phpdir}/conf.d
+
 Name:           libkolab
-Version:        0.4.0
+Version:        0.4.1
 Release:        0
+%define soname  0
 Summary:        Conversions from/to KDE containers
 License:        LGPL-2.0+ and LGPL-3.0+ and AGPL-3.0+
 Group:          Development/Libraries/C and C++
 Url:            http://wiki.kolab.org/Kolab_3.0_development#libkolab
 Source:         
http://mirror.kolabsys.com/pub/releases/%{name}-%{version}.tar.gz
+# Patch to hack SWIGUtils.cmake to find PHP5 on openSUSE
+Patch0:         fix_php5_bindings.diff
 BuildRequires:  libkdepimlibs4-devel
 BuildRequires:  libkolabxml-devel
 BuildRequires:  libxerces-c-devel
+BuildRequires:  php5-devel
+BuildRequires:  python-devel
+BuildRequires:  swig
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
 
 %description
@@ -36,19 +44,39 @@
 to read and write kolabv2 and kolabv3.
 The Akonadi-Kolab-Resource as well as the upgradetool are based on this code.
 
-%package -n %{name}%{SONAME}
+%package -n %{name}%{soname}
 Summary:        Conversions from/to KDE containers
 Group:          Development/Libraries/C and C++
 
-%description -n %{name}%{SONAME}
+%description -n %{name}%{soname}
 libkolab provides conversions from/to KDE containers, mime message handling 
and facilities
 to read and write kolabv2 and kolabv3.
 The Akonadi-Kolab-Resource as well as the upgradetool are based on this code.
 
+%package -n php-%{name}%{soname}
+Summary:        PHP Bindings for libkolab
+Group:          Development/Languages/Other
+Provides:       php-kolab = %{version}
+
+%description -n php-%{name}%{soname}
+libkolab provides conversions from/to KDE containers, mime message handling 
and facilities
+to read and write kolabv2 and kolabv3.
+This package provides PHP Bindings for libkolab.
+
+%package -n python-%{name}%{soname}
+Summary:        Python bindings for libkolab
+Group:          Development/Languages/Python
+Provides:       python-kolab = %{version}
+
+%description -n python-%{name}%{soname}
+libkolab provides conversions from/to KDE containers, mime message handling 
and facilities
+to read and write kolabv2 and kolabv3.
+This package provides Python bindings for libkolab.
+
 %package devel
 Summary:        Conversions from/to KDE containers
 Group:          Development/Libraries/C and C++
-Requires:       %{name}%{SONAME} = %{version}
+Requires:       %{name}%{soname} = %{version}
 Requires:       libkdepimlibs4-devel
 Requires:       libkolabxml-devel
 Requires:       libxerces-c-devel
@@ -60,6 +88,7 @@
 
 %prep
 %setup -q
+%patch0 -p0
 
 %build
   export CXXFLAGS="%{optflags}"
@@ -72,6 +101,8 @@
         -DLIB_INSTALL_DIR="%{_lib}" \
         -DCMAKE_SKIP_RPATH=TRUE \
         -DCMAKE_BUILD_TYPE=RELEASE \
+        -DPHP_BINDINGS=TRUE -DPHP_INSTALL_DIR=%{php_extdir} \
+        -DPYTHON_BINDINGS=TRUE -DPYTHON_INSTALL_DIR=%{python_sitearch} \
         ..
 
   make %{?_smp_mflags}
@@ -80,15 +111,48 @@
   cd build
   make DESTDIR=%{buildroot} install
 
-%post -n %{name}%{SONAME} -p /sbin/ldconfig
+  mkdir -p %{buildroot}/%{_datadir}/%{phpdir}
+  mv %{buildroot}/%{php_extdir}/*.php %{buildroot}/%{_datadir}/%{phpdir}/.
 
-%postun -n %{name}%{SONAME} -p /sbin/ldconfig
+  mkdir -p %{buildroot}/%{php_inidir}
+  cat >%{buildroot}/%{php_inidir}/kolab.ini <<EOF
+; Kolab libraries
+extension=kolabformat.so
+extension=kolabshared.so
+extension=kolabobject.so
+extension=kolabcalendaring.so
+EOF
 
-%files -n %{name}%{SONAME}
+%post -n %{name}%{soname} -p /sbin/ldconfig
+%postun -n %{name}%{soname} -p /sbin/ldconfig
+
+%files -n %{name}%{soname}
 %defattr(-,root,root)
 %doc COPYING* README RELEASE-NOTES
 %{_libdir}/libkolab.so.*
 
+%files -n php-%{name}%{soname}
+%defattr(-,root,root)
+%config(noreplace) %{php_inidir}/kolab.ini
+%{_datadir}/%{phpdir}/kolabcalendaring.php
+%{php_extdir}/kolabcalendaring.so
+%{_datadir}/%{phpdir}/kolabicalendar.php
+%{php_extdir}/kolabicalendar.so
+%{_datadir}/%{phpdir}/kolabobject.php
+%{php_extdir}/kolabobject.so
+%{_datadir}/%{phpdir}/kolabshared.php
+%{php_extdir}/kolabshared.so
+
+%files -n python-%{name}%{soname}
+%defattr(-,root,root)
+%dir %{python_sitearch}/kolab
+%{python_sitearch}/kolab/_calendaring.so
+%{python_sitearch}/kolab/calendaring.py*
+%{python_sitearch}/kolab/_icalendar.so
+%{python_sitearch}/kolab/icalendar.py*
+%{python_sitearch}/kolab/_shared.so*
+%{python_sitearch}/kolab/shared.py*
+
 %files devel
 %defattr(-,root,root)
 %{_includedir}/kolab/

++++++ fix_php5_bindings.diff ++++++
--- cmake/modules/SWIGUtils.cmake       2012-12-21 11:08:18.437827039 +0100
+++ cmake/modules/SWIGUtils.cmake       2012-12-21 11:19:28.958789211 +0100
@@ -24,28 +24,59 @@ macro (generatePHPBindings MODULE_NAME I
         set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused" )
     endif()
 
-    find_package(PHP4 5.3 REQUIRED)
-
-    if (PHP4_FOUND)
-        include_directories(${PHP4_INCLUDE_PATH})
-        add_library(${MODULE_NAME}_phpbindings SHARED 
${KOLAB_SWIG_PHP_SOURCE_FILE})
-        target_link_libraries(${MODULE_NAME}_phpbindings kolab)
-        SET_TARGET_PROPERTIES(${MODULE_NAME}_phpbindings PROPERTIES 
OUTPUT_NAME ${MODULE_NAME})
-        SET_TARGET_PROPERTIES(${MODULE_NAME}_phpbindings PROPERTIES PREFIX "")
-
-    #     configure_file(test.php ${CMAKE_CURRENT_BINARY_DIR} COPYONLY)
-
-        set(PHP_INSTALL_DIR "${CMAKE_CURRENT_BINARY_DIR}/phpbindings" CACHE 
STRING "Install directory for php bindings.")
-
-        install(TARGETS ${MODULE_NAME}_phpbindings LIBRARY DESTINATION 
${PHP_INSTALL_DIR})
-
-        install( FILES
-            ${CMAKE_CURRENT_BINARY_DIR}/${MODULE_NAME}.php
-            DESTINATION ${PHP_INSTALL_DIR}
+    # Try to find PHP5
+    find_path(PHP_INCLUDE_DIR NAMES main/php.h PATH_SUFFIXES php php5)
+    find_program(PHP_EXECUTABLE NAMES php)
+    
+    # Libkolabxml needs PHP >= 5.3
+    set(PHP_MIN_VERSION 50300)
+    
+    # Find where to install the extension files if it's not defined
+    if(NOT DEFINED PHP_INSTALL_DIR)
+      find_program(PHP_CONFIG_EXECUTABLE NAMES php-config)
+      if(PHP_CONFIG_EXECUTABLE)
+        execute_process(COMMAND ${PHP_CONFIG_EXECUTABLE} --extension-dir
+                        OUTPUT_VARIABLE _php_extensions_dir
         )
-    else(PHP4_FOUND)
-        message(WARNING "not building php bindings because php was not found")
-    endif (PHP4_FOUND)
+        string(REGEX REPLACE "\n" "" _php_extensions_dir 
"${_php_extensions_dir}")
+        set(PHP_INSTALL_DIR ${_php_extensions_dir} CACHE STRING "Install 
directory for PHP bindings.")
+      else()
+        set(PHP_INSTALL_DIR ${LIB_INSTALL_DIR}/extensions)
+      endif()
+    endif()
+    
+    if(PHP_INCLUDE_DIR AND PHP_EXECUTABLE)
+      file(READ ${PHP_INCLUDE_DIR}/main/php_version.h PHP_VERSION_CONTENT)
+      string(REGEX MATCH "#define PHP_VERSION_ID[ ]*[0-9]*\n" 
_PHP_VERSION_ID_MATCH ${PHP_VERSION_CONTENT})
+      if(_PHP_VERSION_ID_MATCH)
+        string(REGEX REPLACE "#define PHP_VERSION_ID[ ]*([0-9]*)\n" "\\1" 
PHP_VERSION_ID ${_PHP_VERSION_ID_MATCH})
+      endif()
+
+      # Include the needed PHP5 subdirs
+      set(PHP_INCLUDE_DIRS ${PHP_INCLUDE_DIR} ${PHP_INCLUDE_DIR}/main 
${PHP_INCLUDE_DIR}/TSRM ${PHP_INCLUDE_DIR}/Zend )
+    endif()
+    
+    if(NOT PHP_VERSION_ID VERSION_LESS ${PHP_MIN_VERSION})
+      include_directories(${PHP_INCLUDE_DIRS})
+      add_library(${MODULE_NAME}_phpbindings SHARED 
${KOLAB_SWIG_PHP_SOURCE_FILE})
+      target_link_libraries(${MODULE_NAME}_phpbindings kolab)
+      set_target_properties(${MODULE_NAME}_phpbindings PROPERTIES OUTPUT_NAME 
${MODULE_NAME})
+      set_target_properties(${MODULE_NAME}_phpbindings PROPERTIES PREFIX "")
+    
+      #configure_file(test.php ${CMAKE_CURRENT_BINARY_DIR} COPYONLY)
+    
+      set(PHP_INSTALL_DIR "${CMAKE_CURRENT_BINARY_DIR}/phpbindings" CACHE 
STRING "Install directory for php bindings.")
+      
+      install(TARGETS ${MODULE_NAME}_phpbindings LIBRARY DESTINATION 
${PHP_INSTALL_DIR})
+    
+      install( FILES
+              ${CMAKE_CURRENT_BINARY_DIR}/${MODULE_NAME}.php
+              DESTINATION ${PHP_INSTALL_DIR}
+          )
+    
+    else()
+      message(WARNING "not building php bindings because php was not found")
+    endif()
 endmacro()
 
 
@@ -97,4 +128,4 @@ macro(generatePythonBindings MODULE_NAME
         DESTINATION ${PYTHON_INSTALL_DIR}/kolab
     )
 
-endmacro()
\ Kein Zeilenumbruch am Dateiende.
+endmacro()
++++++ libkolab-0.4.0.tar.gz -> libkolab-0.4.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libkolab-0.4.0/CMakeLists.txt 
new/libkolab-0.4.1/CMakeLists.txt
--- old/libkolab-0.4.0/CMakeLists.txt   2012-11-11 17:30:47.000000000 +0100
+++ new/libkolab-0.4.1/CMakeLists.txt   2013-01-09 13:59:23.000000000 +0100
@@ -33,10 +33,10 @@
 set(Libkolab_VERSION_MAJOR 0)
 set(Libkolab_VERSION_MINOR 4)
 # Enable the full x.y.z version only for release versions
-#set(Libkolab_VERSION_PATCH 1)
-#set(Libkolab_VERSION 
${Libkolab_VERSION_MAJOR}.${Libkolab_VERSION_MINOR}.${Libkolab_VERSION_PATCH} )
-set(Libkolab_VERSION ${Libkolab_VERSION_MAJOR}.${Libkolab_VERSION_MINOR} )
-set(Libkolab_VERSION_STRING ${CMAKE_PROJECT_NAME}-${Libkolab_VERSION})
+set(Libkolab_VERSION_PATCH 1)
+set(Libkolab_VERSION 
${Libkolab_VERSION_MAJOR}.${Libkolab_VERSION_MINOR}.${Libkolab_VERSION_PATCH} )
+#set(Libkolab_VERSION ${Libkolab_VERSION_MAJOR}.${Libkolab_VERSION_MINOR} )
+#set(Libkolab_VERSION_STRING ${CMAKE_PROJECT_NAME}-${Libkolab_VERSION})
 
 # set up install directories.
 set(LIB_INSTALL_DIR lib CACHE STRING "The directories where to install 
libraries to")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libkolab-0.4.0/cmake/modules/COPYING-CMAKE-SCRIPTS 
new/libkolab-0.4.1/cmake/modules/COPYING-CMAKE-SCRIPTS
--- old/libkolab-0.4.0/cmake/modules/COPYING-CMAKE-SCRIPTS      1970-01-01 
01:00:00.000000000 +0100
+++ new/libkolab-0.4.1/cmake/modules/COPYING-CMAKE-SCRIPTS      2013-01-09 
13:59:23.000000000 +0100
@@ -0,0 +1,22 @@
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products 
+   derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libkolab-0.4.0/conversion/CMakeLists.txt 
new/libkolab-0.4.1/conversion/CMakeLists.txt
--- old/libkolab-0.4.0/conversion/CMakeLists.txt        2012-11-11 
17:30:47.000000000 +0100
+++ new/libkolab-0.4.1/conversion/CMakeLists.txt        2013-01-09 
13:59:23.000000000 +0100
@@ -2,6 +2,7 @@
 set (CONVERSION_SRCS
     ${CMAKE_CURRENT_SOURCE_DIR}/kcalconversion.cpp 
     ${CMAKE_CURRENT_SOURCE_DIR}/kabcconversion.cpp 
-    ${CMAKE_CURRENT_SOURCE_DIR}/commonconversion.cpp 
-    ${CMAKE_CURRENT_SOURCE_DIR}/kolabconversion.cpp PARENT_SCOPE)
+    ${CMAKE_CURRENT_SOURCE_DIR}/commonconversion.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/kolabconversion.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/timezoneconverter.cpp PARENT_SCOPE)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libkolab-0.4.0/conversion/commonconversion.cpp 
new/libkolab-0.4.1/conversion/commonconversion.cpp
--- old/libkolab-0.4.0/conversion/commonconversion.cpp  2012-11-11 
17:30:47.000000000 +0100
+++ new/libkolab-0.4.1/conversion/commonconversion.cpp  2013-01-09 
13:59:23.000000000 +0100
@@ -16,6 +16,7 @@
  */
 
 #include "commonconversion.h"
+#include "timezoneconverter.h"
 #include <kolabformat/errorhandler.h>
 
 #include <iostream>
@@ -87,7 +88,14 @@
             date.setUTC(true);
         } else if (dt.timeType() == KDateTime::TimeZone) { //Timezone
             //TODO handle local timezone?
-            date.setTimezone(toStdString(dt.timeZone().name())); //FIXME use 
system independent name according to spec
+            //Convert non-olson timezones if necessary
+            const QString timezone = 
TimezoneConverter::normalizeTimezone(dt.timeZone().name());
+            if (!timezone.isEmpty()) {
+                date.setTimezone(toStdString(timezone));
+            } else {
+                Error() << "invalid timezone: " << dt.timeZone().name() << " , 
assuming floating time";
+                return date;
+            }
         } else if (dt.timeType() != KDateTime::ClockTime) {
             Error() << "invalid timespec, assuming floating time" << 
dt.timeType();
             return date;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libkolab-0.4.0/conversion/timezoneconverter.cpp 
new/libkolab-0.4.1/conversion/timezoneconverter.cpp
--- old/libkolab-0.4.0/conversion/timezoneconverter.cpp 1970-01-01 
01:00:00.000000000 +0100
+++ new/libkolab-0.4.1/conversion/timezoneconverter.cpp 2013-01-09 
13:59:23.000000000 +0100
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2012  Christian Mollekopf <[email protected]>
+ *
+ * This program 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "timezoneconverter.h"
+#include <ktimezone.h>
+#include <ksystemtimezone.h>
+#include <kdebug.h>
+#include <QRegExp>
+#include <QStringList>
+
+QString TimezoneConverter::normalizeTimezone(const QString& tz)
+{
+    KTimeZone timezone = KSystemTimeZones::zone(tz); //Needs ktimezoned 
(timezone daemon running) 
http://api.kde.org/4.x-api/kdelibs-apidocs/kdecore/html/classKSystemTimeZones.html
+    if (timezone.isValid()) {
+        return tz;
+    }
+    //We're dealing with an invalid or unknown timezone, try to parse it
+    QString guessedTimezone = fromCityName(tz);
+    if (guessedTimezone.isEmpty()) {
+        guessedTimezone = fromHardcodedList(tz);
+    }
+    if (guessedTimezone.isEmpty()) {
+        guessedTimezone = fromGMTOffsetTimezone(tz);
+    }
+    return guessedTimezone;
+}
+
+QString TimezoneConverter::fromGMTOffsetTimezone(const QString& tz)
+{
+    Q_UNUSED(tz);
+    return QString();
+}
+
+QString TimezoneConverter::fromCityName(const QString& tz)
+{
+    const KTimeZones::ZoneMap zones = KSystemTimeZones::zones();
+    KTimeZones::ZoneMap::const_iterator it = zones.constBegin();
+    QHash<QString, QString> countryMap;
+    for(;it != zones.constEnd(); it++) {
+        const QString cityName = it.key().split('/').last();
+//         kDebug() << it.key() << it.value().name() << cityName;
+        Q_ASSERT(!countryMap.contains(cityName));
+        countryMap.insert(cityName, it.key());
+    }
+
+    QRegExp locationFinder("\\b([a-zA-Z])+\\b", Qt::CaseSensitive, 
QRegExp::RegExp2);
+    int pos = 0;
+    while (pos >= 0) {
+        pos = locationFinder.indexIn(tz, pos);
+        if (pos >= 0) {
+            ++pos;
+        }
+        const QString location = locationFinder.capturedTexts().first();
+//         kDebug() << "location " << location;
+        if (countryMap.contains(location)) {
+//             kDebug() << "found match " << countryMap.value(location);
+            return countryMap.value(location);
+        }
+    }
+    return QString();
+}
+
+
+//Based on
+// * http://msdn.microsoft.com/en-us/library/ms912391(v=winembedded.11).aspx
+// * http://technet.microsoft.com/en-us/library/cc749073(v=ws.10).aspx
+// * http://unicode.org/repos/cldr/trunk/common/supplemental/windowsZones.xml
+// * http://stackoverflow.com/questions/4967903/linux-windows-timezone-mapping
+static const struct WindowsTimezone {
+//   const int gmtOffset;
+  const char *timezoneSpecifier; //This one should be stable and always in 
english
+  const char *name; //The display name (which is in some cases still useful to 
try guessing)
+  const char *olson[28]; //Corresponding olson timezones we can map to
+} windowsTimezones[] = {
+    {"Afghanistan Standard Time", "Kabul", {"Asia/Kabul", "Asia/Kabul"}},
+    {"Alaskan Standard Time", "Alaska", {"America/Anchorage", 
"America/Anchorage America/Juneau America/Nome America/Sitka America/Yakutat"}},
+    {"Arab Standard Time", "Kuwait, Riyadh", {"Asia/Riyadh", "Asia/Bahrain", 
"Asia/Kuwait", "Asia/Qatar", "Asia/Riyadh", "Asia/Aden"}},
+    {"Arabian Standard Time", "Abu Dhabi, Muscat", {"Asia/Dubai", 
"Asia/Dubai", "Asia/Muscat", "Etc/GMT-4"}},
+    {"Arabic Standard Time", "Baghdad", {"Asia/Baghdad", "Asia/Baghdad"}},
+    {"Atlantic Standard Time", "Atlantic Time (Canada)", {"America/Halifax", 
"Atlantic/Bermuda", "America/Halifax America/Glace_Bay America/Goose_Bay 
America/Moncton", "America/Thule"}},
+    {"AUS Central Standard Time", "Darwin", {"Australia/Darwin", 
"Australia/Darwin"}},
+    {"AUS Eastern Standard Time", "Canberra, Melbourne, Sydney", 
{"Australia/Sydney", "Australia/Sydney Australia/Melbourne"}},
+    {"Azerbaijan Standard Time", "Baku", {"Asia/Baku", "Asia/Baku"}},
+    {"Azores Standard Time", "Azores", {"Atlantic/Azores", 
"America/Scoresbysund", "Atlantic/Azores"}},
+    {"Canada Central Standard Time", "Saskatchewan", {"America/Regina", 
"America/Regina America/Swift_Current"}},
+    {"Cape Verde Standard Time", "Cape Verde Islands", {"Atlantic/Cape_Verde", 
"Atlantic/Cape_Verde", "Etc/GMT+1"}},
+    {"Caucasus Standard Time", "Yerevan", {"Asia/Yerevan", "Asia/Yerevan"}},
+    {"Cen. Australia Standard Time", "Adelaide", {"Australia/Adelaide", 
"Australia/Adelaide Australia/Broken_Hill"}},
+    {"Central America Standard Time", "Central America", {"America/Guatemala", 
"America/Belize", "America/Costa_Rica", "Pacific/Galapagos", 
"America/Guatemala", "America/Tegucigalpa", "America/Managua", 
"America/El_Salvador", "Etc/GMT+6"}},
+    {"Central Asia Standard Time", "Astana, Dhaka", {"Asia/Almaty", 
"Antarctica/Vostok", "Indian/Chagos", "Asia/Bishkek", "Asia/Almaty 
Asia/Qyzylorda", "Etc/GMT-6"}},
+    {"Central Brazilian Standard Time", "Manaus", {"America/Cuiaba", 
"America/Cuiaba America/Campo_Grande"}},
+    {"Central Europe Standard Time", "Belgrade, Bratislava, Budapest, 
Ljubljana, Prague", {"Europe/Budapest", "Europe/Tirane", "Europe/Prague", 
"Europe/Budapest", "Europe/Podgorica", "Europe/Belgrade", "Europe/Ljubljana", 
"Europe/Bratislava"}},
+    {"Central European Standard Time", "Sarajevo, Skopje, Warsaw, Zagreb", 
{"Europe/Warsaw", "Europe/Sarajevo", "Europe/Zagreb", "Europe/Skopje", 
"Europe/Warsaw"}},
+    {"Central Pacific Standard Time", "Magadan, Solomon Islands, New 
Caledonia", {"Pacific/Guadalcanal", "Antarctica/Macquarie", "Pacific/Ponape 
Pacific/Kosrae", "Pacific/Noumea", "Pacific/Guadalcanal", "Pacific/Efate", 
"Etc/GMT-11"}},
+    {"Central Standard Time", "Central Time (US and Canada)", 
{"America/Chicago", "America/Winnipeg America/Rainy_River America/Rankin_Inlet 
America/Resolute", "America/Matamoros", "America/Chicago America/Indiana/Knox 
America/Indiana/Tell_City America/Menominee America/North_Dakota/Beulah 
America/North_Dakota/Center America/North_Dakota/New_Salem", "CST6CDT"}},
+    {"Central Standard Time (Mexico)", "Guadalajara, Mexico City, Monterrey", 
{"America/Mexico_City", "America/Mexico_City America/Bahia_Banderas 
America/Cancun America/Merida America/Monterrey"}},
+    {"China Standard Time", "Beijing, Chongqing, Hong Kong SAR, Urumqi", 
{"Asia/Shanghai", "Asia/Shanghai Asia/Chongqing Asia/Harbin Asia/Kashgar 
Asia/Urumqi", "Asia/Hong_Kong", "Asia/Macau"}},
+    {"Dateline Standard Time", "International Date Line West", {"Etc/GMT+12", 
"Etc/GMT+12"}},
+    {"E. Africa Standard Time", "Nairobi", {"Africa/Nairobi", 
"Antarctica/Syowa", "Africa/Djibouti", "Africa/Asmera", "Africa/Addis_Ababa", 
"Africa/Nairobi", "Indian/Comoro", "Indian/Antananarivo", "Africa/Khartoum", 
"Africa/Mogadishu", "Africa/Juba", "Africa/Dar_es_Salaam", "Africa/Kampala", 
"Indian/Mayotte", "Etc/GMT-3"}},
+    {"E. Australia Standard Time", "Brisbane", {"Australia/Brisbane", 
"Australia/Brisbane Australia/Lindeman"}},
+    {"E. Europe Standard Time", "Minsk", {"Asia/Nicosia", "Asia/Nicosia"}},
+    {"E. South America Standard Time", "Brasilia", {"America/Sao_Paulo", 
"America/Sao_Paulo"}},
+    {"Eastern Standard Time", "Eastern Time (US and Canada)", 
{"America/New_York", "America/Nassau", "America/Toronto America/Iqaluit 
America/Montreal America/Nipigon America/Pangnirtung America/Thunder_Bay", 
"America/Grand_Turk", "America/New_York America/Detroit 
America/Indiana/Petersburg America/Indiana/Vincennes America/Indiana/Winamac 
America/Kentucky/Monticello America/Louisville", "EST5EDT"}},
+    {"Egypt Standard Time", "Cairo", {"Africa/Cairo", "Africa/Cairo", 
"Asia/Gaza Asia/Hebron"}},
+    {"Ekaterinburg Standard Time", "Ekaterinburg", {"Asia/Yekaterinburg", 
"Asia/Yekaterinburg"}},
+    {"Fiji Standard Time", "Fiji Islands, Kamchatka, Marshall Islands", 
{"Pacific/Fiji", "Pacific/Fiji"}},
+    {"FLE Standard Time", "Helsinki, Kiev, Riga, Sofia, Tallinn, Vilnius", 
{"Europe/Kiev", "Europe/Mariehamn", "Europe/Sofia", "Europe/Tallinn", 
"Europe/Helsinki", "Europe/Vilnius", "Europe/Riga", "Europe/Kiev 
Europe/Simferopol Europe/Uzhgorod Europe/Zaporozhye"}},
+    {"Georgian Standard Time", "Tblisi", {"Asia/Tbilisi", "Asia/Tbilisi"}},
+    {"GMT Standard Time", "Greenwich Mean Time : Dublin, Edinburgh, Lisbon, 
London", {"Europe/London", "Atlantic/Canary", "Atlantic/Faeroe", 
"Europe/London", "Europe/Guernsey", "Europe/Dublin", "Europe/Isle_of_Man", 
"Europe/Jersey", "Europe/Lisbon Atlantic/Madeira"}},
+    {"Greenland Standard Time", "Greenland", {"America/Godthab", 
"America/Godthab"}},
+    {"Greenwich Standard Time", "Casablanca, Monrovia", {"Atlantic/Reykjavik", 
"Africa/Ouagadougou", "Africa/Abidjan", "Africa/El_Aaiun", "Africa/Accra", 
"Africa/Banjul", "Africa/Conakry", "Africa/Bissau", "Atlantic/Reykjavik", 
"Africa/Monrovia", "Africa/Bamako", "Africa/Nouakchott", "Atlantic/St_Helena", 
"Africa/Freetown", "Africa/Dakar", "Africa/Sao_Tome", "Africa/Lome"}},
+    {"GTB Standard Time", "Athens, Bucharest, Istanbul", {"Europe/Bucharest", 
"Europe/Athens", "Europe/Chisinau", "Europe/Bucharest"}},
+    {"Hawaiian Standard Time", "Hawaii", {"Pacific/Honolulu", 
"Pacific/Rarotonga", "Pacific/Tahiti", "Pacific/Johnston", "Pacific/Honolulu", 
"Etc/GMT+10"}},
+    {"India Standard Time", "Chennai, Kolkata, Mumbai, New Delhi", 
{"Asia/Calcutta", "Asia/Calcutta"}},
+    {"Iran Standard Time", "Tehran", {"Asia/Tehran", "Asia/Tehran"}},
+    {"Israel Standard Time", "Jerusalem", {"Asia/Jerusalem", 
"Asia/Jerusalem"}},
+    {"Korea Standard Time", "Seoul", {"Asia/Seoul", "Asia/Pyongyang", 
"Asia/Seoul"}},
+//    {"Mid-Atlantic Standard Time", "Mid-Atlantic", {"}},
+    {"Mountain Standard Time", "Mountain Time (US and Canada)", 
{"America/Denver", "America/Edmonton America/Cambridge_Bay America/Inuvik 
America/Yellowknife", "America/Ojinaga", "America/Denver America/Boise 
America/Shiprock", "MST7MDT"}},
+    {"Mountain Standard Time (Mexico)", "Chihuahua, La Paz, Mazatlan", 
{"America/Chihuahua", "America/Chihuahua America/Mazatlan"}},
+    {"Myanmar Standard Time", "Yangon (Rangoon)", {"Asia/Rangoon", 
"Indian/Cocos", "Asia/Rangoon"}},
+    {"N. Central Asia Standard Time", "Almaty, Novosibirsk", 
{"Asia/Novosibirsk", "Asia/Novosibirsk Asia/Novokuznetsk Asia/Omsk"}},
+    {"Namibia Standard Time", "Windhoek", {"Africa/Windhoek", 
"Africa/Windhoek"}},
+    {"Nepal Standard Time", "Kathmandu", {"Asia/Katmandu", "Asia/Katmandu"}},
+    {"New Zealand Standard Time", "Auckland, Wellington", {"Pacific/Auckland", 
"Antarctica/South_Pole Antarctica/McMurdo", "Pacific/Auckland"}},
+    {"Newfoundland Standard Time", "Newfoundland and Labrador", 
{"America/St_Johns", "America/St_Johns"}},
+    {"North Asia East Standard Time", "Irkutsk, Ulaanbaatar", {"Asia/Irkutsk", 
"Asia/Irkutsk"}},
+    {"North Asia Standard Time", "Krasnoyarsk", {"Asia/Krasnoyarsk", 
"Asia/Krasnoyarsk"}},
+    {"Pacific SA Standard Time", "Santiago", {"America/Santiago", 
"Antarctica/Palmer", "America/Santiago"}},
+    {"Pacific Standard Time", "Pacific Time (US and Canada); Tijuana", 
{"America/Los_Angeles", "America/Vancouver America/Dawson America/Whitehorse", 
"America/Tijuana", "America/Los_Angeles", "PST8PDT"}},
+    {"Romance Standard Time", "Brussels, Copenhagen, Madrid, Paris", 
{"Europe/Paris", "Europe/Brussels", "Europe/Copenhagen", "Europe/Madrid 
Africa/Ceuta", "Europe/Paris"}},
+    {"Russian Standard Time", "Moscow, St. Petersburg, Volgograd", 
{"Europe/Moscow", "Europe/Moscow Europe/Samara Europe/Volgograd"}},
+    {"SA Eastern Standard Time", "Buenos Aires, Georgetown", 
{"America/Cayenne", "Antarctica/Rothera", "America/Fortaleza America/Araguaina 
America/Belem America/Maceio America/Recife America/Santarem", 
"Atlantic/Stanley", "America/Cayenne", "America/Paramaribo", "Etc/GMT+3"}},
+    {"SA Pacific Standard Time", "Bogota, Lima, Quito", {"America/Bogota", 
"America/Coral_Harbour", "America/Bogota", "America/Guayaquil", 
"America/Port-au-Prince", "America/Jamaica", "America/Cayman", 
"America/Panama", "America/Lima", "Etc/GMT+5"}},
+    {"SA Western Standard Time", "Caracas, La Paz", {"America/La_Paz", 
"America/Antigua", "America/Anguilla", "America/Aruba", "America/Barbados", 
"America/St_Barthelemy", "America/La_Paz", "America/Kralendijk", 
"America/Manaus America/Boa_Vista America/Eirunepe America/Porto_Velho 
America/Rio_Branco", "America/Blanc-Sablon", "America/Curacao", 
"America/Dominica", "America/Santo_Domingo", "America/Grenada", 
"America/Guadeloupe", "America/Guyana", "America/St_Kitts", "America/St_Lucia", 
"America/Marigot", "America/Martinique", "America/Montserrat", 
"America/Puerto_Rico", "America/Lower_Princes", "America/Port_of_Spain", 
"America/St_Vincent", "America/Tortola", "America/St_Thomas", "Etc/GMT+4"}},
+    {"Samoa Standard Time", "Midway Island, Samoa", {"Pacific/Apia", 
"Pacific/Apia"}},
+    {"SE Asia Standard Time", "Bangkok, Hanoi, Jakarta", {"Asia/Bangkok", 
"Antarctica/Davis", "Indian/Christmas", "Asia/Jakarta Asia/Pontianak", 
"Asia/Phnom_Penh", "Asia/Vientiane", "Asia/Hovd", "Asia/Bangkok", 
"Asia/Saigon", "Etc/GMT-7"}},
+    {"Singapore Standard Time", "Kuala Lumpur, Singapore", {"Asia/Singapore", 
"Asia/Brunei", "Asia/Makassar", "Asia/Kuala_Lumpur Asia/Kuching", 
"Asia/Manila", "Asia/Singapore", "Etc/GMT-8"}},
+    {"South Africa Standard Time", "Harare, Pretoria", {"Africa/Johannesburg", 
"Africa/Bujumbura", "Africa/Gaborone", "Africa/Lubumbashi", "Africa/Maseru", 
"Africa/Blantyre", "Africa/Maputo", "Africa/Kigali", "Africa/Mbabane", 
"Africa/Johannesburg", "Africa/Lusaka", "Africa/Harare", "Etc/GMT-2"}},
+    {"Sri Lanka Standard Time", "Sri Jayawardenepura", {"Asia/Colombo", 
"Asia/Colombo"}},
+    {"Taipei Standard Time", "Taipei", {"Asia/Taipei", "Asia/Taipei"}},
+    {"Tasmania Standard Time", "Hobart", {"Australia/Hobart", 
"Australia/Hobart Australia/Currie"}},
+    {"Tokyo Standard Time", "Osaka, Sapporo, Tokyo", {"Asia/Tokyo", 
"Asia/Jayapura", "Asia/Tokyo", "Pacific/Palau", "Asia/Dili", "Etc/GMT-9"}},
+    {"Tonga Standard Time", "Nuku'alofa", {"Pacific/Tongatapu", 
"Pacific/Enderbury", "Pacific/Fakaofo", "Pacific/Tongatapu", "Etc/GMT-13"}},
+    {"US Eastern Standard Time", "Indiana (East)", {"America/Indianapolis", 
"America/Indianapolis America/Indiana/Marengo America/Indiana/Vevay"}},
+    {"US Mountain Standard Time", "Arizona", {"America/Phoenix", 
"America/Dawson_Creek America/Creston", "America/Hermosillo", 
"America/Phoenix", "Etc/GMT+7"}},
+    {"Vladivostok Standard Time", "Vladivostok", {"Asia/Vladivostok", 
"Asia/Vladivostok Asia/Sakhalin"}},
+    {"W. Australia Standard Time", "Perth", {"Australia/Perth", 
"Antarctica/Casey", "Australia/Perth"}},
+    {"W. Central Africa Standard Time", "West Central Africa", 
{"Africa/Lagos", "Africa/Luanda", "Africa/Porto-Novo", "Africa/Kinshasa", 
"Africa/Bangui", "Africa/Brazzaville", "Africa/Douala", "Africa/Algiers", 
"Africa/Libreville", "Africa/Malabo", "Africa/Niamey", "Africa/Lagos", 
"Africa/Ndjamena", "Africa/Tunis", "Etc/GMT-1"}},
+    {"W. Europe Standard Time", "Amsterdam, Berlin, Bern, Rome, Stockholm, 
Vienna", {"Europe/Berlin", "Europe/Andorra", "Europe/Vienna", "Europe/Zurich", 
"Europe/Berlin", "Europe/Gibraltar", "Europe/Rome", "Europe/Vaduz", 
"Europe/Luxembourg", "Africa/Tripoli", "Europe/Monaco", "Europe/Malta", 
"Europe/Amsterdam", "Europe/Oslo", "Europe/Stockholm", "Arctic/Longyearbyen", 
"Europe/San_Marino", "Europe/Vatican"}},
+    {"West Asia Standard Time", "Islamabad, Karachi, Tashkent", 
{"Asia/Tashkent", "Antarctica/Mawson", "Asia/Oral Asia/Aqtau Asia/Aqtobe", 
"Indian/Maldives", "Indian/Kerguelen", "Asia/Dushanbe", "Asia/Ashgabat", 
"Asia/Tashkent Asia/Samarkand", "Etc/GMT-5"}},
+    {"West Pacific Standard Time", "Guam, Port Moresby", 
{"Pacific/Port_Moresby", "Antarctica/DumontDUrville", "Pacific/Truk", 
"Pacific/Guam", "Pacific/Saipan", "Pacific/Port_Moresby", "Etc/GMT-10"}},
+    {"Yakutsk Standard Time", "Yakuts", {"Asia/Yakutsk", "Asia/Yakutsk"}}
+};
+static const int numWindowsTimezones = sizeof windowsTimezones / sizeof 
*windowsTimezones;
+
+QString TimezoneConverter::fromHardcodedList(const QString& tz)
+{
+    for (int i = 0; i <numWindowsTimezones; i++) {
+        const WindowsTimezone &windowsTimezone = windowsTimezones[i];
+        const QByteArray specifier(windowsTimezone.timezoneSpecifier);
+        const QByteArray windowsName(windowsTimezone.name);
+        if ((!specifier.isEmpty() && tz.contains(specifier)) ||
+            (!windowsName.isEmpty() && tz.contains(windowsName))) {
+            //TODO find the olson timezone matching the local timezone if we 
have multiple to map to
+            return QString::fromLatin1(windowsTimezone.olson[0]);
+        }
+    }
+    return QString();
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libkolab-0.4.0/conversion/timezoneconverter.h 
new/libkolab-0.4.1/conversion/timezoneconverter.h
--- old/libkolab-0.4.0/conversion/timezoneconverter.h   1970-01-01 
01:00:00.000000000 +0100
+++ new/libkolab-0.4.1/conversion/timezoneconverter.h   2013-01-09 
13:59:23.000000000 +0100
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2012  Christian Mollekopf <[email protected]>
+ *
+ * This program 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef TIMEZONECONVERTER_H
+#define TIMEZONECONVERTER_H
+
+#include <QString>
+
+class TimezoneConverter
+{
+public:
+    static QString normalizeTimezone(const QString &tz);
+private:
+    static QString fromCityName(const QString &tz);
+    static QString fromHardcodedList(const QString &tz);
+    static QString fromGMTOffsetTimezone(const QString &tz);
+};
+
+#endif // TIMEZONECONVERTER_H
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libkolab-0.4.0/freebusy/freebusy.cpp 
new/libkolab-0.4.1/freebusy/freebusy.cpp
--- old/libkolab-0.4.0/freebusy/freebusy.cpp    2012-11-11 17:30:47.000000000 
+0100
+++ new/libkolab-0.4.1/freebusy/freebusy.cpp    2013-01-09 13:59:23.000000000 
+0100
@@ -19,6 +19,7 @@
 #include "freebusy.h"
 #include "conversion/kcalconversion.h"
 #include "conversion/commonconversion.h"
+#include "libkolab-version.h"
 #include <kcalcore/freebusy.h>
 #include <kcalcore/icalformat.h>
 #include <kdebug.h>
@@ -311,6 +312,7 @@
     fb->setLastModified(Kolab::Conversion::toDate(freebusy.timestamp()));
 
     KCalCore::ICalFormat format;
+    format.setApplication("libkolab", LIBKOLAB_LIB_VERSION_STRING);
     QString data = format.createScheduleMessage( fb, KCalCore::iTIPPublish );
     return Conversion::toStdString(data);
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libkolab-0.4.0/icalendar/icalendar.cpp 
new/libkolab-0.4.1/icalendar/icalendar.cpp
--- old/libkolab-0.4.0/icalendar/icalendar.cpp  2012-11-11 17:30:47.000000000 
+0100
+++ new/libkolab-0.4.1/icalendar/icalendar.cpp  2013-01-09 13:59:23.000000000 
+0100
@@ -20,6 +20,7 @@
 
 #include "icalendar.h"
 #include "imip.h"
+#include "libkolab-version.h"
 #include <conversion/kcalconversion.h>
 #include <conversion/commonconversion.h>
 #include <mime/mimeutils.h>
@@ -42,6 +43,7 @@
         calendar->addEvent(kcalEvent);
     }
     KCalCore::ICalFormat format;
+    format.setApplication("libkolab", LIBKOLAB_LIB_VERSION_STRING);
 //     qDebug() << format.createScheduleMessage(calendar->events().first(), 
KCalCore::iTIPRequest);
 
     return Conversion::toStdString(format.toString(calendar));
@@ -52,6 +54,7 @@
 {
     KCalCore::Calendar::Ptr calendar(new 
KCalCore::MemoryCalendar(Kolab::Conversion::getTimeSpec(true, std::string())));
     KCalCore::ICalFormat format;
+    format.setApplication("libkolab", LIBKOLAB_LIB_VERSION_STRING);
     format.fromString(calendar, Conversion::fromStdString(input));
     std::vector<Event> events;
     foreach (const KCalCore::Event::Ptr &event, calendar->events()) {
@@ -84,6 +87,7 @@
 std::string ITipHandler::toITip(const Event &event, ITipHandler::ITipMethod 
method) const
 {
     KCalCore::ICalFormat format;
+    format.setApplication("libkolab", LIBKOLAB_LIB_VERSION_STRING);
     KCalCore::iTIPMethod m = mapToKCalCore(method);
     if (m == KCalCore::iTIPNoMethod) {
         return std::string();
@@ -125,6 +129,7 @@
     KCalCore::Event::Ptr e = Conversion::toKCalCore(event);
 //     e->recurrence()->addRDateTime(e->dtStart()); //FIXME The 
createScheduleMessage converts everything to utc without a recurrence.
     KCalCore::ICalFormat format;
+    format.setApplication("libkolab", LIBKOLAB_LIB_VERSION_STRING);
     KCalCore::iTIPMethod method = mapToKCalCore(m);
     const QString &messageText = format.createScheduleMessage( e, method );
     //This code is mostly from MailScheduler::performTransaction
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libkolab-0.4.0/kolabformat/kolabobject.cpp 
new/libkolab-0.4.1/kolabformat/kolabobject.cpp
--- old/libkolab-0.4.0/kolabformat/kolabobject.cpp      2012-11-11 
17:30:47.000000000 +0100
+++ new/libkolab-0.4.1/kolabformat/kolabobject.cpp      2013-01-09 
13:59:23.000000000 +0100
@@ -576,7 +576,7 @@
         const Kolab::DistList &dist = Kolab::Conversion::fromKABC(distlist);
         const std::string &v3String = Kolab::writeDistlist(dist, 
Conversion::toStdString(getProductId(productId)));
         ErrorHandler::handleLibkolabxmlErrors();
-        return  Mime::createMessage(Conversion::fromStdString(dist.uid()), 
xCardMimeType(), contactKolabType(), 
Conversion::fromStdString(v3String).toUtf8(), true, getProductId(productId));
+        return  Mime::createMessage(Conversion::fromStdString(dist.uid()), 
xCardMimeType(), distlistKolabType(), 
Conversion::fromStdString(v3String).toUtf8(), true, getProductId(productId));
     }
     KolabV2::DistributionList d(&distlist);
     return distListToKolabFormat(d, getProductId(productId));
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libkolab-0.4.0/kolabformat/xmlobject.cpp 
new/libkolab-0.4.1/kolabformat/xmlobject.cpp
--- old/libkolab-0.4.0/kolabformat/xmlobject.cpp        2012-11-11 
17:30:47.000000000 +0100
+++ new/libkolab-0.4.1/kolabformat/xmlobject.cpp        2013-01-09 
13:59:23.000000000 +0100
@@ -55,7 +55,7 @@
         if (i->uid().isEmpty()) {
             i->setUid(createUuid());
         }
-        mWrittenUID = Conversion::toStdString(i->uid().toUtf8().constData());
+        mWrittenUID = Conversion::toStdString(i->uid());
         //The timezone is used for created and last modified dates
         const QString &xml = KolabV2::Event::eventToXML(i, 
QLatin1String("UTC"));
         return Conversion::toStdString(xml);
@@ -72,7 +72,7 @@
         const KCalCore::Event::Ptr event = 
Kolab::fromXML<KCalCore::Event::Ptr, 
KolabV2::Event>(QString::fromUtf8(s.c_str()).toUtf8(), attachments);
         mAttachments.clear();
         foreach (const QString &attachment, attachments) {
-            
mAttachments.push_back(std::string(attachment.toUtf8().constData()));
+            mAttachments.push_back(Conversion::toStdString(attachment));
         }
         return Conversion::fromKCalCore(*event);
     }
@@ -87,7 +87,7 @@
         if (i->uid().isEmpty()) {
             i->setUid(createUuid());
         }
-        mWrittenUID = Conversion::toStdString(i->uid().toUtf8().constData());
+        mWrittenUID = Conversion::toStdString(i->uid());
         //The timezone is used for created and last modified dates
         const QString &xml = KolabV2::Task::taskToXML(i, QLatin1String("UTC"));
         return Conversion::toStdString(xml);
@@ -104,7 +104,7 @@
         const KCalCore::Todo::Ptr event = Kolab::fromXML<KCalCore::Todo::Ptr, 
KolabV2::Task>(QString::fromUtf8(s.c_str()).toUtf8(), attachments);
         mAttachments.clear();
         foreach (const QString &attachment, attachments) {
-            
mAttachments.push_back(std::string(attachment.toUtf8().constData()));
+            mAttachments.push_back(Conversion::toStdString(attachment));
         }
         return Conversion::fromKCalCore(*event);
     }
@@ -119,7 +119,7 @@
         if (i->uid().isEmpty()) {
             i->setUid(createUuid());
         }
-        mWrittenUID = Conversion::toStdString(i->uid().toUtf8().constData());
+        mWrittenUID = Conversion::toStdString(i->uid());
         //The timezone is used for created and last modified dates
         const QString &xml = KolabV2::Journal::journalToXML(i, 
QLatin1String("UTC"));
         return Conversion::toStdString(xml);
@@ -136,7 +136,7 @@
         const KCalCore::Journal::Ptr event = 
Kolab::fromXML<KCalCore::Journal::Ptr, 
KolabV2::Journal>(QString::fromUtf8(s.c_str()).toUtf8(), attachments);
         mAttachments.clear();
         foreach (const QString &attachment, attachments) {
-            
mAttachments.push_back(std::string(attachment.toUtf8().constData()));
+            mAttachments.push_back(Conversion::toStdString(attachment));
         }
         return Conversion::fromKCalCore(*event);
     }
@@ -204,10 +204,9 @@
         if (addressee.uid().isEmpty()) {
             addressee.setUid(createUuid());
         }
-        mWrittenUID = 
Conversion::toStdString(addressee.uid().toUtf8().constData());
+        mWrittenUID = Conversion::toStdString(addressee.uid());
         const KolabV2::Contact contact(&addressee);
-        const QByteArray xml = contact.saveXML().toUtf8();
-        return std::string(xml.constData());
+        return Conversion::toStdString(contact.saveXML());
     }
     const std::string result = Kolab::writeContact(contact, productId);
     mWrittenUID = Kolab::getSerializedUID();
@@ -232,10 +231,9 @@
         if (contactGroup.id().isEmpty()) {
             contactGroup.setId(createUuid());
         }
-        mWrittenUID = 
Conversion::toStdString(contactGroup.id().toUtf8().constData());
+        mWrittenUID = Conversion::toStdString(contactGroup.id());
         const KolabV2::DistributionList d(&contactGroup);
-        const QByteArray xml = d.saveXML().toUtf8();
-        return std::string(xml.constData());
+        return Conversion::toStdString(d.saveXML());
     }
     const std::string result = Kolab::writeDistlist(distlist, productId);
     mWrittenUID = Kolab::getSerializedUID();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libkolab-0.4.0/tests/CMakeLists.txt 
new/libkolab-0.4.1/tests/CMakeLists.txt
--- old/libkolab-0.4.0/tests/CMakeLists.txt     2012-11-11 17:30:47.000000000 
+0100
+++ new/libkolab-0.4.1/tests/CMakeLists.txt     2013-01-09 13:59:23.000000000 
+0100
@@ -20,3 +20,4 @@
 addTest(icalendartest)
 addTest(freebusytest)
 addTest(kolabobjecttest)
+addTest(timezonetest)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libkolab-0.4.0/tests/formattest.cpp 
new/libkolab-0.4.1/tests/formattest.cpp
--- old/libkolab-0.4.0/tests/formattest.cpp     2012-11-11 17:30:47.000000000 
+0100
+++ new/libkolab-0.4.1/tests/formattest.cpp     2013-01-09 13:59:23.000000000 
+0100
@@ -29,6 +29,7 @@
 
 #include <kcalcore/icalformat.h>
 #include <kabc/vcardconverter.h>
+#include <kabc/contactgrouptool.h>
 #include <akonadi/notes/noteutils.h>
 
 #include "testutils.h"
@@ -279,6 +280,72 @@
     QCOMPARE(Kolab::ErrorHandler::instance().error(), 
Kolab::ErrorHandler::Debug);
 }
 
+void FormatTest::testDistlist_data()
+{
+    QTest::addColumn<Kolab::Version>( "version" );
+    QTest::addColumn<Kolab::ObjectType>( "type" );
+    QTest::addColumn<QString>( "vcardFileName" );
+    QTest::addColumn<QString>( "mimeFileName" );
+    
+    QTest::newRow( "v3distlistSimple" ) << Kolab::KolabV3 << 
Kolab::DistlistObject << 
TESTFILEDIR+QString::fromLatin1("v3/contacts/distlist.vcf") << 
TESTFILEDIR+QString::fromLatin1("v3/contacts/distlist.vcf.mime");
+}
+
+void FormatTest::testDistlist()
+{
+    QFETCH( Kolab::Version, version );
+    QFETCH( Kolab::ObjectType, type );
+    QFETCH( QString, vcardFileName ); //To compare
+    QFETCH( QString, mimeFileName ); //For parsing
+    
+    //Parse mime message
+    bool ok = false;
+    const KMime::Message::Ptr &msg = readMimeFile( mimeFileName, ok );
+    QVERIFY(ok);
+    Kolab::KolabObjectReader reader;
+    Kolab::ObjectType t = reader.parseMimeMessage(msg);
+    QCOMPARE(t, type);
+    QCOMPARE(reader.getVersion(), version);
+    QCOMPARE(Kolab::ErrorHandler::instance().error(), 
Kolab::ErrorHandler::Debug);
+    
+    KABC::ContactGroup convertedAddressee = reader.getDistlist();
+    
+    //Parse vcard
+    QFile vcardFile( vcardFileName );
+    QVERIFY( vcardFile.open( QFile::ReadOnly ) );
+    KABC::VCardConverter converter;
+    QByteArray c = vcardFile.readAll();
+    QBuffer data(&c);
+    data.open(QIODevice::ReadOnly);
+    
+    KABC::ContactGroup realAddressee;
+    KABC::ContactGroupTool::convertFromXml( &data, realAddressee );
+
+    {
+        QBuffer expected;
+        expected.open(QIODevice::WriteOnly);
+        KABC::ContactGroupTool::convertToXml(realAddressee, &expected);
+        
+        QBuffer converted;
+        converted.open(QIODevice::WriteOnly);
+        KABC::ContactGroupTool::convertToXml(convertedAddressee, &converted);
+        
+        showDiff(expected.buffer(), converted.buffer());
+    }
+    QCOMPARE( realAddressee, convertedAddressee );
+
+    //Write
+    const KMime::Message::Ptr &convertedMime = 
Kolab::KolabObjectWriter::writeDistlist(realAddressee, version);
+    
+    if ( !compareMimeMessage( convertedMime, msg )) {
+        QString expected = msg->encodedContent();
+        normalizeMimemessage(expected);
+        QString converted = convertedMime->encodedContent();
+        normalizeMimemessage(converted);
+        showDiff(expected, converted);
+        QVERIFY( false );
+    }
+    QCOMPARE(Kolab::ErrorHandler::instance().error(), 
Kolab::ErrorHandler::Debug);
+}
 
 void FormatTest::testNote_data()
 {
@@ -376,6 +443,18 @@
 //     KABC::Addressee convertedAddressee = reader.getContact();
 //     KABC::VCardConverter converter;
 //     qDebug() << converter.createVCard(convertedAddressee);
+
+//     bool ok = false;
+//     const KMime::Message::Ptr &msg = readMimeFile( 
TESTFILEDIR+QString::fromLatin1("v3/contacts/distlist.vcf.mime"), ok );
+//     qDebug() << msg->encodedContent();
+//     Kolab::KolabObjectReader reader;
+//     Kolab::ObjectType t = reader.parseMimeMessage(msg);
+// 
+//     KABC::ContactGroup convertedAddressee = reader.getDistlist();
+//     QBuffer buf;
+//     buf.open(QIODevice::WriteOnly);
+//     KABC::ContactGroupTool::convertToXml(convertedAddressee, &buf);
+//     qDebug() << buf.buffer();
 }
 
 //Pseudo test to show that JPG is always lossy, even with quality set to 100
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libkolab-0.4.0/tests/formattest.h 
new/libkolab-0.4.1/tests/formattest.h
--- old/libkolab-0.4.0/tests/formattest.h       2012-11-11 17:30:47.000000000 
+0100
+++ new/libkolab-0.4.1/tests/formattest.h       2013-01-09 13:59:23.000000000 
+0100
@@ -55,6 +55,9 @@
     
     void testContact_data();
     void testContact();
+    
+    void testDistlist_data();
+    void testDistlist();
 
     void testNote_data();
     void testNote();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libkolab-0.4.0/tests/testfiles/v3/contacts/distlist.vcf 
new/libkolab-0.4.1/tests/testfiles/v3/contacts/distlist.vcf
--- old/libkolab-0.4.0/tests/testfiles/v3/contacts/distlist.vcf 1970-01-01 
01:00:00.000000000 +0100
+++ new/libkolab-0.4.1/tests/testfiles/v3/contacts/distlist.vcf 2013-01-09 
13:59:23.000000000 +0100
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<contactGroup uid="4xuyC0cyjV" name="My Distlist">
+    <contactData name="John Doe" email="[email protected]"/>
+    <contactData name="John Doe2" email="[email protected]"/>
+</contactGroup>
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libkolab-0.4.0/tests/testfiles/v3/contacts/distlist.vcf.mime 
new/libkolab-0.4.1/tests/testfiles/v3/contacts/distlist.vcf.mime
--- old/libkolab-0.4.0/tests/testfiles/v3/contacts/distlist.vcf.mime    
2012-11-11 17:30:47.000000000 +0100
+++ new/libkolab-0.4.1/tests/testfiles/v3/contacts/distlist.vcf.mime    
2013-01-09 13:59:23.000000000 +0100
@@ -1,10 +1,9 @@
 Date: Mon, 23 Apr 2012 12:46:37 +0200
-X-Kolab-Type: application/x-vnd.kolab.distribution-list
+X-Kolab-Type: application/x-vnd.kolab.contact.distlist
 X-Kolab-Mime-Version: 3.0
 User-Agent: Libkolab-0.1.0
 Content-Type: multipart/mixed; boundary="nextPart1365947.WmFcbPlLFA"
 Subject: 4xuyC0cyjV
-From: Volker Krause <[email protected]>
 MIME-Version: 1.0
 
 
@@ -38,10 +37,6 @@
     <rev>
       <timestamp>20120505T050505Z</timestamp>
     </rev>
-    <categories>
-      <text>cat1</text>
-      <text>cat2</text>
-    </categories>
     <kind>
       <text>group</text>
     </kind>
@@ -49,18 +44,13 @@
       <text>My Distlist</text>
     </fn>
     <member>
-      <uri>mailto:john%20doe%[email protected]%3e</uri>
+      <uri>mailto:John%20Doe%3Cjdoe%40example.com%3E</uri>
     </member>
     <member>
-      <uri>mailto:john%20doe2%[email protected]%3e</uri>
+      <uri>mailto:John%20Doe2%3Cjdoe2%40example.com%3E</uri>
     </member>
-    <x-custom>
-      <identifier>X-Identifier</identifier>
-      <value>TestValue</value>
-    </x-custom>
-
   </vcard>
 
 </vcards>
 
---nextPart1365947.WmFcbPlLFA--
\ No newline at end of file
+--nextPart1365947.WmFcbPlLFA--
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libkolab-0.4.0/tests/timezonetest.cpp 
new/libkolab-0.4.1/tests/timezonetest.cpp
--- old/libkolab-0.4.0/tests/timezonetest.cpp   1970-01-01 01:00:00.000000000 
+0100
+++ new/libkolab-0.4.1/tests/timezonetest.cpp   2013-01-09 13:59:23.000000000 
+0100
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2012  Christian Mollekopf <[email protected]>
+ *
+ * This program 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "timezonetest.h"
+#include <conversion/timezoneconverter.h>
+#include <kolabformat/kolabobject.h>
+#include <kolabformat/errorhandler.h>
+
+#include <QTest>
+// #include <unicode/uversion.h>
+// #include <unicode/timezone.h>
+// #include <iostream>
+#include <kdebug.h>
+#include <kcalcore/event.h>
+
+// void icuFoo()
+// {
+//     icu::UnicodeString s;
+//     UErrorCode error;
+// //     icu::TimeZone::getCanonicalID("GMT+01.00) Sarajevo/Warsaw/Zagreb", 
s, error);
+// //     
icu::TimeZone::getCanonicalID(icu::UnicodeString::fromUTF8("Europe/Zurich"), s, 
error);
+//     
icu::TimeZone::getCanonicalID(icu::UnicodeString::fromUTF8("GMT+01.00"), s, 
error);
+//     std::string cs;
+//     s.toUTF8String(cs);
+//     std::cout << "This is the new timezone: " << cs  << std::endl << 
u_errorName(error) << std::endl;
+// // 
+// // 
+// //     icu::TimeZone *tz = icu::TimeZone::createTimeZone("GMT-8:00");
+// //     icu::UnicodeString result;
+// //     tz->getDisplayName(result);
+// //     std::string stringresult;
+// //     result.toUTF8String(stringresult);
+// //     std::cout << stringresult;
+//     
+// //     icu::TimeZone *tz = icu::TimeZone::getStaticClassID();
+// 
+// }
+
+void TimezoneTest::testFromName()
+{
+    TimezoneConverter converter;
+    const QString timezone = converter.normalizeTimezone("(GMT+01.00) 
Sarajevo/Warsaw/Zagreb");
+    QCOMPARE(timezone, QLatin1String("Europe/Sarajevo"));
+}
+
+void TimezoneTest::testFromHardcodedList_data()
+{
+    QTest::addColumn<QString>( "timezone" );
+    
+    QTest::newRow( "1" ) << QString::fromLatin1("(GMT+01:00) West Central 
Africa");
+    QTest::newRow( "2" ) << QString::fromLatin1("(GMT-04:00) Atlantic Time 
(Canada)");
+    QTest::newRow( "3" ) << QString::fromLatin1("(GMT-06:00) Saskatchewan");
+    QTest::newRow( "4" ) << QString::fromLatin1("(GMT-01:00) Cape Verde 
Islands");
+    QTest::newRow( "5" ) << QString::fromLatin1("(GMT-06:00) Central America");
+    QTest::newRow( "6" ) << QString::fromLatin1("(GMT-06:00) Central Time (US 
and Canada)");
+//     QTest::newRow( "7" ) << QString::fromLatin1("(GMT-12:00) International 
Date Line West"); //Not mappable
+    QTest::newRow( "8" ) << QString::fromLatin1("(GMT-05:00) Eastern Time (US 
and Canada)");
+//     QTest::newRow( "9" ) << QString::fromLatin1("(GMT-02:00) 
Mid-Atlantic"); //Not mappable
+    QTest::newRow( "10" ) << QString::fromLatin1("(GMT-07:00) Mountain Time 
(US and Canada)");
+    QTest::newRow( "11" ) << QString::fromLatin1("(GMT-03:30) Newfoundland and 
Labrador");
+    QTest::newRow( "12" ) << QString::fromLatin1("(GMT-08:00) Pacific Time (US 
and Canada); Tijuana");
+    QTest::newRow( "13" ) << QString::fromLatin1("(GMT-11:00) Midway Island, 
Samoa");
+    QTest::newRow( "14" ) << QString::fromLatin1("W. Europe Standard Time");
+}
+
+void TimezoneTest::testFromHardcodedList()
+{
+    TimezoneConverter converter;
+    QFETCH(QString, timezone);
+    const QString tz = converter.normalizeTimezone(timezone);
+    kDebug() << tz;
+    QVERIFY(!tz.isEmpty());
+    QVERIFY(tz != timezone);
+}
+
+void TimezoneTest::testKolabObjectWriter()
+{
+    KCalCore::Event::Ptr event(new KCalCore::Event());
+    event->setOrganizer(KCalCore::Person::Ptr());
+    event->setDtStart(KDateTime(QDate(2012,11,11), QTime(1,1), 
KDateTime::Spec(KTimeZone("(GMT+01:00) West Central Africa"))));
+    KMime::Message::Ptr msg = Kolab::KolabObjectWriter::writeEvent(event);
+    Kolab::KolabObjectReader reader(msg);
+    KCalCore::Event::Ptr result = reader.getEvent();
+    kDebug() << result->dtStart().timeZone().name();
+    QCOMPARE(result->dtStart().timeZone().name(), 
KTimeZone(QLatin1String("Africa/Lagos")).name());
+}
+
+
+QTEST_MAIN( TimezoneTest )
+
+#include "timezonetest.moc"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libkolab-0.4.0/tests/timezonetest.h 
new/libkolab-0.4.1/tests/timezonetest.h
--- old/libkolab-0.4.0/tests/timezonetest.h     1970-01-01 01:00:00.000000000 
+0100
+++ new/libkolab-0.4.1/tests/timezonetest.h     2013-01-09 13:59:23.000000000 
+0100
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2012  Christian Mollekopf <[email protected]>
+ *
+ * This program 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef TIMEZONETEST_H
+#define TIMEZONETEST_H
+#include <QObject>
+
+class TimezoneTest: public QObject
+{
+    Q_OBJECT
+private slots:
+    void testFromName();
+    void testFromHardcodedList_data();
+    void testFromHardcodedList();
+    void testKolabObjectWriter();
+};
+
+#endif // TIMEZONETEST_H

-- 
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to