Projects
Kolab:3.4
kolab-utils
Log In
Username
Password
We truncated the diff of some files because they were too big. If you want to see the full diff for every file,
click here
.
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 8
View file
kolab-utils.spec
Changed
@@ -5,8 +5,8 @@ %endif Name: kolab-utils -Version: 3.0.5 -Release: 3%{?dist} +Version: 3.1 +Release: 0.1.dev20140624.git8ebf74a1%{?dist} Summary: Kolab Utilities Group: System Environment/Base @@ -14,6 +14,7 @@ License: GPLv2+ URL: http://www.kolab.org/about/kolab-utils +# From 8ebf74a167bdde08da49bec1ffe126a7c799c4a9 Source0: http://git.kolab.org/kolab-utils/snapshot/%{name}-%{version}.tar.gz Source3: kolab-freebusy.cron
View file
debian.changelog
Changed
@@ -1,3 +1,9 @@ +kolab-utils (3.1~dev20140624-0~kolab1) unstable; urgency=low + + * New git master head snapshot + + -- Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com> Wed, 25 Jun 2014 23:00:55 +0100 + kolab-utils (3.0.5-2) unstable; urgency=low * Set QT_NO_GLIB=1 in cron.
View file
kolab-utils-3.0.5.tar.gz/CMakeLists.txt -> kolab-utils-3.1.tar.gz/CMakeLists.txt
Changed
@@ -1,4 +1,4 @@ -project (KolabUtilsFormat) +project (KolabUtils) cmake_minimum_required(VERSION 2.6) @@ -6,16 +6,34 @@ cmake_policy(SET CMP0013 NEW) endif() +# Versioning +# x.y.z scheme +# Development versions are only x.y +# +# i.e. +# 0.1 (0.1 development version towards 0.1.0) +# 0.1.0 (first release) +# 0.1.1 (patch release for 0.1.0) +# 0.2 (0.2 development version towards 0.2.0) +set(Kolabutils_VERSION_MAJOR 3) +set(Kolabutils_VERSION_MINOR 1) +# Enable the full x.y.z version only for release versions +# set(Kolabutils_VERSION_PATCH 0) +# set(Kolabutils_VERSION ${Kolabutils_VERSION_MAJOR}.${Kolabutils_VERSION_MINOR}.${Kolabutils_VERSION_PATCH} ) +set(Kolabutils_VERSION ${Kolabutils_VERSION_MAJOR}.${Kolabutils_VERSION_MINOR} ) +set(Kolabutils_VERSION_STRING ${CMAKE_PROJECT_NAME}-${Kolabutils_VERSION}) + option( USE_LIBCALENDARING "Use libcalendaring" FALSE ) +option(BUILD_GOOGLESUPPORT "Build modues that require libkgoogle" FALSE) -set(CMAKE_MODULE_PATH ${KolabUtilsFormat_SOURCE_DIR}/cmake/modules) +set(CMAKE_MODULE_PATH ${KolabUtils_SOURCE_DIR}/cmake/modules) set(BIN_INSTALL_DIR bin CACHE STRING "Where to install binaries to") set(LIB_INSTALL_DIR lib CACHE STRING "Where to install libraries to") find_package(Qt4 4.6.0 REQUIRED) -find_package(Libkolab 0.4.0 REQUIRED) -find_package(Libkolabxml 0.7 REQUIRED) #We should probably add the Libkolabxml_INCLUDES to Libkolab_INCLUDES if we have libkolabxml headers in the installed libkolab headers +find_package(Libkolab 0.5.0 REQUIRED) +find_package(Libkolabxml 1.0 REQUIRED) if (USE_LIBCALENDARING) find_package(Libcalendaring) set( KDE_INCLUDES ${Libcalendaring_INCLUDE_DIRS} ) @@ -37,10 +55,13 @@ set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wnon-virtual-dtor -Wno-long-long -ansi -Wundef -Wcast-align -Wchar-subscripts -Wall -W -Wpointer-arith -Wformat-security -fno-check-new -fno-common -Woverloaded-virtual -fno-threadsafe-statics -fvisibility=hidden -Werror=return-type -fvisibility-inlines-hidden -fexceptions -UQT_NO_EXCEPTIONS -g" ) set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DQT_NO_DEBUG") +configure_file(kolabutils-version.h.cmake "${CMAKE_BINARY_DIR}/kolabutils-version.h" @ONLY) + include_directories(./ lib ${QT_INCLUDES} ${KDE_INCLUDES} ${Libkolab_INCLUDES} ${Libkolabxml_INCLUDES}) set(COMMON_DEPENDENCIES ${Libkolab_LIBRARIES} + ${Libkolabxml_LIBRARIES} ${QT_QTCORE_LIBRARY} ${QT_QTXML_LIBRARY} ${QT_GUI_LIBRARY}
View file
kolab-utils-3.0.5.tar.gz/autogen.sh -> kolab-utils-3.1.tar.gz/autogen.sh
Changed
@@ -71,7 +71,7 @@ cd .. -git archive --prefix=kolab-utils-3.0.5/ HEAD | gzip -c > kolab-utils-3.0.5.tar.gz +git archive --prefix=kolab-utils-0.4/ HEAD | gzip -c > kolab-utils-0.4.tar.gz -cp kolab-utils-3.0.5.tar.gz `rpm --eval='%{_sourcedir}'` +cp kolab-utils-0.4.tar.gz `rpm --eval='%{_sourcedir}'`
View file
kolab-utils-3.0.5.tar.gz/fbdaemon/CMakeLists.txt -> kolab-utils-3.1.tar.gz/fbdaemon/CMakeLists.txt
Changed
@@ -16,7 +16,15 @@ ${CMAKE_CURRENT_SOURCE_DIR}/kolabjob.h ${CMAKE_CURRENT_SOURCE_DIR}/fbaggregatorjob.h ) -set( FBDAEMON_SRCS ${FBDAEMON_SRCS} ${FB_MOC} ${JOBS_SRCS} ) + +set(FBDAEMON_SRCS ${FBDAEMON_SRCS} ${FB_MOC}) + +#We require 1.0, otherwise fb objects are not correctly generated: +#"Failed iTIP restrictions for FREEBUSY property. Expected one or more instances of the property and got 0" +#find_package(libical 1.0) + +add_library(fb_static STATIC ${FBDAEMON_SRCS}) +target_link_libraries(fb_static ${COMMON_DEPENDENCIES} kolabutils) add_executable(kolab-freebusyd ${FBDAEMON_SRCS} ${JOB_SRCS} main.cpp) target_link_libraries(kolab-freebusyd ${COMMON_DEPENDENCIES} kolabutils) @@ -27,4 +35,4 @@ ARCHIVE DESTINATION ${LIB_INSTALL_DIR} ) -# add_subdirectory(tests) +add_subdirectory(tests)
View file
kolab-utils-3.1.tar.gz/fbdaemon/README
Added
@@ -0,0 +1,58 @@ +The fbdeamon generates and aggreagates fb (freebusy) information on the kolab server. + +== Functionality == + +The agent has two primary purposes, the generation of kolab freebusy objects from calendar data, and the aggregation of said objects into an ical file (.ifb) that can be published for consumers. + +Freebusy information can either be: +* generated (--generate $USER) +* aggregated (--aggregate $USER) +* batch generated and aggregated for all users (--generateall $FILTER) + +$FILTER is a simply checkes wether $FILTER is part of the user (i.e. example.com, will check that example.com is part of the username). + +=== Generation === + +The generating process uses all events found in the calendar folders of the user as input, and generates a single freebusy object as output. + +The freebusy information is generated by iterating through all available events, inserting a busy period for each event that is not transparent. + +The process is influenced by the following configuration options: +* timeframe: limits the processed events to the ones that occur within the specified timeframe. The timeframe always starts at the current date-time. + +The freebusy object (see [0]) is stored in a dedicated folder for freebusy objects (kolab type "freebusy") which is created if not existing. +Note that old freebusy objects are removed by the process once a new object is generated (there is supposed to be always one per user). + +=== Aggregation === + +The aggregater is supposed to aggregate various fb-information sources. Currently the only source is the previously generated freebusy object. + +The aggregator reads all freebusy objects, merges the periods of each object and then generates an .ifb file which can then be published. Note there is no deduplication of periods and it is perfectly valid to have an object with multiple equal periods. + +The default output directory is /var/lib/kolab-freebusy + +== Configuration == + +The configruation file is by default at /etc/kolab/kolab.conf. The location can be overridden using --configuration. + +Example (with default values): + +[kolab] +imap_backend=cyrus-imap +timeframe=90 +[cyrus-imap] +uri=imaps://imap.example.org:993 +admin_login=cyrus-admin +admin_password=ADMINPASSWORD + +The following configuration options are available: +* timeframe: in days, timeframe from current date time for which to generate fb information +* admin_login/admin_password: used to get a list of users +* uri: server address in the format [imap[s]://]URL[:PORT]. Default ports are 993 for ssl and 143 otherwise. + +== Additional Information == +For additional information regarding the design and future features, see: +* http://wiki.kolab.org/Free_Busy +* http://wiki.kolab.org/FreeBusy_in_Kolab_3.0 + +[0] https://wiki.kolab.org/User:Mollekopf/Drafts/KEP:17#Freebusy \ No newline at end of file
View file
kolab-utils-3.0.5.tar.gz/fbdaemon/fbaggregatorjob.cpp -> kolab-utils-3.1.tar.gz/fbdaemon/fbaggregatorjob.cpp
Changed
@@ -39,16 +39,16 @@ return QStringList() << KOLAB_FOLDER_TYPE_FREEBUSY; } -void FBAggregatorJob::startWork(ProbeKolabServerJob* capabilitiesJob) +void FBAggregatorJob::startWork() { Debug() << "starting aggregator job for " << mSessionSettings.userName; - if (capabilitiesJob->kolabFolders().values(KOLAB_FOLDER_TYPE_FREEBUSY).isEmpty()) { + if (mKolabFolders.values(KOLAB_FOLDER_TYPE_FREEBUSY).isEmpty()) { kWarning() << "no freebusy folder found"; setError(KJob::UserDefinedError); logout(); return; } - mFreebusyFolder = capabilitiesJob->kolabFolders().values(KOLAB_FOLDER_TYPE_FREEBUSY).first(); + mFreebusyFolder = mKolabFolders.values(KOLAB_FOLDER_TYPE_FREEBUSY).first(); FetchMessagesJob *fetchJob = new FetchMessagesJob(mFreebusyFolder, mSession, this); connect( fetchJob, SIGNAL(result(KJob*)), this, SLOT(onFetchFBDone(KJob*)) ); @@ -91,7 +91,7 @@ // kDebug() << QString::fromStdString(Kolab::FreebusyUtils::toIFB(aggregatedFb)); - QFile file(QDir(Settings::instance().getAggregatedICalOutputDirectory()).absoluteFilePath(QString::fromLatin1("%1.ifb").arg(mSessionSettings.userName)/*.arg(KDateTime::currentUtcDateTime().toString(KDateTime::ISODate))*/)); + QFile file(QDir(Settings::instance().getAggregatedICalOutputDirectory()).absoluteFilePath(QString::fromLatin1("%1.ifb").arg(mSessionSettings.userName.toLower())/*.arg(KDateTime::currentUtcDateTime().toString(KDateTime::ISODate))*/)); if (!file.open(QIODevice::WriteOnly|QIODevice::Text)) { Warning() << "failed to create aggregated f/b file"; logout();
View file
kolab-utils-3.0.5.tar.gz/fbdaemon/fbaggregatorjob.h -> kolab-utils-3.1.tar.gz/fbdaemon/fbaggregatorjob.h
Changed
@@ -40,7 +40,7 @@ // void onGenerateFBDone(KJob*); // void onModDone(KJob*); private: - virtual void startWork(ProbeKolabServerJob* job); + virtual void startWork(); QString mFreebusyFolder; QString mGeneratedFile;
View file
kolab-utils-3.0.5.tar.gz/fbdaemon/fbgeneratorjob.cpp -> kolab-utils-3.1.tar.gz/fbdaemon/fbgeneratorjob.cpp
Changed
@@ -49,16 +49,16 @@ } -void FBGeneratorJob::startWork(ProbeKolabServerJob* capabilitiesJob) +void FBGeneratorJob::startWork() { - if (capabilitiesJob->kolabFolders().values(KOLAB_FOLDER_TYPE_FREEBUSY).isEmpty()) { + if (mKolabFolders.values(KOLAB_FOLDER_TYPE_FREEBUSY).isEmpty()) { kWarning() << "no freebusy folder found"; setError(KJob::UserDefinedError); logout(); return; } - mFreebusyFolder = capabilitiesJob->kolabFolders().values(KOLAB_FOLDER_TYPE_FREEBUSY).first(); - mEventFolders = capabilitiesJob->kolabFolders().values(KOLAB_FOLDER_TYPE_EVENT); + mFreebusyFolder = mKolabFolders.values(KOLAB_FOLDER_TYPE_FREEBUSY).first(); + mEventFolders = mKolabFolders.values(KOLAB_FOLDER_TYPE_EVENT); if (mEventFolders.isEmpty()) { kWarning() << "no event folders available"; logout();
View file
kolab-utils-3.0.5.tar.gz/fbdaemon/fbgeneratorjob.h -> kolab-utils-3.1.tar.gz/fbdaemon/fbgeneratorjob.h
Changed
@@ -35,7 +35,7 @@ protected: virtual QStringList requiredFolders(); private: - virtual void startWork(ProbeKolabServerJob* job); + virtual void startWork(); QString mFreebusyFolder; QStringList mEventFolders;
View file
kolab-utils-3.0.5.tar.gz/fbdaemon/generatefbjob.cpp -> kolab-utils-3.1.tar.gz/fbdaemon/generatefbjob.cpp
Changed
@@ -19,7 +19,6 @@ #include <jobs/fetchmessagesjob.h> #include <kimap/fetchjob.h> #include <kimap/selectjob.h> -#include <kdebug.h> #include <freebusy.h> #include <kolabobject.h> @@ -52,17 +51,16 @@ QList<KCalCore::Event::Ptr> events; Q_FOREACH ( const KMime::Message::Ptr &message, messages ) { // kDebug() << message->encodedContent(); - Kolab::KolabObjectReader reader(message); - if (Kolab::ErrorHandler::instance().error() > Kolab::ErrorHandler::Debug) { - kWarning() << Kolab::ErrorHandler::instance().errorMessage(); + const Kolab::KolabObjectReader reader(message); + if (Kolab::ErrorHandler::instance().errorOccured()) { + Debug() << "Error occurrend, skipping"; continue; } if (reader.getType() != Kolab::EventObject) { - kWarning() << "wrong object type in calendar =/"; + Error() << "wrong object type in calendar, skipping"; continue; } - KCalCore::Event::Ptr event = reader.getEvent(); - events.append(event); + events.append(reader.getEvent()); } const Kolab::Freebusy &fb = Kolab::FreebusyUtils::generateFreeBusy(events, start, end, KCalCore::Person::Ptr()); if (!freebusy.isValid()) { @@ -80,7 +78,7 @@ void GenerateFBJob::onFetchDone(KJob *job) { if ( job->error() ) { - kWarning() << job->errorString(); + Warning() << job->errorString(); setError(KJob::UserDefinedError); emitResult(); return;
View file
kolab-utils-3.0.5.tar.gz/fbdaemon/kolabjob.cpp -> kolab-utils-3.1.tar.gz/fbdaemon/kolabjob.cpp
Changed
@@ -24,6 +24,7 @@ #include "uiproxy.h" #include "authenticationjob.h" #include "jobs/probekolabserverjob.h" +#include <jobs/setupkolabfoldersjob.h> #include <sessionsettings.h> KolabJob::KolabJob(const SessionSettings &sessionSettings, QObject* parent) @@ -72,7 +73,6 @@ } // Debug() << "login successful"; ProbeKolabServerJob *probeJob = new ProbeKolabServerJob(mSession, this); - probeJob->createDefaultsIfMissing(requiredFolders()); QObject::connect(probeJob, SIGNAL(result(KJob*)), this, SLOT(onProbeDone(KJob*))); probeJob->start(); } @@ -85,9 +85,35 @@ emitResult(); return; } - ProbeKolabServerJob *capabilitiesJob = qobject_cast<ProbeKolabServerJob*>( job ); - Q_ASSERT(capabilitiesJob); - startWork(capabilitiesJob); + ProbeKolabServerJob *probeJob = static_cast<ProbeKolabServerJob*>(job); + mKolabFolders = probeJob->kolabFolders(); + + QString rootFolder; + QStringList toCreate; + foreach (const QString &folderType, requiredFolders()) { + if (!mKolabFolders.contains(folderType)) { + toCreate << folderType; + } + } + if (toCreate.isEmpty()) { + startWork(); + } else { + SetupKolabFoldersJob *setupJob = new SetupKolabFoldersJob(probeJob->capabilities(), rootFolder, mSession, this); + setupJob->setKolabFolders(toCreate); + connect(setupJob, SIGNAL(result(KJob*)), this, SLOT(onSetupDone(KJob*))); + setupJob->start(); + } +} + +void KolabJob::onSetupDone(KJob *job) +{ + if ( job->error() ) { + Warning() << job->errorString(); + setError(KJob::UserDefinedError); + emitResult(); + return; + } + startWork(); } void KolabJob::logout()
View file
kolab-utils-3.0.5.tar.gz/fbdaemon/kolabjob.h -> kolab-utils-3.1.tar.gz/fbdaemon/kolabjob.h
Changed
@@ -19,6 +19,8 @@ #define KOLABJOB_H #include <kimap/session.h> #include <QStringList> +#include <QHash> +#include <kimap/listjob.h> #include <sessionsettings.h> #define X_ORIGIN_HEADER "X-Freebusy-Origin" @@ -36,17 +38,18 @@ void onAuthDone(KJob*); void onProbeDone(KJob* job); void onLogoutDone(KJob*); + void onSetupDone(KJob*); protected: virtual QStringList requiredFolders(); - virtual void startWork(ProbeKolabServerJob *job) = 0; + virtual void startWork() = 0; void logout(); SessionSettings mSessionSettings; QString mFreebusyFolder; KIMAP::Session *mSession; - + QMultiHash<QString, QString> mKolabFolders; }; #endif // KOLABJOB_H
View file
kolab-utils-3.0.5.tar.gz/fbdaemon/main.cpp -> kolab-utils-3.1.tar.gz/fbdaemon/main.cpp
Changed
@@ -20,13 +20,17 @@ #include <QDir> #include <kcmdlineargs.h> #include <kdebug.h> +#include <kglobal.h> #include "fbcoordinator.h" #include "settings.h" +#include "kolabutils-version.h" int main(int argc, char *argv[]) { + //Init for ki18n calls + KGlobal::locale(); - KCmdLineArgs::init(argc, argv, argv[0], QByteArray(), ki18n("freebusy"), "0.1"); + KCmdLineArgs::init(argc, argv, argv[0], QByteArray(), ki18n("freebusy"), KOLABUTILS_VERSION, ki18n("kolab freebusy generator"), KCmdLineArgs::CmdLineArgNone); KCmdLineOptions options; options.add("c").add("configuration <file>", ki18n("Configuration file"), "/etc/kolab/kolab.conf"); @@ -82,4 +86,4 @@ } return 0; -} \ No newline at end of file +}
View file
kolab-utils-3.0.5.tar.gz/fbdaemon/tests/CMakeLists.txt -> kolab-utils-3.1.tar.gz/fbdaemon/tests/CMakeLists.txt
Changed
@@ -1,17 +1,14 @@ +include_directories( + ${CMAKE_CURRENT_SOURCE_DIR}/.. + ${CMAKE_CURRENT_BINARY_DIR} +) -include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/.. ) -include_directories(${CMAKE_CURRENT_BINARY_DIR}) +set(FBTEST_DEPENDENCIES ${COMMON_DEPENDENCIES} ${QT_QTTEST_LIBRARY} kolabutils fb_static) -qt4_generate_moc( - ${CMAKE_CURRENT_SOURCE_DIR}/fbgeneratortest.cpp - ${CMAKE_CURRENT_BINARY_DIR}/fbgeneratortest.moc -) -add_executable(fbgeneratortest ${FBDAEMON_SRCS} fbgeneratortest.cpp fbgeneratortest.moc) -target_link_libraries(fbgeneratortest ${COMMON_DEPENDENCIES} ${QT_QTTEST_LIBRARY} kolabutils) +qt4_automoc(fbgeneratortest.cpp) +add_executable(fbgeneratortest fbgeneratortest.cpp) +target_link_libraries(fbgeneratortest ${FBTEST_DEPENDENCIES}) -qt4_generate_moc( - ${CMAKE_CURRENT_SOURCE_DIR}/fbaggregatortest.cpp - ${CMAKE_CURRENT_BINARY_DIR}/fbaggregatortest.moc -) -add_executable(fbaggregatortest ${FBDAEMON_SRCS} fbaggregatortest.cpp fbaggregatortest.moc) -target_link_libraries(fbaggregatortest ${COMMON_DEPENDENCIES} ${QT_QTTEST_LIBRARY} kolabutils) \ No newline at end of file +qt4_automoc(fbaggregatortest.cpp) +add_executable(fbaggregatortest fbaggregatortest.cpp) +target_link_libraries(fbaggregatortest ${FBTEST_DEPENDENCIES}) \ No newline at end of file
View file
kolab-utils-3.0.5.tar.gz/fbdaemon/tests/fbaggregatortest.cpp -> kolab-utils-3.1.tar.gz/fbdaemon/tests/fbaggregatortest.cpp
Changed
@@ -15,125 +15,107 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include <QObject> +#include "fbaggregatortest.h" + #include <QTest> #include <QDebug> #include <QDir> -#include <kolabobject.h> -#include <freebusy.h> -#include <kcalconversion.h> #include <kcalcore/memorycalendar.h> #include <kcalcore/icalformat.h> +#include <freebusy.h> +#include <kcalconversion.h> +#include <kolabobject.h> #include "fbdaemon/fbgeneratorjob.h" +#include "fbdaemon/fbaggregatorjob.h" #include "settings.h" -#include <fbaggregatorjob.h> #include "kolabaccount.h" #include "testlib/testutils.h" -class FBAggregatorTest: public QObject +FBAggregatorTest::FBAggregatorTest(QObject* parent) + : QObject(parent), + targethost("192.168.122.10"), + user("john.doe@example.org"), + admin("cyrus-admin"), + adminpw("admin"), + port(143) { - Q_OBJECT - -// QString sourcehost; - QString targethost; - QString user; - QString admin; - QString adminpw; - qint16 port; - QList<Folder> folders; - QString generatedFile; + Object fbObj1; + Kolab::Freebusy fb; + fb.setOrganizer(Kolab::ContactReference("mail@example.com", "john doe")); + fb.setStart(Kolab::Conversion::fromDate(KDateTime::currentUtcDateTime())); + fb.setEnd(Kolab::Conversion::fromDate(KDateTime::currentUtcDateTime().addDays(60))); + fbObj1.object = QVariant::fromValue(Kolab::KolabObjectWriter::writeFreebusy(fb, Kolab::KolabV3, "fbtest")); -public: - explicit FBAggregatorTest(QObject* parent = 0) - : QObject(parent), -// sourcehost("192.168.122.104"), - targethost("192.168.122.10"), - user("john.doe@example.org"), - admin("cyrus-admin"), - adminpw("admin"), - port(143) - { - Object fbObj1; - Kolab::Freebusy fb; - fb.setOrganizer(Kolab::ContactReference("mail@example.com", "john doe")); - fb.setStart(Kolab::Conversion::fromDate(KDateTime::currentUtcDateTime())); - fb.setEnd(Kolab::Conversion::fromDate(KDateTime::currentUtcDateTime().addDays(60))); - fbObj1.object = QVariant::fromValue(Kolab::KolabObjectWriter::writeFreebusy(fb, Kolab::KolabV3, "fbtest")); - - Object fbObj2; - Kolab::Freebusy fb2; - fb2.setStart(Kolab::Conversion::fromDate(KDateTime::currentUtcDateTime())); - fb2.setEnd(Kolab::Conversion::fromDate(KDateTime::currentUtcDateTime().addDays(60))); - fbObj2.object = QVariant::fromValue(Kolab::KolabObjectWriter::writeFreebusy(fb2, Kolab::KolabV3, "fbtest")); - - folders << Folder("Freebusy", Kolab::FreebusyType, QList<Object>() << fbObj1 << fbObj2); - } + Object fbObj2; + Kolab::Freebusy fb2; + fb2.setStart(Kolab::Conversion::fromDate(KDateTime::currentUtcDateTime())); + fb2.setEnd(Kolab::Conversion::fromDate(KDateTime::currentUtcDateTime().addDays(60))); + fbObj2.object = QVariant::fromValue(Kolab::KolabObjectWriter::writeFreebusy(fb2, Kolab::KolabV3, "fbtest")); -private: + folders << Folder("Freebusy", Kolab::FreebusyType, QList<Object>() << fbObj1 << fbObj2); +} - void setupTargetAccount() - { - QObject obj; - KolabAccount *account = new KolabAccount(&obj); - account->setHost(targethost, port); - account->setCredentials(user, adminpw, admin); - account->setEncryptionMode(KIMAP::LoginJob::TlsV1); - QVERIFY(account->init()); +void FBAggregatorTest::setupTargetAccount() +{ + QObject obj; + KolabAccount *account = new KolabAccount(&obj); + account->setHost(targethost, port); + account->setCredentials(user, adminpw, admin); + account->setEncryptionMode(KIMAP::LoginJob::TlsV1); + QVERIFY(account->init()); + + account->cleanAccount(); + createFolders(account, folders); +} - account->cleanAccount(); - createFolders(account, folders); - } +void FBAggregatorTest::executeAggregation() +{ + Settings::instance().setAuthorizationUser(admin); + Settings::instance().setPassword(adminpw); + Settings::instance().setServerUri(targethost); + Settings::instance().setThreshold(10); + Settings::instance().setTimeframe(60); + Settings::instance().setAggregatedICalOutputDirectory(QDir::tempPath()); + SessionSettings sessionSettings = Settings::instance().getSessionSettings(); + sessionSettings.userName = user; - void executeAggregation() - { - Settings::instance().setAuthorizationUser(admin); - Settings::instance().setPassword(adminpw); - Settings::instance().setServerUri(targethost); - Settings::instance().setThreshold(10); - Settings::instance().setTimeframe(60); - Settings::instance().setAggregatedICalOutputDirectory(QDir::tempPath()); - SessionSettings sessionSettings = Settings::instance().getSessionSettings(); - sessionSettings.userName = user; - - QObject obj; - FBAggregatorJob *job = new FBAggregatorJob(sessionSettings, &obj); - job->exec(); - generatedFile = job->generatedFile(); - } + QObject obj; + FBAggregatorJob *job = new FBAggregatorJob(sessionSettings, &obj); + job->exec(); + generatedFile = job->generatedFile(); +} - void checkFbObject() - { - QVERIFY(QFileInfo(generatedFile).exists()); - QFile file(generatedFile); - QVERIFY(file.open(QIODevice::ReadOnly|QIODevice::Text)); - QTextStream in(&file); - QString data = in.readAll(); +void FBAggregatorTest::checkFbObject() +{ + QVERIFY(QFileInfo(generatedFile).exists()); + QFile file(generatedFile); + QVERIFY(file.open(QIODevice::ReadOnly|QIODevice::Text)); + QTextStream in(&file); + QString data = in.readAll(); - qDebug() << data; - - KCalCore::ICalFormat format; - KCalCore::Calendar::Ptr cal(new KCalCore::MemoryCalendar(KDateTime::Spec::UTC())); - KCalCore::ScheduleMessage::Ptr msg = format.parseScheduleMessage(cal, data); - QVERIFY(msg); - QCOMPARE(msg->method(), KCalCore::iTIPPublish); - QCOMPARE(format.timeSpec(), KDateTime::Spec::UTC()); - QVERIFY(msg->event()); - QCOMPARE(msg->event()->organizer()->email(), QLatin1String("john.doe@example.org")); - QVERIFY(!msg->event()->uid().isEmpty()); - QVERIFY(msg->event()->lastModified().isValid()); - - //Check that aggregated fb object has been created - } + qDebug() << data; + + KCalCore::ICalFormat format; + KCalCore::Calendar::Ptr cal(new KCalCore::MemoryCalendar(KDateTime::Spec::UTC())); + KCalCore::ScheduleMessage::Ptr msg = format.parseScheduleMessage(cal, data); + QVERIFY(msg); + QCOMPARE(msg->method(), KCalCore::iTIPPublish); + QCOMPARE(format.timeSpec(), KDateTime::Spec::UTC()); + QVERIFY(msg->event()); + QCOMPARE(msg->event()->organizer()->email(), QLatin1String("john.doe@example.org")); + QVERIFY(!msg->event()->uid().isEmpty()); + QVERIFY(msg->event()->lastModified().isValid()); + + //Check that aggregated fb object has been created +} -private slots: - void testGenerator() - { - setupTargetAccount(); - executeAggregation(); - checkFbObject(); - } +void FBAggregatorTest::testGenerator() +{ + setupTargetAccount(); + executeAggregation();
View file
kolab-utils-3.1.tar.gz/fbdaemon/tests/fbaggregatortest.h
Added
@@ -0,0 +1,46 @@ +/* + * Copyright (C) 2012 Christian Mollekopf <mollekopf@kolabsys.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +#ifndef FBAGGREGATORTEST_H +#define FBAGGREGATORTEST_H + +#include <QObject> +#include "testlib/testutils.h" + +class FBAggregatorTest: public QObject +{ + Q_OBJECT +public: + explicit FBAggregatorTest(QObject* parent = 0); + +private slots: + void testGenerator(); + +private: + void setupTargetAccount(); + void executeAggregation(); + void checkFbObject(); + + QString targethost; + QString user; + QString admin; + QString adminpw; + qint16 port; + QList<Folder> folders; + QString generatedFile; +}; + +#endif
View file
kolab-utils-3.0.5.tar.gz/fbdaemon/tests/fbgeneratortest.cpp -> kolab-utils-3.1.tar.gz/fbdaemon/tests/fbgeneratortest.cpp
Changed
@@ -14,8 +14,8 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "fbgeneratortest.h" -#include <QObject> #include <QTest> #include <QDebug> #include <QDir> @@ -25,120 +25,101 @@ #include "fbdaemon/fbgeneratorjob.h" #include "settings.h" #include "kolabaccount.h" -#include "testlib/testutils.h" -class FBGeneratorTest: public QObject +FBGeneratorTest::FBGeneratorTest(QObject* parent) + : QObject(parent), + targethost("192.168.122.10"), + user("john.doe@example.org"), + admin("cyrus-admin"), + adminpw("admin"), + port(143) { - Q_OBJECT - -// QString sourcehost; - QString targethost; - QString user; - QString admin; - QString adminpw; - qint16 port; - QList<Folder> folders; + Object calObj1; + KCalCore::Event::Ptr event(new KCalCore::Event()); + event->setUid("uid1"); + event->setDtStart(KDateTime::currentUtcDateTime()); + event->setDtEnd(KDateTime::currentUtcDateTime().addSecs(3600)); + calObj1.object = QVariant::fromValue(Kolab::KolabObjectWriter::writeEvent(event, Kolab::KolabV3, "fbtest")); + folders << Folder("Calendar", Kolab::EventType, QList<Object>() << calObj1); -public: - explicit FBGeneratorTest(QObject* parent = 0) - : QObject(parent), -// sourcehost("192.168.122.104"), - targethost("192.168.122.10"), - user("john.doe@example.org"), - admin("cyrus-admin"), - adminpw("admin"), - port(143) - { - Object calObj1; - KCalCore::Event::Ptr event(new KCalCore::Event()); - event->setUid("uid1"); - event->setDtStart(KDateTime::currentUtcDateTime()); - event->setDtEnd(KDateTime::currentUtcDateTime().addSecs(3600)); - calObj1.object = QVariant::fromValue(Kolab::KolabObjectWriter::writeEvent(event, Kolab::KolabV3, "fbtest")); - folders << Folder("Calendar", Kolab::EventType, QList<Object>() << calObj1); - // folders << Folder("Freebusy", Kolab::FreebusyType, QList<Object>()/* << fbObj1*/); - } +} -private: +void FBGeneratorTest::setupTargetAccount() +{ + QObject obj; + KolabAccount *account = new KolabAccount(&obj); + account->setHost(targethost, port); + account->setCredentials(user, adminpw, admin); + QVERIFY(account->init()); - void setupTargetAccount() - { - QObject obj; - KolabAccount *account = new KolabAccount(&obj); - account->setHost(targethost, port); - account->setCredentials(user, adminpw, admin); - QVERIFY(account->init()); + account->cleanAccount(); + createFolders(account, folders); +} - account->cleanAccount(); - createFolders(account, folders); - } +void FBGeneratorTest::executeGeneration() +{ + Settings::instance().setAuthorizationUser(admin); + Settings::instance().setPassword(adminpw); + Settings::instance().setServerUri(targethost); + Settings::instance().setThreshold(10); + Settings::instance().setTimeframe(60); + Settings::instance().setAggregatedICalOutputDirectory(QDir::tempPath()); + SessionSettings sessionSettings = Settings::instance().getSessionSettings(); + sessionSettings.userName = user; - void executeGeneration() - { - Settings::instance().setAuthorizationUser(admin); - Settings::instance().setPassword(adminpw); - Settings::instance().setServerUri(targethost); - Settings::instance().setThreshold(10); - Settings::instance().setTimeframe(60); - Settings::instance().setAggregatedICalOutputDirectory(QDir::tempPath()); - SessionSettings sessionSettings = Settings::instance().getSessionSettings(); - sessionSettings.userName = user; - - QObject obj; - FBGeneratorJob *job = new FBGeneratorJob(sessionSettings, &obj); - job->exec(); - } + QObject obj; + FBGeneratorJob *job = new FBGeneratorJob(sessionSettings, &obj); + job->exec(); +} - void checkFolders(KolabAccount *account, const QList<Folder> &folders) - { - const QStringList &receivedFolders = account->lookupFolderList(); - qDebug() << receivedFolders; - foreach(const Folder &folder, folders) { - qDebug() << folder.name; - QVERIFY(receivedFolders.contains(folder.name)); - const QList<Object> &objects = account->getObjects(folder.name); - QCOMPARE(objects.size(), folder.objects.size()); - - QList<Object>::const_iterator recObjIt = objects.constBegin(); - QList<Object>::const_iterator objIt = folder.objects.constBegin(); - for (;objIt != folder.objects.constEnd() && recObjIt != objects.constEnd(); ++objIt, ++recObjIt) { - //TODO Check fb objects - } +void FBGeneratorTest::checkFolders(KolabAccount *account, const QList<Folder> &folders) +{ + const QStringList &receivedFolders = account->lookupFolderList(); + qDebug() << receivedFolders; + foreach(const Folder &folder, folders) { + qDebug() << folder.name; + QVERIFY(receivedFolders.contains(folder.name)); + const QList<Object> &objects = account->getObjects(folder.name); + QCOMPARE(objects.size(), folder.objects.size()); + + QList<Object>::const_iterator recObjIt = objects.constBegin(); + QList<Object>::const_iterator objIt = folder.objects.constBegin(); + for (;objIt != folder.objects.constEnd() && recObjIt != objects.constEnd(); ++objIt, ++recObjIt) { + //TODO Check fb objects } } +} - void checkTargetAccount() - { - //Check that fb-object and aggregated fb object has been created - QObject obj; - KolabAccount *account = new KolabAccount(&obj); - account->setHost(targethost, port); - account->setCredentials(user, adminpw, admin); - account->init(); +void FBGeneratorTest::checkTargetAccount() +{ + //Check that fb-object and aggregated fb object has been created + QObject obj; + KolabAccount *account = new KolabAccount(&obj); + account->setHost(targethost, port); + account->setCredentials(user, adminpw, admin); + account->init(); - Object fbObj1; - Kolab::Freebusy fb; - fb.setStart(Kolab::Conversion::fromDate(KDateTime::currentUtcDateTime())); - fb.setEnd(Kolab::Conversion::fromDate(KDateTime::currentUtcDateTime().addDays(60))); - fbObj1.object = QVariant(Kolab::KolabObjectWriter::writeFreebusy(fb, Kolab::KolabV3, "fbtest")); - - QList<Folder> targetFolders; - targetFolders << Folder("Freebusy", Kolab::FreebusyType, QList<Object>() << fbObj1); - checkFolders(account, targetFolders); - account->logout(); - } + Object fbObj1; + Kolab::Freebusy fb; + fb.setStart(Kolab::Conversion::fromDate(KDateTime::currentUtcDateTime())); + fb.setEnd(Kolab::Conversion::fromDate(KDateTime::currentUtcDateTime().addDays(60))); + fbObj1.object = QVariant(Kolab::KolabObjectWriter::writeFreebusy(fb, Kolab::KolabV3, "fbtest")); + + QList<Folder> targetFolders; + targetFolders << Folder("Freebusy", Kolab::FreebusyType, QList<Object>() << fbObj1); + checkFolders(account, targetFolders); + account->logout(); +} -private slots: - void testGenerator() - { - setupTargetAccount(); - executeGeneration(); - checkTargetAccount(); - } +void FBGeneratorTest::testGenerator()
View file
kolab-utils-3.1.tar.gz/fbdaemon/tests/fbgeneratortest.h
Added
@@ -0,0 +1,47 @@ +/* + * Copyright (C) 2012 Christian Mollekopf <mollekopf@kolabsys.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +#ifndef FBGENERATORTEST_H +#define FBGENERATORTEST_H + +#include <QObject> +#include "testlib/testutils.h" + +class KolabAccount; +class FBGeneratorTest: public QObject +{ + Q_OBJECT +public: + explicit FBGeneratorTest(QObject* parent = 0); + +private slots: + void testGenerator(); + +private: + void setupTargetAccount(); + void executeGeneration(); + void checkFolders(KolabAccount *account, const QList<Folder> &folders); + void checkTargetAccount(); + + QString targethost; + QString user; + QString admin; + QString adminpw; + qint16 port; + QList<Folder> folders; +}; + +#endif \ No newline at end of file
View file
kolab-utils-3.1.tar.gz/kolabutils-version.h.cmake
Added
@@ -0,0 +1,24 @@ +/* + * Copyright (C) 2012 Christian Mollekopf <mollekopf@kolabsys.com> + * + * 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 KOLABUTILS_VERSION_H +#define KOLABUTILS_VERSION_H + +#define KOLABUTILS_VERSION "@Kolabutils_VERSION@" +#define KOLABUTILS_VERSION_STRING "@Kolabutils_VERSION_STRING@" + +#endif \ No newline at end of file
View file
kolab-utils-3.0.5.tar.gz/lib/CMakeLists.txt -> kolab-utils-3.1.tar.gz/lib/CMakeLists.txt
Changed
@@ -7,12 +7,14 @@ add_subdirectory(jobs) QT4_WRAP_CPP(JOB_MOC ${CMAKE_CURRENT_SOURCE_DIR}/jobs/findkolabfoldersjob.h + ${CMAKE_CURRENT_SOURCE_DIR}/jobs/probeimapserverjob.h ${CMAKE_CURRENT_SOURCE_DIR}/jobs/probekolabserverjob.h ${CMAKE_CURRENT_SOURCE_DIR}/jobs/sequentialcompositejob.h ${CMAKE_CURRENT_SOURCE_DIR}/jobs/messagemodifyjob.h ${CMAKE_CURRENT_SOURCE_DIR}/jobs/fetchmessagesjob.h ${CMAKE_CURRENT_SOURCE_DIR}/jobs/setupkolabfoldersjob.h ${CMAKE_CURRENT_SOURCE_DIR}/jobs/getuserlistjob.h + ${CMAKE_CURRENT_SOURCE_DIR}/jobs/createkolabfolderjob.h ) set( JOBS_SRCS ${JOBS_SRCS} ${JOB_MOC} ) @@ -32,6 +34,4 @@ RUNTIME DESTINATION ${BIN_INSTALL_DIR} LIBRARY DESTINATION ${LIB_INSTALL_DIR} ARCHIVE DESTINATION ${LIB_INSTALL_DIR} -) - -add_subdirectory(testlib) \ No newline at end of file +) \ No newline at end of file
View file
kolab-utils-3.0.5.tar.gz/lib/jobs/CMakeLists.txt -> kolab-utils-3.1.tar.gz/lib/jobs/CMakeLists.txt
Changed
@@ -1,10 +1,12 @@ set (JOBS_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/findkolabfoldersjob.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/probeimapserverjob.cpp ${CMAKE_CURRENT_SOURCE_DIR}/probekolabserverjob.cpp ${CMAKE_CURRENT_SOURCE_DIR}/sequentialcompositejob.cpp ${CMAKE_CURRENT_SOURCE_DIR}/messagemodifyjob.cpp ${CMAKE_CURRENT_SOURCE_DIR}/fetchmessagesjob.cpp ${CMAKE_CURRENT_SOURCE_DIR}/setupkolabfoldersjob.cpp ${CMAKE_CURRENT_SOURCE_DIR}/getuserlistjob.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/createkolabfolderjob.cpp PARENT_SCOPE)
View file
kolab-utils-3.1.tar.gz/lib/jobs/createkolabfolderjob.cpp
Added
@@ -0,0 +1,109 @@ +/* + * Copyright (C) 2013 Christian Mollekopf <mollekopf@kolabsys.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "createkolabfolderjob.h" + +#include <kimap/createjob.h> +#include <kimap/setmetadatajob.h> +#include <QStringList> + +#include <errorhandler.h> +#include <kolabdefinitions.h> + +CreateKolabFolderJob::CreateKolabFolderJob(const QString& name, const QByteArray& sharedAnnotation, const QByteArray& privateAnnotation, CreateKolabFolderJob::MetadataCapability cap, KIMAP::Session* session, QObject* parent) +: KJob(parent), + m_session(session), + m_name(name), + m_sharedAnnotation(sharedAnnotation), + m_privateAnnotation(privateAnnotation), + m_metadataCapability(cap) +{ + +} + +void CreateKolabFolderJob::start() +{ + KIMAP::CreateJob *createJob = new KIMAP::CreateJob(m_session); + createJob->setMailBox(m_name); + connect(createJob, SIGNAL(result(KJob*)), this, SLOT(onCreateDone(KJob*))); + createJob->start(); +} + +CreateKolabFolderJob::MetadataCapability CreateKolabFolderJob::capablitiesFromString(const QString &cap) +{ + if (cap.contains(QLatin1String("ANNOTATEMORE"))) { + return Annotatemore; + } + return Metadata; +} + +CreateKolabFolderJob::MetadataCapability CreateKolabFolderJob::capablitiesFromString(const QStringList &cap) +{ + if (cap.contains(QLatin1String("ANNOTATEMORE"))) { + return Annotatemore; + } + return Metadata; +} + +void CreateKolabFolderJob::onCreateDone(KJob *job) +{ + if (job->error()) { + Warning() << job->errorString() << "Trying to fix the metadata"; + } else { + KIMAP::CreateJob *createJob = static_cast<KIMAP::CreateJob*>(job); + Debug() << "Created folder " << createJob->mailBox(); + } + + KIMAP::SetMetaDataJob *setMetadataJob = new KIMAP::SetMetaDataJob(m_session); + setMetadataJob->setMailBox(m_name); + if ( m_metadataCapability == Metadata ) { + setMetadataJob->setServerCapability( KIMAP::MetaDataJobBase::Metadata ); + if (!m_sharedAnnotation.isEmpty()) { + setMetadataJob->addMetaData("/shared" KOLAB_FOLDER_TYPE_ANNOTATION, m_sharedAnnotation); + } + if (!m_privateAnnotation.isEmpty()) { + setMetadataJob->addMetaData("/private" KOLAB_FOLDER_TYPE_ANNOTATION, m_privateAnnotation); + } + } else { + setMetadataJob->setServerCapability( KIMAP::MetaDataJobBase::Annotatemore ); + setMetadataJob->setEntry( KOLAB_FOLDER_TYPE_ANNOTATION ); + if (!m_sharedAnnotation.isEmpty()) { + setMetadataJob->addMetaData("value.shared", m_sharedAnnotation); + } + if (!m_privateAnnotation.isEmpty()) { + setMetadataJob->addMetaData("value.priv", m_privateAnnotation); + } + } + connect(setMetadataJob, SIGNAL(result(KJob*)), this, SLOT(onMetadataSetDone(KJob*))); + setMetadataJob->start(); +} + +void CreateKolabFolderJob::onMetadataSetDone(KJob *job) +{ + if ( job->error() ) { + Warning() << job->errorString(); + setErrorText("Failed to create folder: " + m_name); + setError(KJob::UserDefinedError); + } + emitResult(); +} + +QString CreateKolabFolderJob::folder() const +{ + return m_name; +} +
View file
kolab-utils-3.1.tar.gz/lib/jobs/createkolabfolderjob.h
Added
@@ -0,0 +1,54 @@ +/* + * Copyright (C) 2013 Christian Mollekopf <mollekopf@kolabsys.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef CREATEKOLABFOLDERJOB_H +#define CREATEKOLABFOLDERJOB_H + +#include <kjob.h> + +namespace KIMAP { +class Session; +} + +class CreateKolabFolderJob : public KJob +{ + Q_OBJECT +public: + enum MetadataCapability { + Metadata, + Annotatemore + }; + explicit CreateKolabFolderJob(const QString &name, const QByteArray &sharedAnnotation, const QByteArray &privateAnnotation, MetadataCapability cap, KIMAP::Session *session, QObject* parent = 0); + virtual void start(); + + QString folder() const; + + static MetadataCapability capablitiesFromString(const QString &); + static MetadataCapability capablitiesFromString(const QStringList &); + +private slots: + void onCreateDone(KJob*); + void onMetadataSetDone(KJob*); +private: + KIMAP::Session *m_session; + QString m_name; + QByteArray m_sharedAnnotation; + QByteArray m_privateAnnotation; + MetadataCapability m_metadataCapability; +}; + +#endif
View file
kolab-utils-3.0.5.tar.gz/lib/jobs/fetchmessagesjob.cpp -> kolab-utils-3.1.tar.gz/lib/jobs/fetchmessagesjob.cpp
Changed
@@ -27,9 +27,33 @@ FetchMessagesJob::FetchMessagesJob(const QString &folder, KIMAP::Session *session, QObject* parent) : KJob(parent), mSession(session), - mFolder(folder) + mFolder(folder), + mNumberOfMessagesToFetch(0), + mTransient(false), + mBatchSizeLimit(10000000), //in bytes => 10MB + mBatchSize(0) { + mFetchScope.mode = KIMAP::FetchJob::FetchScope::Full; +} +void FetchMessagesJob::setMaxNumberOfMessagesToFetch(int number) +{ + mNumberOfMessagesToFetch = number; +} + +void FetchMessagesJob::setUidsToFetch(const QList< qint64 >& uids) +{ + mUidsToFetch = uids; +} + +void FetchMessagesJob::setUidsToSkip(const QList< qint64 >& uids) +{ + mUidsToSkip = uids; +} + +void FetchMessagesJob::setTransient(bool transient) +{ + mTransient = transient; } void FetchMessagesJob::start() @@ -37,10 +61,16 @@ Debug() << "Fetching messages from Mailbox....... " << mFolder; KIMAP::SelectJob *select = new KIMAP::SelectJob( mSession ); select->setMailBox( mFolder ); + select->setOpenReadOnly( true ); connect( select, SIGNAL(result(KJob*)), this, SLOT(onSelectDone(KJob*)) ); select->start(); } +KIMAP::FetchJob::FetchScope& FetchMessagesJob::fetchScope() +{ + return mFetchScope; +} + void FetchMessagesJob::onSelectDone(KJob *job) { if ( job->error() ) { @@ -54,20 +84,32 @@ Q_ASSERT(select); const int messageCount = select->messageCount(); - if (messageCount <= 0) { //empty, nothing to do Debug() << "no messages available, nothing to do"; emitResult(); return; } - - KIMAP::FetchJob::FetchScope scope; - scope.mode = KIMAP::FetchJob::FetchScope::Full; + setTotalAmount(Files, messageCount); + Debug() << "Found " << messageCount << " messages"; + + int messagesToFetch = messageCount; + if (mNumberOfMessagesToFetch > 0) { + messagesToFetch = qMin(mNumberOfMessagesToFetch, messageCount); + } KIMAP::FetchJob *fetch = new KIMAP::FetchJob( mSession ); - fetch->setSequenceSet( KIMAP::ImapSet( 1, messageCount ) ); - fetch->setScope( scope ); + KIMAP::FetchJob::FetchScope fetchScope; + fetchScope.mode = KIMAP::FetchJob::FetchScope::Headers; + fetch->setScope( fetchScope ); + if (!mUidsToFetch.isEmpty()) { + KIMAP::ImapSet set; + set.add(mUidsToFetch); + fetch->setSequenceSet(set); + fetch->setUidBased(true); + } else { + fetch->setSequenceSet(KIMAP::ImapSet(1, messagesToFetch)); + } connect( fetch, SIGNAL( headersReceived( QString, QMap<qint64, qint64>, QMap<qint64, qint64>, QMap<qint64, KIMAP::MessageFlags>, QMap<qint64, KIMAP::MessagePtr> ) ), this, SLOT( onHeadersReceived( QString, QMap<qint64, qint64>, QMap<qint64, qint64>, @@ -77,30 +119,93 @@ fetch->start(); } -void FetchMessagesJob::onHeadersReceived( const QString &/* mailBox */, +void FetchMessagesJob::onHeadersReceived( const QString &/*mailBox*/, + const QMap<qint64, qint64> &uids, + const QMap<qint64, qint64> &sizes, + const QMap<qint64, KIMAP::MessageFlags> &/*flags*/, + const QMap<qint64, KIMAP::MessagePtr> &/*messages*/ ) +{ + QMap <qint64, qint64 >::const_iterator it = sizes.begin(); + for (;it != sizes.end(); it++) { + const qint64 uid = uids.value(it.key()); + if (mUidsToSkip.contains(uid)) { + continue; + } + if ((mBatchSize + it.value()) >= mBatchSizeLimit) { +// Debug() << "Batch full " << (int)mBatchSize; + mBatchSize = 0; + if (!mTempSet.isEmpty()) { + mBatches.append(mTempSet); + mTempSet = KIMAP::ImapSet(); + } + } + mBatchSize += it.value(); + mTempSet.add(uid); + } +} + +void FetchMessagesJob::onHeadersFetchDone( KJob *job ) +{ + if ( job->error() ) { + Warning() << job->errorString(); + } + if (!mTempSet.isEmpty()) { + mBatches.append(mTempSet); + } + fetchNextBatch(); +} + +void FetchMessagesJob::fetchNextBatch() +{ + if (mBatches.isEmpty()) { + emitResult(); + return; + } + const KIMAP::ImapSet batch = mBatches.takeFirst(); + KIMAP::FetchJob *fetch = new KIMAP::FetchJob( mSession ); + fetch->setScope( mFetchScope ); + fetch->setSequenceSet(batch); + fetch->setUidBased(true); + connect( fetch, SIGNAL( headersReceived( QString, QMap<qint64, qint64>, QMap<qint64, qint64>, + QMap<qint64, KIMAP::MessageFlags>, QMap<qint64, KIMAP::MessagePtr> ) ), + this, SLOT( onMessagesReceived( QString, QMap<qint64, qint64>, QMap<qint64, qint64>, + QMap<qint64, KIMAP::MessageFlags>, QMap<qint64, KIMAP::MessagePtr> ) ) ); + connect( fetch, SIGNAL(result(KJob*)), + this, SLOT(onMessagesFetchDone(KJob*)) ); + fetch->start(); +} + +void FetchMessagesJob::onMessagesReceived( const QString &mailBox, const QMap<qint64, qint64> &uids, const QMap<qint64, qint64> &/* sizes */, const QMap<qint64, KIMAP::MessageFlags> &flags, const QMap<qint64, KIMAP::MessagePtr> &messages ) { -// Debug() << mailBox; + QList <Object> objects; foreach (qint64 key, uids.keys()) { Q_ASSERT(messages.contains(key)); - mMessages.insert(key, messages.value(key)); Q_ASSERT(flags.contains(key)); - mFlags.insert(key, flags.value(key)); - mUids.insert(key, uids.value(key)); + if (!mTransient) { + mMessages.insert(key, messages.value(key)); + mFlags.insert(key, flags.value(key)); + mUids.insert(key, uids.value(key)); + } + Object obj; + obj.flags = flags.value(key); + obj.object = QVariant::fromValue(messages.value(key)); + obj.imapUid = uids.value(key); + objects << obj; } + emit messagesReceived(mailBox, objects); + setProcessedAmount(Files, processedAmount(Files)+uids.size()); } -void FetchMessagesJob::onHeadersFetchDone( KJob *job ) +void FetchMessagesJob::onMessagesFetchDone( KJob *job ) { if ( job->error() ) { Warning() << job->errorString(); - emitResult(); - return; } - emitResult(); + fetchNextBatch(); } QList< KMime::Message::Ptr > FetchMessagesJob::getMessages() const @@ -108,6 +213,11 @@ return mMessages.values(); } +QList< qint64 > FetchMessagesJob::getImapUids() const +{
View file
kolab-utils-3.0.5.tar.gz/lib/jobs/fetchmessagesjob.h -> kolab-utils-3.1.tar.gz/lib/jobs/fetchmessagesjob.h
Changed
@@ -21,6 +21,7 @@ #include <kmime/kmime_message.h> #include <kimap/session.h> #include <kimap/fetchjob.h> +#include <object.h> class FetchMessagesJob: public KJob { @@ -28,10 +29,20 @@ public: explicit FetchMessagesJob(const QString &folder, KIMAP::Session *, QObject* parent = 0); virtual void start(); + void setMaxNumberOfMessagesToFetch(int); + void setUidsToFetch(const QList<qint64> &uids); + void setUidsToSkip(const QList<qint64> &uids); + KIMAP::FetchJob::FetchScope &fetchScope(); + + //Controls wether mapping are collected or not (otherwise the functions below return nothing) + void setTransient(bool transient); QList<KMime::Message::Ptr> getMessages() const; + QList<qint64> getImapUids() const; KIMAP::MessageFlags getFlags(KMime::Message::Ptr) const; qint64 getImapUid(KMime::Message::Ptr) const; +Q_SIGNALS: + void messagesReceived(QString, QList<Object>); private Q_SLOTS: void onSelectDone(KJob *job); void onHeadersReceived( const QString &mailBox, @@ -40,14 +51,29 @@ const QMap<qint64, KIMAP::MessageFlags> &flags, const QMap<qint64, KIMAP::MessagePtr> &messages ); void onHeadersFetchDone( KJob *job ); + void onMessagesReceived( const QString &mailBox, + const QMap<qint64, qint64> &uids, + const QMap<qint64, qint64> &sizes, + const QMap<qint64, KIMAP::MessageFlags> &flags, + const QMap<qint64, KIMAP::MessagePtr> &messages ); + void onMessagesFetchDone( KJob *job ); private: - void checkJobDone(); + void fetchNextBatch(); KIMAP::Session *mSession; + KIMAP::FetchJob::FetchScope mFetchScope; QString mFolder; QMap<qint64, qint64> mUids; QMap<qint64, KIMAP::MessageFlags> mFlags; QMap<qint64, KIMAP::MessagePtr> mMessages; + QList<qint64> mUidsToFetch; + QList<qint64> mUidsToSkip; + int mNumberOfMessagesToFetch; + bool mTransient; + KIMAP::ImapSet mTempSet; + qint64 mBatchSizeLimit; + qint64 mBatchSize; + QList<KIMAP::ImapSet> mBatches; }; #endif // FETCHMESSAGESJOB_H
View file
kolab-utils-3.0.5.tar.gz/lib/jobs/findkolabfoldersjob.cpp -> kolab-utils-3.1.tar.gz/lib/jobs/findkolabfoldersjob.cpp
Changed
@@ -82,10 +82,15 @@ meta->setMailBox( descriptor.name ); if ( m_serverCapabilities.contains( "METADATA" ) ) { meta->setServerCapability( KIMAP::MetaDataJobBase::Metadata ); - meta->addEntry( KOLAB_FOLDER_TYPE_ANNOTATION ); - } else { + //TODO support shared/private + meta->addEntry( "/shared" KOLAB_FOLDER_TYPE_ANNOTATION ); + } else if ( m_serverCapabilities.contains( "ANNOTATEMORE" ) ) { meta->setServerCapability( KIMAP::MetaDataJobBase::Annotatemore ); meta->addEntry( KOLAB_FOLDER_TYPE_ANNOTATION, "value.shared" ); + } else { + Warning() << "Server does not support annotations"; + emitResult(); + return; } connect( meta, SIGNAL(result(KJob*)), SLOT(onGetMetaDataDone(KJob*)) ); m_metadataRetrieveJobs++; @@ -120,18 +125,16 @@ QMap<QByteArray, QMap<QByteArray, QByteArray> > rawAnnotations = meta->allMetaData( meta->mailBox() ); QByteArray attribute = ""; + QByteArray annotation = KOLAB_FOLDER_TYPE_ANNOTATION; if ( meta->serverCapability()==KIMAP::MetaDataJobBase::Annotatemore ) { attribute = "value.shared"; } - -// QMap<QByteArray, QByteArray> annotations; -// foreach ( const QByteArray &entry, rawAnnotations.keys() ) { -// annotations[entry] = rawAnnotations[entry][attribute]; -// Debug() << entry << annotations[entry]; -// } + if ( meta->serverCapability()==KIMAP::MetaDataJobBase::Metadata ) { + annotation = "/shared" KOLAB_FOLDER_TYPE_ANNOTATION; + } //TODO default flag? - const QByteArray &kolabType = rawAnnotations[KOLAB_FOLDER_TYPE_ANNOTATION][attribute]; + const QByteArray &kolabType = rawAnnotations[annotation][attribute]; // Debug() << meta->mailBox() << kolabType; if (!kolabType.isEmpty()) { if (kolabType.contains(KOLAB_FOLDER_TYPE_CONTACT)) { @@ -146,7 +149,7 @@ m_kolabFolders.insertMulti(KOLAB_FOLDER_TYPE_NOTE, meta->mailBox()); } else if (kolabType.contains(KOLAB_FOLDER_TYPE_FREEBUSY)) { m_kolabFolders.insertMulti(KOLAB_FOLDER_TYPE_FREEBUSY, meta->mailBox()); - } else if (kolabType.contains("mail") || kolabType.contains("configuration")) { + } else if (kolabType.contains("mail") || kolabType.contains("configuration") || kolabType.contains("file") || kolabType == "NIL") { //ignore silently } else { Warning() << "invalid/unhandled folder-type " << kolabType;
View file
kolab-utils-3.1.tar.gz/lib/jobs/probeimapserverjob.cpp
Added
@@ -0,0 +1,93 @@ + +/* + * Copyright (C) 2012 Christian Mollekopf <mollekopf@kolabsys.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "probeimapserverjob.h" +#include <kimap/capabilitiesjob.h> +#include <kimap/namespacejob.h> +#include <errorhandler.h> + +ProbeIMAPServerJob::ProbeIMAPServerJob(KIMAP::Session *session, QObject* parent) +: KJob(parent), + mSession(session) +{ + +} + +ProbeIMAPServerJob::~ProbeIMAPServerJob() +{ + +} + +void ProbeIMAPServerJob::start() +{ + KIMAP::CapabilitiesJob *capabilities = new KIMAP::CapabilitiesJob(mSession); + connect(capabilities, SIGNAL(result(KJob*)), this, SLOT(onCapabilitiesTestDone(KJob*))); + capabilities->start(); +} + +void ProbeIMAPServerJob::onCapabilitiesTestDone(KJob* job) +{ + if ( job->error() ) { + Warning() << job->errorString(); + setError(KJob::UserDefinedError); + emitResult(); + return; + } + KIMAP::CapabilitiesJob *capabilitiesJob = qobject_cast<KIMAP::CapabilitiesJob*>( job ); + Q_ASSERT(capabilitiesJob); + mCapabilities = capabilitiesJob->capabilities(); + if ( mCapabilities.contains( "NAMESPACE" ) ) { + KIMAP::NamespaceJob *nsJob = new KIMAP::NamespaceJob( mSession ); + QObject::connect( nsJob, SIGNAL(result(KJob*)), SLOT(onNamespacesTestDone(KJob*)) ); + nsJob->start(); + return; + } else { + emitResult(); + } +} + +void ProbeIMAPServerJob::onNamespacesTestDone( KJob *job ) +{ + if ( job->error() ) { + Warning() << job->errorString(); + setError(KJob::UserDefinedError); + emitResult(); + return; + } + KIMAP::NamespaceJob *nsJob = qobject_cast<KIMAP::NamespaceJob*>( job ); + Q_ASSERT(nsJob); + mPersonalNamespace = nsJob->personalNamespaces(); + mExcludedNamespace = nsJob->userNamespaces()+nsJob->sharedNamespaces(); + + emitResult(); +} + +QStringList ProbeIMAPServerJob::capabilities() const +{ + return mCapabilities; +} + +QList< KIMAP::MailBoxDescriptor > ProbeIMAPServerJob::personalNamespace() const +{ + return mPersonalNamespace; +} + +QList< KIMAP::MailBoxDescriptor > ProbeIMAPServerJob::excludedNamespaces() const +{ + return mExcludedNamespace; +}
View file
kolab-utils-3.1.tar.gz/lib/jobs/probeimapserverjob.h
Added
@@ -0,0 +1,53 @@ + +/* + * Copyright (C) 2013 Christian Mollekopf <mollekopf@kolabsys.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef PROBEIMAPSERVERJOB_H +#define PROBEIMAPSERVERJOB_H +#include <kcompositejob.h> +#include <QStringList> +#include <QHash> +#include <kimap/session.h> +#include <kimap/listjob.h> + +/** + * Probeserver for supported IMAP features + */ +class ProbeIMAPServerJob: public KJob +{ + Q_OBJECT +public: + explicit ProbeIMAPServerJob(KIMAP::Session *, QObject* parent = 0); + virtual ~ProbeIMAPServerJob(); + virtual void start(); + + QList<KIMAP::MailBoxDescriptor> personalNamespace() const; + QList<KIMAP::MailBoxDescriptor> excludedNamespaces() const; + QStringList capabilities() const; + +protected Q_SLOTS: + void onCapabilitiesTestDone(KJob *); + void onNamespacesTestDone(KJob *); + +private: + KIMAP::Session *mSession; + QStringList mCapabilities; + QList<KIMAP::MailBoxDescriptor> mPersonalNamespace; + QList<KIMAP::MailBoxDescriptor> mExcludedNamespace; +}; + +#endif
View file
kolab-utils-3.0.5.tar.gz/lib/jobs/probekolabserverjob.cpp -> kolab-utils-3.1.tar.gz/lib/jobs/probekolabserverjob.cpp
Changed
@@ -18,8 +18,7 @@ #include "probekolabserverjob.h" #include "findkolabfoldersjob.h" #include "setupkolabfoldersjob.h" -#include <kimap/capabilitiesjob.h> -#include <kimap/namespacejob.h> +#include "probeimapserverjob.h" #include <errorhandler.h> ProbeKolabServerJob::ProbeKolabServerJob(KIMAP::Session *session, QObject* parent) @@ -36,53 +35,23 @@ void ProbeKolabServerJob::start() { - KIMAP::CapabilitiesJob *capabilities = new KIMAP::CapabilitiesJob(mSession); - connect(capabilities, SIGNAL(result(KJob*)), this, SLOT(onCapabilitiesTestDone(KJob*))); - capabilities->start(); + ProbeIMAPServerJob *probeJob = new ProbeIMAPServerJob(mSession, this); + connect(probeJob, SIGNAL(result(KJob*)), this, SLOT(onProbeJobDone(KJob*))); + probeJob->start(); } -void ProbeKolabServerJob::createDefaultsIfMissing(const QStringList &folders) +void ProbeKolabServerJob::onProbeJobDone(KJob* job) { - mFoldersToCreate = folders; -} - -void ProbeKolabServerJob::onCapabilitiesTestDone(KJob* job) -{ - if ( job->error() ) { - Warning() << job->errorString(); - setError(KJob::UserDefinedError); - emitResult(); - return; - } - KIMAP::CapabilitiesJob *capabilitiesJob = qobject_cast<KIMAP::CapabilitiesJob*>( job ); - Q_ASSERT(capabilitiesJob); - mCapabilities = capabilitiesJob->capabilities(); - if ( mCapabilities.contains( "NAMESPACE" ) ) { - KIMAP::NamespaceJob *nsJob = new KIMAP::NamespaceJob( mSession ); - QObject::connect( nsJob, SIGNAL(result(KJob*)), SLOT(onNamespacesTestDone(KJob*)) ); - nsJob->start(); - return; - } else { - FindKolabFoldersJob *findJob = new FindKolabFoldersJob(mCapabilities, mPersonalNamespace, mExcludedNamespace, mSession, this); - connect(findJob, SIGNAL(result(KJob*)), this, SLOT(findKolabFoldersDone(KJob*))); - findJob->start(); - } -} - - -void ProbeKolabServerJob::onNamespacesTestDone( KJob *job ) -{ - if ( job->error() ) { + if (job->error()) { Warning() << job->errorString(); setError(KJob::UserDefinedError); emitResult(); return; } - KIMAP::NamespaceJob *nsJob = qobject_cast<KIMAP::NamespaceJob*>( job ); - Q_ASSERT(nsJob); - mPersonalNamespace = nsJob->personalNamespaces(); - mExcludedNamespace = nsJob->userNamespaces()+nsJob->sharedNamespaces(); - + ProbeIMAPServerJob *probeJob = static_cast<ProbeIMAPServerJob*>(job); + mCapabilities = probeJob->capabilities(); + mPersonalNamespace = probeJob->personalNamespace(); + mExcludedNamespace = probeJob->excludedNamespaces(); FindKolabFoldersJob *findJob = new FindKolabFoldersJob(mCapabilities, mPersonalNamespace, mExcludedNamespace, mSession, this); connect(findJob, SIGNAL(result(KJob*)), this, SLOT(findKolabFoldersDone(KJob*))); findJob->start(); @@ -99,40 +68,9 @@ FindKolabFoldersJob *findJob = static_cast<FindKolabFoldersJob*>(job); // qDebug() << "Found kolab folders: " << findJob->getKolabFolders(); mKolabFolders = findJob->getKolabFolders(); - - //TODO Setting up the missing folders shouldn't be part of the ProbeJob, and it's probably only used in one place in here => separate - QString rootFolder; - QStringList toCreate; - foreach (const QString &folderType, mFoldersToCreate) { - if (!mKolabFolders.contains(folderType)) { - toCreate << folderType; - } - } - if (toCreate.isEmpty()) { - emitResult(); - return; - } - SetupKolabFoldersJob *setupJob = new SetupKolabFoldersJob(mCapabilities, rootFolder, mSession, this); - setupJob->setKolabFolders(toCreate); - connect(setupJob, SIGNAL(result(KJob*)), this, SLOT(onSetupDone(KJob*))); - setupJob->start(); -} - -void ProbeKolabServerJob::onSetupDone(KJob *job) -{ - if (job->error()) { - Warning() << job->errorString(); - setError(KJob::UserDefinedError); - } - SetupKolabFoldersJob *setupJob = static_cast<SetupKolabFoldersJob*>(job); - const QMap<QString, QString> createdFolders = setupJob->createdFolders(); - foreach (const QString &folderType, createdFolders.keys()) { - mKolabFolders.insert(folderType, createdFolders.value(folderType)); - } emitResult(); } - QMultiHash<QString, QString> ProbeKolabServerJob::kolabFolders() const { return mKolabFolders;
View file
kolab-utils-3.0.5.tar.gz/lib/jobs/probekolabserverjob.h -> kolab-utils-3.1.tar.gz/lib/jobs/probekolabserverjob.h
Changed
@@ -17,7 +17,6 @@ #ifndef PROBEKOLABSERVERJOB_H #define PROBEKOLABSERVERJOB_H -#include <kcompositejob.h> #include <QStringList> #include <QHash> #include <kimap/session.h> @@ -34,26 +33,21 @@ virtual ~ProbeKolabServerJob(); virtual void start(); - void createDefaultsIfMissing(const QStringList &); - QList<KIMAP::MailBoxDescriptor> personalNamespace() const; QList<KIMAP::MailBoxDescriptor> excludedNamespaces() const; QStringList capabilities() const; QMultiHash<QString, QString> kolabFolders() const; protected Q_SLOTS: - void onCapabilitiesTestDone( KJob *job ); - void onNamespacesTestDone( KJob *job ); + void onProbeJobDone(KJob *job); void findKolabFoldersDone(KJob*); + private: KIMAP::Session *mSession; QStringList mCapabilities; QList<KIMAP::MailBoxDescriptor> mPersonalNamespace; QList<KIMAP::MailBoxDescriptor> mExcludedNamespace; QMultiHash<QString, QString> mKolabFolders; - QStringList mFoldersToCreate; -public slots: - void onSetupDone(KJob*); }; #endif // PROBEKOLABSERVERJOB_H
View file
kolab-utils-3.0.5.tar.gz/lib/jobs/setupkolabfoldersjob.cpp -> kolab-utils-3.1.tar.gz/lib/jobs/setupkolabfoldersjob.cpp
Changed
@@ -16,16 +16,16 @@ */ #include "setupkolabfoldersjob.h" + #include <kimap/session.h> -#include <kimap/createjob.h> #include <kimap/selectjob.h> -#include <kimap/setmetadatajob.h> -#include <QStringList> #include <errorhandler.h> #include <kolabdefinitions.h> #include <formathelpers.h> +#include "createkolabfolderjob.h" + SetupKolabFoldersJob::SetupKolabFoldersJob(const QStringList &serverCapabilities, QString rootFolder, KIMAP::Session* session, QObject* parent) : KJob(parent), m_session(session), @@ -53,7 +53,7 @@ connect(selectJob, SIGNAL(result(KJob*)), this, SLOT(onSelectDone(KJob*))); selectJob->start(); } else { - createMailbox(); + createNext(); } } @@ -65,7 +65,7 @@ emitResult(); return; } - createMailbox(); + createNext(); } static QString getFolderName(Kolab::FolderType type) @@ -75,76 +75,56 @@ static Kolab::FolderType getFolderType(const QString &typeString) { - Kolab::FolderType folderType = Kolab::folderTypeFromString(typeString.toStdString()); - //FIXME: this is only required for libkolab < 0.4.0. Afterwards folderTypeFromString should do the job - if (!typeString.compare(QLatin1String("freebusy"), Qt::CaseInsensitive)) { - folderType = Kolab::FreebusyType; - } - return folderType; + return Kolab::folderTypeFromString(typeString.toStdString()); } -void SetupKolabFoldersJob::createMailbox() +void SetupKolabFoldersJob::createNext() { if (m_folderTypes.isEmpty()) { emitResult(); return; } - m_currentFolderType = m_folderTypes.takeFirst(); - Kolab::FolderType folderType = getFolderType(m_currentFolderType); + createMailbox(m_folderTypes.takeFirst()); +} + +void SetupKolabFoldersJob::createMailbox(const QString ¤tFolderType) +{ + const Kolab::FolderType folderType = getFolderType(currentFolderType); if (folderType == Kolab::MailType) { - Warning() << "unknown kolab type: " << m_currentFolderType; + Warning() << "unknown kolab type: " << currentFolderType; setError(KJob::UserDefinedError); emitResult(); return; } - KIMAP::CreateJob *createJob = new KIMAP::CreateJob(m_session); - createJob->setMailBox(getFolderName(folderType)); + const QString name = getFolderName(folderType); + const QByteArray privateAnnotation = QString::fromStdString(Kolab::folderAnnotation(folderType, true)).toLatin1(); + const QByteArray sharedAnnotation = QString::fromStdString(Kolab::folderAnnotation(folderType, false)).toLatin1(); + + m_createdFolders.insert(currentFolderType, name); + + CreateKolabFolderJob *createJob = new CreateKolabFolderJob(name, + sharedAnnotation, + privateAnnotation, + CreateKolabFolderJob::capablitiesFromString(m_serverCapabilities), + m_session, + this + ); connect(createJob, SIGNAL(result(KJob*)), this, SLOT(onCreateDone(KJob*))); createJob->start(); } void SetupKolabFoldersJob::onCreateDone(KJob *job) { - QString mailbox; if (job->error()) { - Warning() << job->errorString() << "Trying to fix the metadata"; - mailbox = getFolderName(getFolderType(m_currentFolderType)); + Warning() << job->errorString() << "Failed to create folder"; } else { - KIMAP::CreateJob *createJob = static_cast<KIMAP::CreateJob*>(job); - mailbox = createJob->mailBox(); - Debug() << "Created folder " << m_rootFolder << createJob->mailBox(); + CreateKolabFolderJob *createJob = static_cast<CreateKolabFolderJob*>(job); + Debug() << "Created folder " << m_rootFolder << createJob->folder(); } - m_createdFolders.insert(m_currentFolderType, mailbox); - - KIMAP::SetMetaDataJob *setMetadataJob = new KIMAP::SetMetaDataJob(m_session); - setMetadataJob->setMailBox(mailbox); - Kolab::FolderType folderType = Kolab::folderTypeFromString(m_currentFolderType.toStdString()); - if ( m_serverCapabilities.contains( "METADATA" ) ) { - setMetadataJob->setServerCapability( KIMAP::MetaDataJobBase::Metadata ); - setMetadataJob->addMetaData("/shared" KOLAB_FOLDER_TYPE_ANNOTATION, QString::fromStdString(Kolab::folderAnnotation(folderType, false)).toLatin1() ); - } else { - setMetadataJob->setServerCapability( KIMAP::MetaDataJobBase::Annotatemore ); - setMetadataJob->setEntry( KOLAB_FOLDER_TYPE_ANNOTATION ); - setMetadataJob->addMetaData( "value.shared", QString::fromStdString(Kolab::folderAnnotation(folderType, false)).toLatin1() ); - } - //TODO also set the private annotation with the .default suffix - connect(setMetadataJob, SIGNAL(result(KJob*)), this, SLOT(onMetadataSetDone(KJob*))); - setMetadataJob->start(); -} - -void SetupKolabFoldersJob::onMetadataSetDone(KJob *job) -{ - if ( job->error() ) { - Warning() << job->errorString(); - setErrorText("Failed to create the folder for type: " + m_currentFolderType); - setError(KJob::UserDefinedError); - } - createMailbox(); + createNext(); } QMap< QString, QString > SetupKolabFoldersJob::createdFolders() const { return m_createdFolders; } - -
View file
kolab-utils-3.0.5.tar.gz/lib/jobs/setupkolabfoldersjob.h -> kolab-utils-3.1.tar.gz/lib/jobs/setupkolabfoldersjob.h
Changed
@@ -42,12 +42,12 @@ private slots: void onSelectDone(KJob*); void onCreateDone(KJob*); - void onMetadataSetDone(KJob*); + private: - void createMailbox(); + void createNext(); + void createMailbox(const QString &folderType); KIMAP::Session *m_session; QStringList m_folderTypes; - QString m_currentFolderType; QString m_rootFolder; QStringList m_serverCapabilities; QMap<QString, QString> m_createdFolders;
View file
kolab-utils-3.0.5.tar.gz/lib/kolabaccount.cpp -> kolab-utils-3.1.tar.gz/lib/kolabaccount.cpp
Changed
@@ -16,9 +16,10 @@ */ #include "kolabaccount.h" -#include "uiproxy.h" -#include <jobs/setupkolabfoldersjob.h> +#include "sessionfactory.h" +#include "jobs/setupkolabfoldersjob.h" #include "jobs/fetchmessagesjob.h" +#include "jobs/createkolabfolderjob.h" #include <kimap/session.h> #include <kimap/logoutjob.h> #include <kimap/appendjob.h> @@ -43,11 +44,20 @@ mEncryptionMode(KIMAP::LoginJob::TlsV1), mAuthenticationMode(KIMAP::LoginJob::Plain), mDryRun(false), + mWipeTargetFolders(false), mVersion(Kolab::KolabV3) { } +KolabAccount::~KolabAccount() +{ + if (mSession) { + mSession->close(); + mSession->deleteLater(); + } +} + void KolabAccount::setVersion(Kolab::Version version) { mVersion = version; @@ -66,6 +76,11 @@ mAuthorizationName = authorizationName; } +QString KolabAccount::getUsername() const +{ + return mUsername; +} + void KolabAccount::setEncryptionMode(KIMAP::LoginJob::EncryptionMode encryptionMode) { mEncryptionMode = encryptionMode; @@ -81,13 +96,20 @@ mDryRun = enable; } +void KolabAccount::setWipeTargetFolders(bool enable) +{ + mWipeTargetFolders = enable; +} + bool KolabAccount::init() { + if (mDryRun) { + return true; + } if (mSession) { return false; } - mSession = new KIMAP::Session( mHost, mPort, this ); - mSession->setUiProxy( KIMAP::SessionUiProxy::Ptr(new UiProxy()) ); + mSession = createSession( mHost, mPort, this ); KIMAP::LoginJob *loginJob = new KIMAP::LoginJob( mSession ); Debug() << mUsername << mAuthorizationName << mPw; if (mAuthorizationName != mUsername) { @@ -157,26 +179,40 @@ return msg; } -void KolabAccount::appendObject(Object obj, const QString& folder) +KJob* KolabAccount::appendObject(Object obj, const QString& folder) { if (mDryRun) { Debug() << "append object in folder: " << folder; - return; + return 0; + } + if (!mFolders.contains(folder, Qt::CaseInsensitive)) { + Error() << "failed to find target folder: " << folder; + qDebug() << mFolders; + return 0; } - Q_ASSERT(mFolders.contains(folder)); KMime::Message::Ptr message = writeObject(obj); - if (!message) { Error() << "got empty message"; - return; + return 0; } + + Q_ASSERT(mSession); KIMAP::AppendJob *job = new KIMAP::AppendJob( mSession ); job->setMailBox( folder ); job->setContent( message->encodedContent( true ) ); //The Recent flag is a special case which is not allowed in the append command obj.flags.removeAll(QByteArray(FlagRecent2)); job->setFlags( obj.flags ); + return job; +} + +void KolabAccount::appendObjectSync(Object obj, const QString& folder) +{ + KJob *job = appendObject(obj, folder); + if (!job) { + return; + } job->exec(); Debug() << "appended object in folder: " << folder; if (job->error()) { @@ -184,21 +220,26 @@ } } -void KolabAccount::logout() +KJob *KolabAccount::logout() { - Q_ASSERT(mSession); - KIMAP::LogoutJob *logoutJob = new KIMAP::LogoutJob(mSession); - logoutJob->exec(); - mSession->close(); -// mSession->deleteLater(); - mSession = 0; - Debug() << "logout done"; + if (!mSession) { + return 0; + } + return new KIMAP::LogoutJob(mSession); } const char* FlagDeleted2 = "\\Deleted"; void KolabAccount::cleanAccount() { + if (!mWipeTargetFolders) { + Debug() << "wiping of target folders disabled"; + return; + } + if (mDryRun) { + Debug() << "wiping account"; + return; + } Q_ASSERT(mSession); KIMAP::ListJob *listJob = new KIMAP::ListJob(mSession); listJob->setOption(KIMAP::ListJob::IncludeUnsubscribed); @@ -228,8 +269,8 @@ Error() << selectJob->errorString(); } const int messageCount = selectJob->messageCount(); + Debug() << "removing folder: " << desc.name << messageCount; if (mDryRun) { - Debug() << "removing folder: " << desc.name << messageCount; continue; } @@ -265,7 +306,13 @@ mFolders.append(QLatin1String("inbox")); //logging out and logging in again seems to help with the "NO Mailbox is locked" problem when creating folders afterwards. - logout(); + KJob *logoutJob = logout(); + if (logoutJob) { + logoutJob->exec(); + } + mSession->close(); + mSession->deleteLater(); + mSession = 0; init(); } @@ -281,38 +328,20 @@ void KolabAccount::createFolder(const QString &name, const QByteArray &annotation) { if (mFolders.contains(name, Qt::CaseInsensitive)) { - Warning() << "folder is already existing: " << name; + Warning() << "folder already exists: " << name; return; } if (mDryRun) { Debug() << "creating folder: " << name << annotation; return; } - - KIMAP::CreateJob *createJob = new KIMAP::CreateJob(mSession); - createJob->setMailBox(name); + CreateKolabFolderJob *createJob = new CreateKolabFolderJob(name, annotation, QByteArray(), CreateKolabFolderJob::capablitiesFromString(mCapabilities), mSession, this); createJob->exec(); - Debug() << "created folder " << name; if (createJob->error()) { Error() << createJob->errorString(); return; } - - KIMAP::SetMetaDataJob *setMetadataJob = new KIMAP::SetMetaDataJob(mSession); - setMetadataJob->setMailBox(createJob->mailBox());
View file
kolab-utils-3.0.5.tar.gz/lib/kolabaccount.h -> kolab-utils-3.1.tar.gz/lib/kolabaccount.h
Changed
@@ -34,6 +34,7 @@ Q_OBJECT public: explicit KolabAccount(QObject* parent = 0); + virtual ~KolabAccount(); void setHost(const QString &host, qint16 port); void setCredentials(const QString &username, const QString &pw, const QString &authorizationName); @@ -43,18 +44,31 @@ void cleanAccount(); void setupFolders(); - void appendObject(Object obj, const QString &folder); + void appendObjectSync(Object obj, const QString &folder); + KJob *appendObject(Object obj, const QString &folder); void createFolder(const QString &name, Kolab::FolderType folderType); void createFolder(const QString &name, const QByteArray &annotation); void setDryRun(bool); + void setWipeTargetFolders(bool); + void setRegextrans(const QStringList &); - void logout(); + KJob *logout(); QList<Object> getObjects(const QString& folder); QStringList lookupFolderList(); void setVersion(Kolab::Version); + QString getUsername() const; + + /** + * Applies any target folder name transformations. + * This includes: + * * user-specified regextrans2 transformations + * * normalizations to get a valid name according to the IMAP specification + */ + QString applyTargetFolderTransformations(const QString &) const; + private slots: void mailBoxesReceived(const QList<KIMAP::MailBoxDescriptor> &descriptors, const QList< QList< QByteArray > > &flags); private: @@ -73,7 +87,9 @@ QStringList mFolders; QStringList mCapabilities; bool mDryRun; + bool mWipeTargetFolders; Kolab::Version mVersion; + QMap<QString, QString> mRegextrans; }; #endif // KOLABACCOUNT_H
View file
kolab-utils-3.0.5.tar.gz/lib/object.h -> kolab-utils-3.1.tar.gz/lib/object.h
Changed
@@ -20,6 +20,7 @@ #include <kmime/kmime_message.h> #include <kcalcore/incidence.h> +#include <QVariant> Q_DECLARE_METATYPE( KCalCore::Incidence::Ptr ) Q_DECLARE_METATYPE( KMime::Message::Ptr ) @@ -40,8 +41,10 @@ struct Object { + qint64 imapUid; QVariant object; QList<QByteArray> flags; }; +Q_DECLARE_METATYPE( Object ) #endif // OBJECT_H
View file
kolab-utils-3.1.tar.gz/lib/sessionfactory.h
Added
@@ -0,0 +1,32 @@ +/* + * Copyright (C) 2012 Christian Mollekopf <mollekopf@kolabsys.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef SESSIONFACTORY_H +#define SESSIONFACTORY_H +#include <QString> +#include <kimap/session.h> +#include "uiproxy.h" + +static KIMAP::Session *createSession(const QString &host, qint16 port, QObject *parent) +{ + KIMAP::Session *session = new KIMAP::Session(host, port, parent); + session->setUiProxy(KIMAP::SessionUiProxy::Ptr(new UiProxy())); + session->setTimeout(300); + return session; +} + +#endif // OBJECT_H
View file
kolab-utils-3.0.5.tar.gz/lib/sessionsettings.h -> kolab-utils-3.1.tar.gz/lib/sessionsettings.h
Changed
@@ -1,4 +1,3 @@ - /* * Copyright (C) 2012 Christian Mollekopf <mollekopf@kolabsys.com> *
View file
kolab-utils-3.0.5.tar.gz/lib/testlib/testutils.h -> kolab-utils-3.1.tar.gz/lib/testlib/testutils.h
Changed
@@ -1,21 +1,58 @@ +#ifndef TESTUTILS_H +#define TESTUTILS_H + #include <QList> #include "kolabaccount.h" - struct Folder { + Folder(){} Folder(const QString &n, Kolab::FolderType type = Kolab::MailType, const QList<Object> &obj = QList<Object>()): objects(obj), name(n), folderType(type){}; + bool operator==(const Folder &other) { + if (other.name == name) { + return true; + } + return false; + } QList<Object> objects; QString name; Kolab::FolderType folderType; }; +void fillDefaultFolders(QList<Folder> &folders) +{ + QList<Folder> defaultFolders; + defaultFolders << Folder("INBOX"); + defaultFolders << Folder("Calendar", Kolab::EventType); + defaultFolders << Folder("Calendar/Personal Calendar", Kolab::EventType); + defaultFolders << Folder("Configuration", Kolab::ConfigurationType); + defaultFolders << Folder("Contacts", Kolab::ContactType); + defaultFolders << Folder("Drafts"); + defaultFolders << Folder("Freebusy"); + defaultFolders << Folder("Journal", Kolab::JournalType); + defaultFolders << Folder("Notes", Kolab::NoteType); + defaultFolders << Folder("Sent"); + defaultFolders << Folder("Tasks", Kolab::TaskType); + defaultFolders << Folder("Trash"); + foreach (const Folder &folder, defaultFolders) { + if (!folders.contains(folder)) { + folders.insert(defaultFolders.indexOf(folder), folder); + } + } + +} + void createFolders(KolabAccount *account, const QList<Folder> &folders) { - foreach (const Folder &folder, folders) { + foreach (Folder folder, folders) { + if (folders.contains(folder)) { + folder = folders.value(folders.indexOf(folder)); + } account->createFolder(folder.name, folder.folderType); foreach(const Object &obj, folder.objects) { - account->appendObject(obj, folder.name); + account->appendObjectSync(obj, folder.name); } } -} \ No newline at end of file +} + +#endif
View file
kolab-utils-3.0.5.tar.gz/migrationutility/CMakeLists.txt -> kolab-utils-3.1.tar.gz/migrationutility/CMakeLists.txt
Changed
@@ -1,13 +1,6 @@ -# set(MIGRATION_SRCS -# ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp -# ${CMAKE_CURRENT_SOURCE_DIR}/migrateuserjob.cpp -# ${CMAKE_CURRENT_SOURCE_DIR}/coordinationjob.cpp -# ${CMAKE_CURRENT_SOURCE_DIR}/sourceaccount.cpp -# ${CMAKE_CURRENT_SOURCE_DIR}/sourceserver.cpp -# PARENT_SCOPE -# ) - -include_directories(${CMAKE_CURRENT_BINARY_DIR}) +include_directories( + ${CMAKE_CURRENT_BINARY_DIR} +) set(MIGRATION_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/migrateuserjob.cpp @@ -16,9 +9,12 @@ ${CMAKE_CURRENT_SOURCE_DIR}/sourceaccount.cpp ${CMAKE_CURRENT_SOURCE_DIR}/sourceserver.cpp ${CMAKE_CURRENT_SOURCE_DIR}/kolabserver.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/statefile.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/imapsourceaccount.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/kolabsourceaccount.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/exchangesourceaccount.cpp ) - QT4_WRAP_CPP(MIGRATION_MOC ${CMAKE_CURRENT_SOURCE_DIR}/migrateuserjob.h ${CMAKE_CURRENT_SOURCE_DIR}/migratefolderjob.h @@ -26,11 +22,53 @@ ${CMAKE_CURRENT_SOURCE_DIR}/sourceaccount.h ${CMAKE_CURRENT_SOURCE_DIR}/sourceserver.h ${CMAKE_CURRENT_SOURCE_DIR}/kolabserver.h + ${CMAKE_CURRENT_SOURCE_DIR}/statefile.h + ${CMAKE_CURRENT_SOURCE_DIR}/imapsourceaccount.h + ${CMAKE_CURRENT_SOURCE_DIR}/kolabsourceaccount.h + ${CMAKE_CURRENT_SOURCE_DIR}/exchangesourceaccount.h +) + +set(MIGRATION_SRCS + ${MIGRATION_SRCS} + ${MIGRATION_MOC} + ${JOBS_SRCS} ) +set(MIGRATION_LIBRARIES + kolabutils + ${COMMON_DEPENDENCIES} +) + +if(BUILD_GOOGLESUPPORT) + find_package(LibKGAPI2 2.0 REQUIRED) + include_directories( + ${LibKGAPI2_INCLUDE_DIR} + ) + + QT4_WRAP_CPP(GOOGLE_MOC + ${CMAKE_CURRENT_SOURCE_DIR}/googlesourceserver.h + ${CMAKE_CURRENT_SOURCE_DIR}/googlesourceaccount.h + ) + + set(MIGRATION_SRCS + ${MIGRATION_SRCS} + ${GOOGLE_MOC} + ${CMAKE_CURRENT_SOURCE_DIR}/googlesourceserver.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/googlesourceaccount.cpp + ) + + set(MIGRATION_LIBRARIES + ${MIGRATION_LIBRARIES} + ${LibKGAPI2_LIBRARY} + ) + add_definitions("-DBUILD_GOOGLESUPPORT") +endif() + +add_library(migration_static STATIC ${MIGRATION_SRCS}) +target_link_libraries(migration_static ${COMMON_DEPENDENCIES} ${MIGRATION_LIBRARIES}) -add_executable(kolab-migration ${MIGRATION_SRCS} ${MIGRATION_MOC} ${JOBS_SRCS} main.cpp) -target_link_libraries(kolab-migration ${COMMON_DEPENDENCIES} kolabutils) +add_executable(kolab-migration ${MIGRATION_SRCS} main.cpp) +target_link_libraries(kolab-migration ${MIGRATION_LIBRARIES}) install(TARGETS kolab-migration RUNTIME DESTINATION ${BIN_INSTALL_DIR} @@ -38,4 +76,4 @@ ARCHIVE DESTINATION ${LIB_INSTALL_DIR} ) -# add_subdirectory(tests) +add_subdirectory(tests)
View file
kolab-utils-3.0.5.tar.gz/migrationutility/coordinationjob.cpp -> kolab-utils-3.1.tar.gz/migrationutility/coordinationjob.cpp
Changed
@@ -32,27 +32,49 @@ void CoordinationJob::start() { - const QStringList &userList = mSourceServer->getUserList(); - if (userList.isEmpty()) { + UserListJob *listJob = mSourceServer->listUsers(); + Q_ASSERT(listJob); + connect(listJob, SIGNAL(result(KJob*)), this, SLOT(onUserListJobDone(KJob*))); + listJob->start(); +} + +void CoordinationJob::onUserListJobDone(KJob* job) +{ + if (job->error()) { + setError(UserDefinedError); + setErrorText("Failed to get user list: " + job->errorString()); + emitResult(); + return; + } + UserListJob *listJob = static_cast<UserListJob*>(job); + mUserList = listJob->getUserList(); + if (mUserList.isEmpty()) { Debug() << "no users found"; } else { Debug() << "migrating the following users: "; - qDebug() << userList; + qDebug() << mUserList; } - foreach (const QString &user, userList) { - MigrateUserJob *job = new MigrateUserJob(mSourceServer->getSourceAccount(user), mKolabServer->getAccount(user), this); - Q_ASSERT(job); - job->exec(); - if (job->error()) { - Error() << job->errorString(); - continue; - } + processUser(); +} + +void CoordinationJob::processUser() +{ + if (mUserList.isEmpty()) { + Debug() << "done"; + emitResult(); + return; } + const QString user = mUserList.takeFirst(); + MigrateUserJob *job = new MigrateUserJob(mSourceServer->getSourceAccounts(user), mKolabServer->getAccount(user), this); + connect(job, SIGNAL(result(KJob*)), this, SLOT(userMigrated(KJob*))); + job->start(); +} - Debug() << "done"; - emitResult(); - emit done(); +void CoordinationJob::userMigrated(KJob *job) +{ + if (job->error()) { + Error() << job->errorString(); + } + processUser(); } -// #include "moc_coordinationjob.cxx" -// #include "coordinationjob.moc"
View file
kolab-utils-3.0.5.tar.gz/migrationutility/coordinationjob.h -> kolab-utils-3.1.tar.gz/migrationutility/coordinationjob.h
Changed
@@ -17,21 +17,27 @@ #ifndef COORDINATIONJOB_H #define COORDINATIONJOB_H + #include <kjob.h> +#include <QStringList> class KolabServer; class SourceServer; + class CoordinationJob: public KJob { Q_OBJECT public: explicit CoordinationJob(SourceServer *sourceServer, KolabServer *kolabServer, QObject* parent = 0); virtual void start(); -signals: - void done(); +private slots: + void onUserListJobDone(KJob *job); + void userMigrated(KJob *job); private: + void processUser(); SourceServer *mSourceServer; KolabServer *mKolabServer; + QStringList mUserList; }; #endif // COORDINATIONJOB_H
View file
kolab-utils-3.1.tar.gz/migrationutility/exchangesourceaccount.cpp
Added
@@ -0,0 +1,134 @@ +/* + * Copyright (C) 2013 Christian Mollekopf <mollekopf@kolabsys.com> + * + * 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 "exchangesourceaccount.h" + +#include <jobs/fetchmessagesjob.h> +#include <errorhandler.h> +#include <kabc/vcardconverter.h> +#include <kcalcore/memorycalendar.h> +#include <kcalcore/icalformat.h> + +ExchangeIMAPSourceAccount::ExchangeIMAPSourceAccount(QObject* parent) +: IMAPSourceAccount(parent) +{ + +} + +QPair<Kolab::ObjectType, KMime::Content*> ExchangeIMAPSourceAccount::getObjectType(const KMime::Message::Ptr &msg) const +{ + const QByteArray calendarType("text/calendar"); + const QByteArray vcardType("text/vcard"); + Q_FOREACH(KMime::Content *c, msg->contents()) { + Debug() << c->contentType()->mimeType(); + if (c->contentType()->mimeType() == calendarType) { + KCalCore::ICalFormat format; + KCalCore::MemoryCalendar::Ptr calendar(new KCalCore::MemoryCalendar(KDateTime::Spec::UTC())); + format.fromRawString(calendar, c->decodedContent()); + if (!calendar->events().isEmpty()) { + return QPair<Kolab::ObjectType, KMime::Content*>(Kolab::EventObject, c); + } else if (!calendar->todos().isEmpty()) { + return QPair<Kolab::ObjectType, KMime::Content*>(Kolab::TodoObject, c); + } else if (!calendar->journals().isEmpty()) { + return QPair<Kolab::ObjectType, KMime::Content*>(Kolab::JournalObject, c); + } + } + if (c->contentType()->mimeType() == vcardType) { + return QPair<Kolab::ObjectType, KMime::Content*>(Kolab::ContactObject, c); + } + } + return QPair<Kolab::ObjectType, KMime::Content*>(Kolab::InvalidObject, 0); +} + +Kolab::FolderType ExchangeIMAPSourceAccount::getFolderType(const QString &folder) +{ + FetchMessagesJob *fetchJob = new FetchMessagesJob(folder, getSession(), this); + //Theoretically one would be enough, but in case we have a couple of invalid ones... + fetchJob->setMaxNumberOfMessagesToFetch(10); + fetchJob->exec(); + Debug() << fetchJob->getMessages().size(); + QList<Object> messages; + foreach (const KMime::Message::Ptr &msg, fetchJob->getMessages()) { + Kolab::ObjectType type = getObjectType(msg).first; + if (type == Kolab::EventObject) { + return Kolab::EventType; + } + if (type == Kolab::TodoObject) { + return Kolab::TaskType; + } + if (type == Kolab::JournalObject) { + return Kolab::JournalType; + } + if (type == Kolab::ContactObject) { + return Kolab::ContactType; + } + } + return Kolab::MailType; +} + +QPair<Kolab::FolderType, QString> ExchangeIMAPSourceAccount::translateFolder(const QString& folder) +{ + return QPair<Kolab::FolderType, QString>(getFolderType(folder), folder); +} + +Object ExchangeIMAPSourceAccount::convertObject(const Object& object, const QString& /*folder*/) const +{ + KMime::Message::Ptr msg = object.object.value<KMime::Message::Ptr>(); + QPair<Kolab::ObjectType, KMime::Content*> type = getObjectType(msg); + Debug() << type.first; + if (type.first == Kolab::InvalidObject) { + Object obj; + obj.object = QVariant::fromValue(msg); + obj.flags = object.flags; + return obj; + } else if (type.first == Kolab::EventObject || type.first == Kolab::TodoObject || type.first == Kolab::JournalObject) { + const QByteArray content = type.second->decodedContent(); + Debug() << "Found incidence object: " << content; + KCalCore::ICalFormat format; + KCalCore::MemoryCalendar::Ptr calendar(new KCalCore::MemoryCalendar(KDateTime::Spec::UTC())); + format.fromRawString(calendar, content); + + //We're simply assuming here that we never have different incidence types mixed in a folder + foreach (const KCalCore::Incidence::Ptr &inc, calendar->incidences()) { + Object obj; + obj.object = QVariant::fromValue(inc); + obj.flags = object.flags; + if (!obj.object.isValid()) { + Error() << "got empty message"; + continue; + } + return obj; + } + } else if (type.first == Kolab::ContactObject) { + const QByteArray content = type.second->decodedContent(); + Debug() << "Found contact object: " << content; + KABC::VCardConverter format; + const KABC::Addressee addressee = format.parseVCard(content); + + Object obj; + obj.object = QVariant::fromValue(addressee); + obj.flags = object.flags; + if (!obj.object.isValid()) { + Error() << "got empty message"; + return object; + } + return obj; + } + return object; +} + +
View file
kolab-utils-3.1.tar.gz/migrationutility/exchangesourceaccount.h
Added
@@ -0,0 +1,36 @@ +/* + * Copyright (C) 2013 Christian Mollekopf <mollekopf@kolabsys.com> + * + * 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 EXCHANGESOURCEACCOUNT_H +#define EXCHANGESOURCEACCOUNT_H + +#include "imapsourceaccount.h" + +class ExchangeIMAPSourceAccount: public IMAPSourceAccount +{ + Q_OBJECT +public: + explicit ExchangeIMAPSourceAccount(QObject* parent = 0); + virtual QPair<Kolab::FolderType, QString> translateFolder(const QString& folder); + virtual Object convertObject(const Object& object, const QString& folder) const; + +private: + QPair<Kolab::ObjectType, KMime::Content*> getObjectType(const KMime::Message::Ptr &msg) const; + Kolab::FolderType getFolderType(const QString &folder); +}; + +#endif
View file
kolab-utils-3.1.tar.gz/migrationutility/googlesourceaccount.cpp
Added
@@ -0,0 +1,390 @@ +/* + * Copyright (C) 2013 Christian Mollekopf <mollekopf@kolabsys.com> + * + * 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 "googlesourceaccount.h" + +#include <libkgapi2/contacts/contact.h> +#include <libkgapi2/contacts/contactfetchjob.h> +#include <libkgapi2/calendar/calendar.h> +#include <libkgapi2/calendar/calendarfetchjob.h> +#include <libkgapi2/calendar/event.h> +#include <libkgapi2/calendar/eventfetchjob.h> +#include <libkgapi2/tasks/tasklistfetchjob.h> +#include <libkgapi2/tasks/task.h> +#include <libkgapi2/tasks/taskfetchjob.h> +#include <libkgapi2/tasks/tasklist.h> +#include <libkgapi2/authjob.h> +#include <libkgapi2/account.h> +#include <quuid.h> + +#include <errorhandler.h> + +GoogleFetchObjectsJob::GoogleFetchObjectsJob(const QString ¤tFolder, const KGAPI2::AccountPtr& account, QObject* parent) +: FetchObjectsJob(parent), + mAccount(account), + mCurrentFolder(currentFolder) +{ + +} + +void GoogleFetchObjectsJob::start() +{ + if (mAccount.isNull()) { + Error() << "Error: Please authenticate first"; + setError(KJob::UserDefinedError); + setErrorText("Error: Please authenticate first"); + emitResult(); + return; + } + + KGAPI2::FetchJob *fetchJob = getFetchJob(mAccount, mCurrentFolder); + connect(fetchJob, SIGNAL(finished(KGAPI2::Job*)), this, SLOT(slotFetchJobFinished(KGAPI2::Job*))); +} + + +void GoogleFetchObjectsJob::slotFetchJobFinished(KGAPI2::Job* job) +{ + KGAPI2::FetchJob *fetchJob = qobject_cast<KGAPI2::FetchJob*>(job); + Q_ASSERT(fetchJob); + fetchJob->deleteLater(); + + if (fetchJob->error() != KGAPI2::NoError) { + Error() << fetchJob->errorString(); + setError(KJob::UserDefinedError); + setErrorText(fetchJob->errorString()); + emitResult(); + return; + } + + QList<Object> objects; + foreach (const KGAPI2::ObjectPtr &i, fetchJob->items()) { + objects << getObject(i); + } + emit objectsReceived(mCurrentFolder, objects); + emitResult(); +} + +GoogleFetchFoldersJob::GoogleFetchFoldersJob(const KGAPI2::AccountPtr& account, QObject* parent) +: FetchFoldersJob(parent), + mAccount(account) +{ + +} + +void GoogleFetchFoldersJob::start() +{ + if (mAccount.isNull()) { + Error() << "Error: Please authenticate first"; + setError(KJob::UserDefinedError); + setErrorText("Error: Please authenticate first"); + emitResult(); + return; + } + + KGAPI2::FetchJob *fetchJob = getFetchJob(mAccount); + connect(fetchJob, SIGNAL(finished(KGAPI2::Job*)), this, SLOT(slotFetchJobFinished(KGAPI2::Job*))); +} + + +void GoogleFetchFoldersJob::slotFetchJobFinished(KGAPI2::Job* job) +{ + KGAPI2::FetchJob *fetchJob = qobject_cast<KGAPI2::FetchJob*>(job); + Q_ASSERT(fetchJob); + fetchJob->deleteLater(); + + if (fetchJob->error() != KGAPI2::NoError) { + Error() << fetchJob->errorString(); + setError(KJob::UserDefinedError); + setErrorText(fetchJob->errorString()); + emitResult(); + return; + } + + QStringList folders; + foreach (const KGAPI2::ObjectPtr &i, fetchJob->items()) { + const QPair<QString, QString> folder = getFolder(i); + folders << folder.first; + mNames.insert(folder.first, folder.second); + } + emit foldersReceived(folders); + emitResult(); +} + + + +FetchContactObjectsJob::FetchContactObjectsJob(const KGAPI2::AccountPtr &account, QObject* parent) +: GoogleFetchObjectsJob(QLatin1String("Contacts"), account, parent) +{ + +} + +KGAPI2::FetchJob* FetchContactObjectsJob::getFetchJob(const KGAPI2::AccountPtr& account, const QString& folder) +{ + Q_UNUSED(folder); + return new KGAPI2::ContactFetchJob(account, this); +} + +Object FetchContactObjectsJob::getObject(const KGAPI2::ObjectPtr& object) +{ + KABC::Addressee contact = *object.dynamicCast<KGAPI2::Contact>(); + //The returned uid's are of format: http://www.google.com/m8/feeds/contacts/NAME%40gmail.com/base/21042a1f892367ee + //We generate a new one that is RFC4122 compliant to avoid incompatibilities + contact.setUid( QUuid::createUuid().toString().mid(1, 36) ); +// Debug() << "contact: " << contact.name(); +// qDebug() << contact.emails(); + Object obj; + obj.object = QVariant::fromValue(contact); + return obj; +} + +FetchCalendarObjectsJob::FetchCalendarObjectsJob(const QString &calendarId, const KGAPI2::AccountPtr& account, QObject* parent) +: GoogleFetchObjectsJob(calendarId, account, parent) +{ +} + +KGAPI2::FetchJob* FetchCalendarObjectsJob::getFetchJob(const KGAPI2::AccountPtr &account, const QString& folder) +{ + return new KGAPI2::EventFetchJob(folder, account, this); +} + +Object FetchCalendarObjectsJob::getObject(const KGAPI2::ObjectPtr &object) +{ + KCalCore::Incidence::Ptr event(object.dynamicCast<KGAPI2::Event>()->clone()); +// Debug() << event->uid() << event->summary(); + Object obj; + obj.object = QVariant::fromValue(event); + return obj; +} + + + +FetchCalendarFoldersJob::FetchCalendarFoldersJob(const KGAPI2::AccountPtr& account, QObject* parent) +: GoogleFetchFoldersJob(account, parent) +{ +} + +KGAPI2::FetchJob* FetchCalendarFoldersJob::getFetchJob(const KGAPI2::AccountPtr& account) +{ + return new KGAPI2::CalendarFetchJob(account, this); +} + +QPair<QString, QString> FetchCalendarFoldersJob::getFolder(const KGAPI2::ObjectPtr& object) +{ + const KGAPI2::Calendar &calendar = *object.dynamicCast<KGAPI2::Calendar>(); + //TODO prefix with Calendar/ + QString name = calendar.title(); +// Debug() << "calendar: " << calendar.title(); + return qMakePair<QString, QString>(calendar.uid(), calendar.title()); +} + +FetchTaskObjectsJob::FetchTaskObjectsJob(const QString &tasklistId, const KGAPI2::AccountPtr& account, QObject* parent) +: GoogleFetchObjectsJob(tasklistId, account, parent) +{ +} + +KGAPI2::FetchJob* FetchTaskObjectsJob::getFetchJob(const KGAPI2::AccountPtr &account, const QString& folder)
View file
kolab-utils-3.1.tar.gz/migrationutility/googlesourceaccount.h
Added
@@ -0,0 +1,199 @@ +/* + * Copyright (C) 2013 Christian Mollekopf <mollekopf@kolabsys.com> + * + * 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 GOOGLESOURCEACCOUNT_H +#define GOOGLESOURCEACCOUNT_H + +#include <libkgapi2/types.h> +#include <QStringList> + +#include "sourceaccount.h" + +namespace KGAPI2 { +class Job; +class FetchJob; +} + +class GoogleSourceAccount: public SourceAccount +{ +public: + explicit GoogleSourceAccount(QObject* parent = 0); + + void setAccount(const KGAPI2::AccountPtr &account); + KGAPI2::AccountPtr account(); + + void setUser(const QString &username); + virtual QPair<Kolab::FolderType, QString> translateFolder(const QString& folder); + + virtual KJob *login(); + virtual KJob *logout(); + +protected: + KGAPI2::AccountPtr mAccount; + QString mUser; +private: + class DummyJob : public KJob { + virtual void start() {emitResult();} + }; +}; + +class GoogleContactsSourceAccount: public GoogleSourceAccount +{ +public: + explicit GoogleContactsSourceAccount(QObject* parent = 0); + + virtual QStringList lookupFolderList(); + virtual FetchObjectsJob *fetchObjects(const QString &folder); +}; + +class GoogleCalendarSourceAccount: public GoogleSourceAccount +{ + Q_OBJECT +public: + explicit GoogleCalendarSourceAccount(QObject* parent = 0); + + virtual FetchFoldersJob *fetchFolderList(); + virtual FetchObjectsJob *fetchObjects(const QString &folder); + virtual QPair<Kolab::FolderType, QString> translateFolder(const QString& folder); + +private slots: + void onFetchedCalendars(KJob *job); + +private: + QHash<QString, QString> mCalendarNames; +}; + +class GoogleTasksSourceAccount: public GoogleSourceAccount +{ + Q_OBJECT +public: + explicit GoogleTasksSourceAccount(QObject* parent = 0); + + virtual FetchFoldersJob *fetchFolderList(); + virtual FetchObjectsJob *fetchObjects(const QString &folder); + virtual QPair<Kolab::FolderType, QString> translateFolder(const QString& folder); + +private slots: + void onFetchedTasklists(KJob *job); + +private: + QHash<QString, QString> mTasklists; +}; + +class GoogleFetchObjectsJob : public FetchObjectsJob +{ + Q_OBJECT +public: + explicit GoogleFetchObjectsJob(const QString &folder, const KGAPI2::AccountPtr &account, QObject* parent = 0); + virtual void start(); + +protected: + virtual Object getObject(const KGAPI2::ObjectPtr &) = 0; + virtual KGAPI2::FetchJob *getFetchJob(const KGAPI2::AccountPtr &, const QString &folder) = 0; + +private slots: + void slotFetchJobFinished(KGAPI2::Job *job); + +private: + const KGAPI2::AccountPtr mAccount; + const QString mCurrentFolder; +}; + +class GoogleFetchFoldersJob : public FetchFoldersJob +{ + Q_OBJECT +public: + explicit GoogleFetchFoldersJob(const KGAPI2::AccountPtr &account, QObject* parent = 0); + virtual void start(); + QHash<QString, QString> mNames; + +protected: + virtual QPair<QString, QString> getFolder(const KGAPI2::ObjectPtr &object) = 0; + virtual KGAPI2::FetchJob *getFetchJob(const KGAPI2::AccountPtr &account) = 0; + +private slots: + void slotFetchJobFinished(KGAPI2::Job *job); + +private: + const KGAPI2::AccountPtr mAccount; +}; + +class FetchContactObjectsJob : public GoogleFetchObjectsJob +{ +public: + explicit FetchContactObjectsJob(const KGAPI2::AccountPtr &account, QObject* parent = 0); + +protected: + virtual KGAPI2::FetchJob* getFetchJob(const KGAPI2::AccountPtr &account, const QString& folder); + virtual Object getObject(const KGAPI2::ObjectPtr &object); +}; + +class LoginJob : public KJob +{ + Q_OBJECT +public: + explicit LoginJob(const KGAPI2::AccountPtr &account, QObject* parent = 0); + virtual void start(); + +private slots: + void slotAuthJobFinished(KGAPI2::Job *job); + +private: + KGAPI2::AccountPtr mAccount; +}; + +class FetchCalendarObjectsJob : public GoogleFetchObjectsJob +{ +public: + explicit FetchCalendarObjectsJob(const QString &mCalendarId, const KGAPI2::AccountPtr &account, QObject* parent = 0); + +protected: + virtual KGAPI2::FetchJob* getFetchJob(const KGAPI2::AccountPtr& , const QString& folder); + virtual Object getObject(const KGAPI2::ObjectPtr& ); +}; + +class FetchCalendarFoldersJob : public GoogleFetchFoldersJob +{ +public: + explicit FetchCalendarFoldersJob(const KGAPI2::AccountPtr &account, QObject* parent = 0); + +protected: + virtual KGAPI2::FetchJob* getFetchJob(const KGAPI2::AccountPtr& account); + virtual QPair<QString, QString> getFolder(const KGAPI2::ObjectPtr& object); +}; + +class FetchTaskObjectsJob : public GoogleFetchObjectsJob +{ +public: + explicit FetchTaskObjectsJob(const QString &mTasklistId, const KGAPI2::AccountPtr &account, QObject* parent = 0); + +protected: + virtual KGAPI2::FetchJob* getFetchJob(const KGAPI2::AccountPtr& , const QString& folder); + virtual Object getObject(const KGAPI2::ObjectPtr& ); +}; + +class FetchTaskListsJob : public GoogleFetchFoldersJob +{ +public: + explicit FetchTaskListsJob(const KGAPI2::AccountPtr &account, QObject* parent = 0); + +protected: + virtual KGAPI2::FetchJob* getFetchJob(const KGAPI2::AccountPtr& account); + virtual QPair< QString, QString > getFolder(const KGAPI2::ObjectPtr& object); +}; + +#endif
View file
kolab-utils-3.1.tar.gz/migrationutility/googlesourceserver.cpp
Added
@@ -0,0 +1,99 @@ +/* + * Copyright (C) 2013 Christian Mollekopf <mollekopf@kolabsys.com> + * + * 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 "googlesourceserver.h" +#include "googlesourceaccount.h" +#include "imapsourceaccount.h" + +#include <jobs/getuserlistjob.h> +#include <kimap/listjob.h> +#include <kimap/logoutjob.h> +#include <commonconversion.h> +#include <errorhandler.h> + +GoogleSourceServer::GoogleSourceServer(QObject* parent) +: SourceServer(parent), + mPort(993), + mEncryptionMode(KIMAP::LoginJob::AnySslVersion), + mAuthenticationMode(KIMAP::LoginJob::ClearText) +{ + +} + +void GoogleSourceServer::setHost(const QString& host, qint16 port) +{ + mHost = host; + mPort = port; +} + +void GoogleSourceServer::setAdminCredentials(const QString& username, const QString& pw) +{ + mUsername = username; + mPw = pw; +} + +void GoogleSourceServer::setEncryption(KIMAP::LoginJob::EncryptionMode enc) +{ + mEncryptionMode = enc; +} + +void GoogleSourceServer::setAuthentication(KIMAP::LoginJob::AuthenticationMode auth) +{ + mAuthenticationMode = auth; +} + +QList<SourceAccount*> GoogleSourceServer::getSourceAccountsImpl(const QString& user) +{ + QList <SourceAccount*> sourceAccounts; + + KGAPI2::AccountPtr sharedAccount; + + if (shouldMigrateType("contacts")) { + GoogleContactsSourceAccount *contactsAccount = new GoogleContactsSourceAccount(this); + contactsAccount->setUser(user); + sourceAccounts << contactsAccount; + sharedAccount = contactsAccount->account(); + } + + if (shouldMigrateType("events")) { + GoogleCalendarSourceAccount *calendarAccount = new GoogleCalendarSourceAccount(this); + if (sharedAccount) { + calendarAccount->setAccount(sharedAccount); + } + calendarAccount->setUser(user); + sourceAccounts << calendarAccount; + sharedAccount = calendarAccount->account(); + } + + if (shouldMigrateType("tasks")) { + GoogleTasksSourceAccount *tasksAccount = new GoogleTasksSourceAccount(this); + if (sharedAccount) { + tasksAccount->setAccount(sharedAccount); + } + tasksAccount->setUser(user); + sourceAccounts << tasksAccount; + } + + if (shouldMigrateType("mail")) { + IMAPSourceAccount *imapAccount = new IMAPSourceAccount(this); + imapAccount->prepareConnection(mHost, mPort, user, user, mPw, mEncryptionMode, mAuthenticationMode); + imapAccount->setIgnoredFolders(ignoredFolders()); + sourceAccounts << imapAccount; + } + + return sourceAccounts; +} \ No newline at end of file
View file
kolab-utils-3.1.tar.gz/migrationutility/googlesourceserver.h
Added
@@ -0,0 +1,47 @@ +/* + * Copyright (C) 2013 Christian Mollekopf <mollekopf@kolabsys.com> + * + * 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 GOOGLESOURCESERVER_H +#define GOOGLESOURCESERVER_H + +#include <kimap/loginjob.h> +#include <QStringList> + +#include "sourceserver.h" + +class GoogleSourceServer: public SourceServer +{ + Q_OBJECT +public: + explicit GoogleSourceServer(QObject* parent = 0); + + void setHost(const QString &host, qint16 port); + void setAdminCredentials(const QString &username, const QString &pw); + void setEncryption(KIMAP::LoginJob::EncryptionMode); + void setAuthentication(KIMAP::LoginJob::AuthenticationMode); +protected: + virtual QList<SourceAccount*> getSourceAccountsImpl(const QString& user); + void logout(); + QString mHost; + int mPort; + QString mUsername; + QString mPw; + KIMAP::LoginJob::EncryptionMode mEncryptionMode; + KIMAP::LoginJob::AuthenticationMode mAuthenticationMode; +}; + +#endif \ No newline at end of file
View file
kolab-utils-3.1.tar.gz/migrationutility/imapsourceaccount.cpp
Added
@@ -0,0 +1,186 @@ +/* + * Copyright (C) 2013 Christian Mollekopf <mollekopf@kolabsys.com> + * + * 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 "imapsourceaccount.h" + +#include <jobs/fetchmessagesjob.h> +#include <jobs/probeimapserverjob.h> +#include <sessionfactory.h> +#include <kimap/session.h> +#include <kimap/listjob.h> +#include <kimap/logoutjob.h> +#include <kimap/capabilitiesjob.h> +#include <kimap/namespacejob.h> +#include <errorhandler.h> + +FetchIMAPObjectsJob::FetchIMAPObjectsJob(FetchMessagesJob *fetchJob, QObject *parent) +: FetchObjectsJob(parent), mFetchMessagesJob(fetchJob) +{ +} + +void FetchIMAPObjectsJob::start() +{ + connect(mFetchMessagesJob, SIGNAL(messagesReceived(QString,QList<Object>)), this, SIGNAL(objectsReceived(QString,QList<Object>))); + connect(mFetchMessagesJob, SIGNAL(result(KJob*)), this, SLOT(onJobDone(KJob*))); + mFetchMessagesJob->start(); +} + +void FetchIMAPObjectsJob::onJobDone(KJob *job) +{ + if (job->error()) { + setError(job->error()); + setErrorText(job->errorString()); + } + emitResult(); +} + + +IMAPSourceAccount::IMAPSourceAccount(QObject* parent) +: SourceAccount(parent), + mSession(0) +{ + +} + +IMAPSourceAccount::~IMAPSourceAccount() +{ + if (mSession) { + mSession->close(); + mSession->deleteLater(); + } +} + +QPair<Kolab::FolderType, QString> IMAPSourceAccount::translateFolder(const QString& folder) +{ + return QPair<Kolab::FolderType, QString>(Kolab::MailType, folder); +} + +void IMAPSourceAccount::init() +{ + ProbeIMAPServerJob *probeJob = new ProbeIMAPServerJob(mSession, this); + probeJob->exec(); + mPersonalNamespaces = probeJob->personalNamespace(); +} + +QStringList IMAPSourceAccount::lookupFolderList() +{ + Q_ASSERT(mSession); +// Debug() << "lookupFolderList" << mSession->state(); + + init(); + + mMailboxes.clear(); + + KIMAP::ListJob *listJob = new KIMAP::ListJob(mSession); + listJob->setOption(KIMAP::ListJob::IncludeUnsubscribed); + listJob->setQueriedNamespaces(mPersonalNamespaces); + QObject::connect( listJob, SIGNAL(mailBoxesReceived(QList<KIMAP::MailBoxDescriptor>,QList<QList<QByteArray> >)), + this, SLOT(mailBoxesReceived(QList<KIMAP::MailBoxDescriptor>,QList<QList<QByteArray> >))); + listJob->exec(); + Debug() << "found " << mMailboxes.size(); + + QStringList mailboxes; + foreach (const KIMAP::MailBoxDescriptor &descriptor, mMailboxes) { + mailboxes.append(descriptor.name); + } + return mailboxes; +} + +void IMAPSourceAccount::mailBoxesReceived(const QList<KIMAP::MailBoxDescriptor> &descriptors, const QList< QList< QByteArray > > &/* flags */) +{ + mMailboxes.append(descriptors); +} + +void IMAPSourceAccount::recordSuccessfulMigration(const QList<Object> &objects, const QString &folder) +{ + if (mStatefile.isValid()) { + QList<qint64> uids; + foreach (const Object &obj, objects) { + uids << obj.imapUid; + } + mStatefile.appendMigratedUids(folder, uids); + } +} + +FetchObjectsJob* IMAPSourceAccount::fetchObjects(const QString& folder) +{ + FetchMessagesJob *fetchJob = new FetchMessagesJob(folder, mSession, this); + fetchJob->setTransient(true); + if (mStatefile.isValid()) { + fetchJob->setUidsToSkip(mStatefile.getMigratedUids(folder)); + } + return new FetchIMAPObjectsJob(fetchJob, this); +} + +Object IMAPSourceAccount::convertObject(const Object& object, const QString& /*folder*/) const +{ + return object; +} + +QList<qint64> IMAPSourceAccount::getImapUids(const QString &folder) +{ + FetchMessagesJob *fetchJob = new FetchMessagesJob(folder, mSession, this); + fetchJob->fetchScope().mode = KIMAP::FetchJob::FetchScope::Headers; + fetchJob->exec(); + return fetchJob->getImapUids(); +} + +KIMAP::Session* IMAPSourceAccount::getSession() +{ + Q_ASSERT(mSession); + return mSession; +} + +void IMAPSourceAccount::prepareConnection(QString host, qint16 port, const QString& authorizationName, const QString& userName, const QString& password, KIMAP::LoginJob::EncryptionMode encryptionMode, KIMAP::LoginJob::AuthenticationMode authenticationMode) +{ + mHost = host; + mPort = port; + mAuthorizationName = authorizationName; + mUsername = userName; + mPw = password; + mEncryptionMode = encryptionMode; + mAuthenticationMode = authenticationMode; +} + +void IMAPSourceAccount::onSessionStateChanged(KIMAP::Session::State oldstate, KIMAP::Session::State newstate) +{ + if (newstate == KIMAP::Session::Disconnected) { + Debug() << "session disconnected"; + } +} + +KJob *IMAPSourceAccount::login() +{ + mSession = createSession(mHost, mPort, this); + QObject::connect(mSession, SIGNAL(stateChanged(KIMAP::Session::State,KIMAP::Session::State)), + this, SLOT(onSessionStateChanged(KIMAP::Session::State,KIMAP::Session::State)) ); + + KIMAP::LoginJob *loginJob = new KIMAP::LoginJob(mSession); + if (mAuthorizationName != mUsername) { + loginJob->setAuthorizationName(mAuthorizationName); + } + loginJob->setUserName(mUsername); + loginJob->setPassword(mPw); + loginJob->setEncryptionMode(mEncryptionMode); + loginJob->setAuthenticationMode(mAuthenticationMode); + return loginJob; +} + +KJob *IMAPSourceAccount::logout() +{ + return new KIMAP::LogoutJob(mSession); +} \ No newline at end of file
View file
kolab-utils-3.1.tar.gz/migrationutility/imapsourceaccount.h
Added
@@ -0,0 +1,85 @@ +/* + * Copyright (C) 2012 Christian Mollekopf <mollekopf@kolabsys.com> + * + * 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 IMAPSOURCEACCOUNT_H +#define IMAPSOURCEACCOUNT_H + +#include "sourceaccount.h" + +class IMAPSourceAccount: public SourceAccount +{ + Q_OBJECT +public: + explicit IMAPSourceAccount(QObject* parent = 0); + virtual ~IMAPSourceAccount(); + virtual QStringList lookupFolderList(); + virtual FetchObjectsJob *fetchObjects(const QString &folder); + virtual Object convertObject(const Object &object, const QString& folder) const; + virtual QPair<Kolab::FolderType, QString> translateFolder(const QString& folder); + + /** + * Prepare the connection for a login attempt. + */ + void prepareConnection(QString host, qint16 port, const QString &authorizationName, const QString &userName, const QString &password, KIMAP::LoginJob::EncryptionMode encryptionMode, KIMAP::LoginJob::AuthenticationMode authenticationMode); + + KJob *login(); + KJob *logout(); + virtual void recordSuccessfulMigration(const QList<Object> &obj, const QString &folder); + +private slots: + void mailBoxesReceived(const QList<KIMAP::MailBoxDescriptor> &descriptors, const QList< QList< QByteArray > > &flags); + void onSessionStateChanged(KIMAP::Session::State,KIMAP::Session::State); + +protected: + //get namespace + virtual void init(); + Kolab::FolderType getFolderType(const QString &folder); + KIMAP::Session *getSession(); + QList<KIMAP::MailBoxDescriptor> mPersonalNamespaces; + +private: + /** + * Get UIDS of all messages in the folder on the source account + * + * This is used to find out which objects to migrate by subtracting already migrated uids from the list. + */ + QList<qint64> getImapUids(const QString &folder); + + QList<KIMAP::MailBoxDescriptor> mMailboxes; + KIMAP::Session *mSession; + QString mHost; + int mPort; + QString mUsername; + QString mAuthorizationName; + QString mPw; + KIMAP::LoginJob::EncryptionMode mEncryptionMode; + KIMAP::LoginJob::AuthenticationMode mAuthenticationMode; +}; + +class FetchIMAPObjectsJob : public FetchObjectsJob +{ + Q_OBJECT +public: + FetchIMAPObjectsJob(FetchMessagesJob *fetchJob, QObject *parent); + virtual void start(); + FetchMessagesJob * const mFetchMessagesJob; +private slots: + void onJobDone(KJob *job); +}; + + +#endif
View file
kolab-utils-3.0.5.tar.gz/migrationutility/kolabserver.cpp -> kolab-utils-3.1.tar.gz/migrationutility/kolabserver.cpp
Changed
@@ -21,10 +21,10 @@ KolabServer::KolabServer(QObject* parent) : QObject(parent), - mSession(0), mEncryptionMode(KIMAP::LoginJob::TlsV1), mAuthenticationMode(KIMAP::LoginJob::Plain), mDryRun(false), + mWipeTargetFolders(false), mVersion(Kolab::KolabV3) { @@ -67,6 +67,17 @@ mDryRun = enable; } +void KolabServer::setWipeTargetFolders(bool enable) +{ + mWipeTargetFolders = enable; +} + +void KolabServer::setRegextrans(const QStringList ®extrans) +{ + Debug() << "Regextrans: " << regextrans; + mRegextrans = regextrans; +} + KolabAccount* KolabServer::getAccount(const QString& user) { KolabAccount *account = new KolabAccount(this); @@ -78,7 +89,9 @@ } account->setCredentials(targetUser, mPw, mUsername); account->setDryRun(mDryRun); + account->setWipeTargetFolders(mWipeTargetFolders); account->setVersion(mVersion); + account->setRegextrans(mRegextrans); if (!account->init()) { account->deleteLater(); return 0;
View file
kolab-utils-3.0.5.tar.gz/migrationutility/kolabserver.h -> kolab-utils-3.1.tar.gz/migrationutility/kolabserver.h
Changed
@@ -18,13 +18,10 @@ #ifndef KOLABSERVER_H #define KOLABSERVER_H #include <QObject> +#include <QStringList> #include <kolabobject.h> #include <kimap/loginjob.h> -namespace KIMAP { -class Session; -} - class KolabAccount; class KolabServer: public QObject { @@ -38,12 +35,12 @@ void setAuthentication(KIMAP::LoginJob::AuthenticationMode); void addTargetUserForSource(const QString &sourceUser, const QString &targetUser); void setDryRun(bool); + void setWipeTargetFolders(bool); + void setRegextrans(const QStringList &); KolabAccount *getAccount(const QString &user); void setVersion(Kolab::Version); private: - void logout(); - KIMAP::Session *mSession; QString mHost; int mPort; QString mUsername; @@ -51,8 +48,10 @@ KIMAP::LoginJob::EncryptionMode mEncryptionMode; KIMAP::LoginJob::AuthenticationMode mAuthenticationMode; bool mDryRun; + bool mWipeTargetFolders; Kolab::Version mVersion; QHash<QString, QString> mTargetForSourceUser; + QStringList mRegextrans; }; #endif // KOLABSERVER_H
View file
kolab-utils-3.1.tar.gz/migrationutility/kolabsourceaccount.cpp
Added
@@ -0,0 +1,103 @@ +/* + * Copyright (C) 2013 Christian Mollekopf <mollekopf@kolabsys.com> + * + * 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 "kolabsourceaccount.h" + +#include <jobs/probekolabserverjob.h> +#include <errorhandler.h> +#include <kolabobject.h> + +KolabSourceAccount::KolabSourceAccount(QObject* parent) +: IMAPSourceAccount(parent) +{ + +} + +Kolab::FolderType KolabSourceAccount::getFolderType(const QString &folder) const +{ + if (mKolabFolders.values().contains(folder)) { + return Kolab::folderTypeFromString(mKolabFolders.key(folder).toStdString()); + } + return Kolab::MailType; +} + +QPair<Kolab::FolderType, QString> KolabSourceAccount::translateFolder(const QString& folder) +{ + return QPair<Kolab::FolderType, QString>(getFolderType(folder), folder); +} + +void KolabSourceAccount::init() +{ + ProbeKolabServerJob *probeJob = new ProbeKolabServerJob(getSession(), this); + probeJob->exec(); + mKolabFolders = probeJob->kolabFolders(); + mPersonalNamespaces = probeJob->personalNamespace(); +} + +// void KolabSourceAccount::mailBoxesReceived(const QList<KIMAP::MailBoxDescriptor> &descriptors, const QList< QList< QByteArray > > &/* flags */) +// { +// mMailboxes.append(descriptors); +// //TODO store folder type from metadata +// // for (int i = 0; i < descriptors.size(); i++) { +// // Debug() << descriptors.at(i).name; +// // foreach (const QByteArray &arr, flags.at(i)) { +// // Debug() << arr; +// // } +// // } +// } + +QVariant upgradeMessage(const KMime::Message::Ptr &msg) +{ + //TODO deduplicate with upgradetool, check for errors during reading. + Kolab::KolabObjectReader reader; + switch (reader.parseMimeMessage(msg)) { + case Kolab::EventObject: + case Kolab::TodoObject: + case Kolab::JournalObject: + return QVariant::fromValue(reader.getIncidence()); + case Kolab::ContactObject: + return QVariant::fromValue(reader.getContact()); + case Kolab::DistlistObject: + return QVariant::fromValue(reader.getDistlist()); + case Kolab::NoteObject: { + Note note; + note.msg = reader.getNote(); + return QVariant::fromValue(note); + } + case Kolab::DictionaryConfigurationObject: { + Dictionary dictionary; + dictionary.dict = reader.getDictionary(dictionary.lang); + return QVariant::fromValue(dictionary); + } + case Kolab::InvalidObject: + default: + //TODO handle configuration objects + Error() << "failed to read mime file"; + } + return QVariant(); +} + +Object KolabSourceAccount::convertObject(const Object& object, const QString& folder) const +{ + const bool isKolabType = mKolabFolders.values().contains(folder); + if (isKolabType) { + Object obj(object); + obj.object = upgradeMessage(object.object.value<KMime::Message::Ptr>()); + return obj; + } + return object; +}
View file
kolab-utils-3.1.tar.gz/migrationutility/kolabsourceaccount.h
Added
@@ -0,0 +1,39 @@ +/* + * Copyright (C) 2012 Christian Mollekopf <mollekopf@kolabsys.com> + * + * 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 KOLABSOURCEACCOUNT_H +#define KOLABSOURCEACCOUNT_H + +#include "imapsourceaccount.h" + +class KolabSourceAccount: public IMAPSourceAccount +{ + Q_OBJECT +public: + explicit KolabSourceAccount(QObject* parent = 0); + virtual Object convertObject(const Object &object, const QString& folder) const; + virtual QPair<Kolab::FolderType, QString> translateFolder(const QString& folder); + +protected: + virtual void init(); + Kolab::FolderType getFolderType(const QString &folder) const; + +private: + QMultiHash<QString, QString> mKolabFolders; +}; + +#endif
View file
kolab-utils-3.0.5.tar.gz/migrationutility/main.cpp -> kolab-utils-3.1.tar.gz/migrationutility/main.cpp
Changed
@@ -16,6 +16,7 @@ */ #include <QtCore/qcoreapplication.h> +#include <QtGui/QApplication> #include <QtCore/QStringList> #include <QtCore/qfile.h> #include <kcmdlineargs.h> @@ -24,6 +25,10 @@ #include "coordinationjob.h" #include "sourceserver.h" #include "kolabserver.h" +#ifdef BUILD_GOOGLESUPPORT +#include "googlesourceserver.h" +#endif +#include "kolabutils-version.h" KIMAP::LoginJob::EncryptionMode getEncryptionMode(const QString &encrypt) { @@ -66,65 +71,49 @@ } /** - * kolab-migrate --from caldav --to kolab (implied?) --caldav-host caldav.example.org --caldav-authn <admin> --caldav-authz <user> --caldav-pass <pass> --<folder-selection> --<folder-mapping> --kolab-host kolab.example.org --kolab-authn <admin> --kolab-authz <user> --kolab-pass <pass> - -* --regextrans2 '/Public Folders/shared/' Regex transformation of folder paths -* Incremental conversion (folder by folder or even by batch of messages) -* Save state persistently and resume from there after interruption (Wipe before starting and start all over as first step) + * kolab-migrate --from caldav --to kolab (implied?) + * --caldav-host caldav.example.org --caldav-authn <admin> --caldav-authz <user> --caldav-pass <pass> + * --<folder-selection> --<folder-mapping> + * --kolab-host kolab.example.org + * --kolab-authn <admin> --kolab-authz <user> --kolab-pass <pass> + * --regextrans2 '/Public Folders/shared/' Regex transformation of folder paths + * Incremental conversion (folder by folder or even by batch of messages) + * Save state persistently and resume from there after interruption (Wipe before starting and start all over as first step) */ - int main(int argc, char *argv[]) { - KCmdLineArgs::init(argc, argv, "migrationutility", "migrationutility",ki18n("migrationutility"), "0.1"); + KCmdLineArgs::init(argc, argv, "migrationutility", "migrationutility",ki18n("migrationutility"), KOLABUTILS_VERSION); KCmdLineOptions options; options.add("dry", ki18n("Dry run, doesn't change anything on the server, but only prints what would be done (Use with care until this is well tested).")); - options.add("from <type>", ki18n("Source host type (kolab2, kolab3, exchangeimap)")); - - options.add("from-kolab2-host <host>", ki18n("Source Kolab2 host")); - options.add("from-kolab2-port <port>", ki18n("Port"), "143"); - options.add("from-kolab2-user <loginname>", ki18n("Username for single-user migration")); - options.add("from-kolab2-proxyauth <loginname>", ki18n("Username to be used for authentication together with password (optional, works with PLAIN/SASL authentication)")); - options.add("from-kolab2-password <password>", ki18n("Password")); - options.add("from-kolab2-encrypt <mode>", ki18n("Encryption mode to be used (NONE, TLS, SSL)"), "TLS"); - options.add("from-kolab2-auth <mode>", ki18n("Authentication mode to be used (PLAIN, LOGIN, CRAMMD5, DIGESTMD5, NTLM, GSSAPI, ANONYMOUS, CLEARTEXT)"), "PLAIN"); - - options.add("from-kolab3-host <host>", ki18n("Source Kolab3 host")); - options.add("from-kolab3-port <port>", ki18n("Port"), "143"); - options.add("from-kolab3-user <loginname>", ki18n("Username for single-user migration")); - options.add("from-kolab3-proxyauth <loginname>", ki18n("Username to be used for authentication together with password (optional, works with PLAIN/SASL authentication)")); - options.add("from-kolab3-password <password>", ki18n("Password")); - options.add("from-kolab3-encrypt <mode>", ki18n("Encryption mode to be used (NONE, TLS, SSL)"), "TLS"); - options.add("from-kolab3-auth <mode>", ki18n("Authentication mode to be used (PLAIN, LOGIN, CRAMMD5, DIGESTMD5, NTLM, GSSAPI, ANONYMOUS, CLEARTEXT)"), "PLAIN"); + options.add("wipeTargetFolders", ki18n("Wipe and recreate target folders (Will only wipe folders in the personal namespace).")); + options.add("statefile", ki18n("Resume from migration-state file"), "/tmp/kolabmigration.state"); + options.add("skipFolder <sourcefolder>", ki18n("Source-folders to skip. Uses a simple \"contains\"-filter. Can be stated multiple times.")); + options.add("objectType <type>", ki18n("Objects types to migrate (MAIL, CONTACTS, EVENTS, TASKS). By default all types are migrated. Can be stated multiple times. Currently only implemented for the google source type.")); + options.add("regextrans2 <s/MATCH/REPLACE/>", ki18n("Allows to translate target folder names. Use --dry to figure out the names that are used by default. Wilcards can be used in the MATCH part, and prefixes can be created in the REPLACE part using \"prefix/*\".")); + + options.add("from <type>", ki18n("Source host type (kolab2, kolab3, exchangeimap, google)")); - options.add("from-exchangeimap-host <host>", ki18n("Source Exchange IMAP host")); - options.add("from-exchangeimap-port <port>", ki18n("Port"), "143"); - options.add("from-exchangeimap-user <loginname>", ki18n("Username for single-user migration")); - options.add("from-exchangeimap-proxyauth <loginname>", ki18n("Username to be used for authentication together with password (optional, works with PLAIN/SASL authentication)")); - options.add("from-exchangeimap-password <password>", ki18n("Password")); - options.add("from-exchangeimap-encrypt <mode>", ki18n("Encryption mode to be used (NONE, TLS, SSL)"), "TLS"); - options.add("from-exchangeimap-auth <mode>", ki18n("Authentication mode to be used (PLAIN, LOGIN, CRAMMD5, DIGESTMD5, NTLM, GSSAPI, ANONYMOUS, CLEARTEXT)"), "PLAIN"); + options.add("from-host <host>", ki18n("Source host")); + options.add("from-port <port>", ki18n("Port"), "143"); + options.add("from-user <loginname>", ki18n("Username for single-user migration")); + options.add("from-proxyauth <loginname>", ki18n("Username to be used for authentication together with password (optional, works with PLAIN/SASL authentication)")); + options.add("from-password <password>", ki18n("Password")); + options.add("from-encrypt <mode>", ki18n("Encryption mode to be used (NONE, TLS, SSL)"), "TLS"); + options.add("from-auth <mode>", ki18n("Authentication mode to be used (PLAIN, LOGIN, CRAMMD5, DIGESTMD5, NTLM, GSSAPI, ANONYMOUS, CLEARTEXT)"), "PLAIN"); options.add("to <type>", ki18n("Target host type (kolab2, kolab3)")); - options.add("to-kolab2-host <host>", ki18n("Target Kolab2 host")); - options.add("to-kolab2-port <port>", ki18n("Port"), "143"); - options.add("to-kolab2-user <loginname>", ki18n("Username for single-user migration")); - options.add("to-kolab2-proxyauth <loginname>", ki18n("Username to be used for authentication together with password (optional, works with PLAIN/SASL authentication)")); - options.add("to-kolab2-password <password>", ki18n("Password")); - options.add("to-kolab2-encrypt <mode>", ki18n("Encryption mode to be used (NONE, TLS, SSL)"), "TLS"); - options.add("to-kolab2-auth <mode>", ki18n("Authentication mode to be used (PLAIN, LOGIN, CRAMMD5, DIGESTMD5, NTLM, GSSAPI, ANONYMOUS, CLEARTEXT)"), "PLAIN"); + options.add("to-host <host>", ki18n("Target host")); + options.add("to-port <port>", ki18n("Port"), "143"); + options.add("to-user <loginname>", ki18n("Username for single-user migration")); + options.add("to-proxyauth <loginname>", ki18n("Username to be used for authentication together with password (optional, works with PLAIN/SASL authentication)")); + options.add("to-password <password>", ki18n("Password")); + options.add("to-encrypt <mode>", ki18n("Encryption mode to be used (NONE, TLS, SSL)"), "TLS"); + options.add("to-auth <mode>", ki18n("Authentication mode to be used (PLAIN, LOGIN, CRAMMD5, DIGESTMD5, NTLM, GSSAPI, ANONYMOUS, CLEARTEXT)"), "PLAIN"); - options.add("to-kolab3-host <host>", ki18n("Target Kolab3 host")); - options.add("to-kolab3-port <port>", ki18n("Port"), "143"); - options.add("to-kolab3-user <loginname>", ki18n("Username for single-user migration")); - options.add("to-kolab3-proxyauth <loginname>", ki18n("Username to be used for authentication together with password (optional, works with PLAIN/SASL authentication)")); - options.add("to-kolab3-password <password>", ki18n("Password")); - options.add("to-kolab3-encrypt <mode>", ki18n("Encryption mode to be used (NONE, TLS, SSL)"), "TLS"); - options.add("to-kolab3-auth <mode>", ki18n("Authentication mode to be used (PLAIN, LOGIN, CRAMMD5, DIGESTMD5, NTLM, GSSAPI, ANONYMOUS, CLEARTEXT)"), "PLAIN"); - KCmdLineArgs::addCmdLineOptions( options ); - QCoreApplication app(argc, argv); + QApplication app(argc, argv); KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); @@ -132,34 +121,59 @@ if (!args->getOption("from").compare("kolab2", Qt::CaseInsensitive)) { Debug() << "From Kolab2 Server"; KolabSourceServer *kolabSourceServer = new KolabSourceServer(&app); - kolabSourceServer->setHost(args->getOption("from-kolab2-host"), args->getOption("from-kolab2-port").toInt()); - kolabSourceServer->setAdminCredentials(args->getOption("from-kolab2-proxyauth"), args->getOption("from-kolab2-password")); - kolabSourceServer->setEncryption(getEncryptionMode(args->getOption("from-kolab2-encrypt"))); - kolabSourceServer->setAuthentication(getAuthenticationMode(args->getOption("from-kolab2-auth"))); - if (args->isSet("from-kolab2-user")) { - kolabSourceServer->setSingleUser(args->getOption("from-kolab2-user")); + kolabSourceServer->setHost(args->getOption("from-host"), args->getOption("from-port").toInt()); + kolabSourceServer->setAdminCredentials(args->getOption("from-proxyauth"), args->getOption("from-password")); + kolabSourceServer->setEncryption(getEncryptionMode(args->getOption("from-encrypt"))); + kolabSourceServer->setAuthentication(getAuthenticationMode(args->getOption("from-auth"))); + if (args->isSet("from-user")) { + kolabSourceServer->setSingleUser(args->getOption("from-user")); } sourceServer = kolabSourceServer; } else if (!args->getOption("from").compare("kolab3", Qt::CaseInsensitive)) { Debug() << "From Kolab3 Server"; KolabSourceServer *kolabSourceServer = new KolabSourceServer(&app); - kolabSourceServer->setHost(args->getOption("from-kolab3-host"), args->getOption("from-kolab3-port").toInt()); - kolabSourceServer->setAdminCredentials(args->getOption("from-kolab3-proxyauth"), args->getOption("from-kolab3-password")); - kolabSourceServer->setEncryption(getEncryptionMode(args->getOption("from-kolab3-encrypt"))); - kolabSourceServer->setAuthentication(getAuthenticationMode(args->getOption("from-kolab3-auth"))); - if (args->isSet("from-kolab3-user")) { - kolabSourceServer->setSingleUser(args->getOption("from-kolab3-user")); + kolabSourceServer->setHost(args->getOption("from-host"), args->getOption("from-port").toInt()); + kolabSourceServer->setAdminCredentials(args->getOption("from-proxyauth"), args->getOption("from-password")); + kolabSourceServer->setEncryption(getEncryptionMode(args->getOption("from-encrypt"))); + kolabSourceServer->setAuthentication(getAuthenticationMode(args->getOption("from-auth"))); + if (args->isSet("from-user")) { + kolabSourceServer->setSingleUser(args->getOption("from-user")); } sourceServer = kolabSourceServer; } else if (!args->getOption("from").compare("exchangeimap", Qt::CaseInsensitive)) { Debug() << "From Exchange IMAP Server"; ExchangeIMAPSourceServer *source = new ExchangeIMAPSourceServer(&app); - source->setHost(args->getOption("from-exchangeimap-host"), args->getOption("from-exchangeimap-port").toInt()); - source->setAdminCredentials(args->getOption("from-exchangeimap-proxyauth"), args->getOption("from-exchangeimap-password")); - source->setEncryption(getEncryptionMode(args->getOption("from-exchangeimap-encrypt"))); - source->setAuthentication(getAuthenticationMode(args->getOption("from-exchangeimap-auth"))); - if (args->isSet("from-exchangeimap-user")) { - source->setSingleUser(args->getOption("from-exchangeimap-user")); + source->setHost(args->getOption("from-host"), args->getOption("from-port").toInt()); + source->setAdminCredentials(args->getOption("from-proxyauth"), args->getOption("from-password")); + source->setEncryption(getEncryptionMode(args->getOption("from-encrypt"))); + source->setAuthentication(getAuthenticationMode(args->getOption("from-auth"))); + if (args->isSet("from-user")) { + source->setSingleUser(args->getOption("from-user")); + } + sourceServer = source; + } +#ifdef BUILD_GOOGLESUPPORT + else if (!args->getOption("from").compare("google", Qt::CaseInsensitive)) { + Debug() << "From Google Server"; + GoogleSourceServer *source = new GoogleSourceServer(&app); + source->setHost("imap.googlemail.com", 993); + source->setAdminCredentials(args->getOption("from-proxyauth"), args->getOption("from-password")); + source->setEncryption(KIMAP::LoginJob::AnySslVersion); + source->setAuthentication(KIMAP::LoginJob::ClearText); + source->setIgnoredFolders(QStringList() << QLatin1String("[Gmail]")); //ignore the virtual folders + source->setSingleUser(args->getOption("from-user")); + sourceServer = source; + } +#endif //BUILD_GOOGLESUPPORT + else if (!args->getOption("from").compare("imap", Qt::CaseInsensitive)) { + Debug() << "From IMAP Server"; + IMAPSourceServer *source = new IMAPSourceServer(&app); + source->setHost(args->getOption("from-host"), args->getOption("from-port").toInt()); + source->setAdminCredentials(args->getOption("from-proxyauth"), args->getOption("from-password")); + source->setEncryption(getEncryptionMode(args->getOption("from-encrypt"))); + source->setAuthentication(getAuthenticationMode(args->getOption("from-auth"))); + if (args->isSet("from-user")) { + source->setSingleUser(args->getOption("from-user")); } sourceServer = source; } @@ -168,31 +182,23 @@ if (!args->getOption("to").compare("kolab2", Qt::CaseInsensitive)) { Debug() << "To Kolab2 Server"; kolabServer = new KolabServer(&app); - kolabServer->setHost(args->getOption("to-kolab2-host"), args->getOption("to-kolab2-port").toInt()); - kolabServer->setAdminCredentials(args->getOption("to-kolab2-proxyauth"), args->getOption("to-kolab2-password"));
View file
kolab-utils-3.0.5.tar.gz/migrationutility/migratefolderjob.cpp -> kolab-utils-3.1.tar.gz/migrationutility/migratefolderjob.cpp
Changed
@@ -19,23 +19,84 @@ #include "sourceaccount.h" #include "kolabaccount.h" #include <errorhandler.h> +#include <qdebug.h> MigrateFolderJob::MigrateFolderJob(const QString &folder, SourceAccount* sourceAccount, KolabAccount *kolabAccount, QObject* parent) : KJob(parent), mSourceAccount(sourceAccount), mKolabAccount(kolabAccount), - mFolder(folder) + mFolder(folder), + mRunningAppendJobs(0), + mFetchDone(false) { } void MigrateFolderJob::start() { + QMetaObject::invokeMethod(this, "doStart", Qt::QueuedConnection); +} + +void MigrateFolderJob::doStart() +{ + Debug() << "migrating " << mFolder; const QPair<Kolab::FolderType, QString> &targetFolder = mSourceAccount->translateFolder(mFolder); - mKolabAccount->createFolder(targetFolder.second, targetFolder.first); - QList<Object> messages = mSourceAccount->getObjects(mFolder); - foreach (const Object &obj, messages) { - mKolabAccount->appendObject(obj, targetFolder.second); + mTargetFolder = mKolabAccount->applyTargetFolderTransformations(targetFolder.second); + mKolabAccount->createFolder(mTargetFolder, targetFolder.first); + + FetchObjectsJob *fetchJob = mSourceAccount->fetchObjects(mFolder); + if (!fetchJob) { + setErrorText("Invalid FetchMessagesJob"); + setError(KJob::UserDefinedError); + emitResult(); + return; } - emitResult(); -} \ No newline at end of file + connect(fetchJob, SIGNAL(objectsReceived(QString, QList<Object>)), this, SLOT(processMessages(QString, QList<Object>))); + connect(fetchJob, SIGNAL(result(KJob*)), this, SLOT(fetchJobFinished(KJob*))); + fetchJob->start(); +} + +void MigrateFolderJob::fetchJobFinished(KJob *job) +{ + if (job->error()) { + setErrorText("Fetch job failed"); + setError(KJob::UserDefinedError); + Warning() << job->errorString(); + } + mFetchDone = true; + checkDone(); +} + +void MigrateFolderJob::processMessages(const QString &folder, const QList<Object> &messages) +{ + foreach (const Object &message, messages) { + KJob *appendJob = mKolabAccount->appendObject(mSourceAccount->convertObject(message, folder), mTargetFolder); + if (!appendJob) { + continue; + } + appendJob->setProperty("appendedObject", QVariant::fromValue(message)); + connect(appendJob, SIGNAL(result(KJob*)), this, SLOT(appendJobFinished(KJob*))); + mRunningAppendJobs++; + appendJob->start(); + } +} + +void MigrateFolderJob::appendJobFinished(KJob *job) +{ + mRunningAppendJobs--; + if (job->error()) { + setErrorText("Append job failed"); + setError(KJob::UserDefinedError); + Warning() << job->errorString(); + } else { + mSourceAccount->recordSuccessfulMigration(job->property("appendedObject").value<Object>(), mFolder); + } + checkDone(); +} + +void MigrateFolderJob::checkDone() +{ + if (mRunningAppendJobs <= 0 && mFetchDone) { + emitResult(); + } +}
View file
kolab-utils-3.0.5.tar.gz/migrationutility/migratefolderjob.h -> kolab-utils-3.1.tar.gz/migrationutility/migratefolderjob.h
Changed
@@ -20,6 +20,7 @@ #include <kjob.h> +struct Object; class SourceAccount; class KolabAccount; class MigrateFolderJob: public KJob @@ -28,10 +29,19 @@ public: explicit MigrateFolderJob(const QString &folder, SourceAccount *sourceAccount, KolabAccount *kolabAccount, QObject* parent = 0); virtual void start(); +private Q_SLOTS: + void doStart(); + void fetchJobFinished(KJob*); + void appendJobFinished(KJob*); + void processMessages(const QString &,const QList<Object>&); private: + void checkDone(); SourceAccount *mSourceAccount; KolabAccount *mKolabAccount; QString mFolder; + QString mTargetFolder; + int mRunningAppendJobs; + bool mFetchDone; }; #endif // MIGRATEFOLDERJOB_H
View file
kolab-utils-3.0.5.tar.gz/migrationutility/migrateuserjob.cpp -> kolab-utils-3.1.tar.gz/migrationutility/migrateuserjob.cpp
Changed
@@ -21,17 +21,17 @@ #include "kolabaccount.h" #include <errorhandler.h> -MigrateUserJob::MigrateUserJob(SourceAccount *sourceAccount, KolabAccount *kolabAccount, QObject* parent) +MigrateUserJob::MigrateUserJob(const QList<SourceAccount*> &sourceAccounts, KolabAccount *kolabAccount, QObject* parent) : KJob(parent), - mSourceAccount(sourceAccount), + mSourceAccounts(sourceAccounts), + mCurrentSourceAccount(0), mKolabAccount(kolabAccount) { - connect(mSourceAccount, SIGNAL(folderList(QStringList)), this, SLOT(migrateFolders(QStringList))); } void MigrateUserJob::start() { - if (!mKolabAccount || !mSourceAccount) { + if (!mKolabAccount || mSourceAccounts.isEmpty()) { setError(KJob::UserDefinedError); setErrorText("Failed to get source or target account"); emitResult(); @@ -39,19 +39,121 @@ } mKolabAccount->cleanAccount(); mKolabAccount->setupFolders(); - migrateFolders(mSourceAccount->lookupFolderList()); + migrateNextAccount(); } -void MigrateUserJob::migrateFolders(const QStringList &folders) +void MigrateUserJob::migrateNextAccount() { - foreach (const QString &folder, folders) { - MigrateFolderJob *job = new MigrateFolderJob(folder, mSourceAccount, mKolabAccount, this); - job->exec(); + if (mCurrentSourceAccount) { + mCurrentSourceAccount->deleteLater(); + } + if (mSourceAccounts.isEmpty()) { + KJob *logoutJob = mKolabAccount->logout(); + if (logoutJob) { + Debug() << "running target logout job"; + connect(logoutJob, SIGNAL(result(KJob*)), this, SLOT(onLogoutDone(KJob*))); + logoutJob->start(); + } else { + onLogoutDone(0); + } + return; + } + mCurrentSourceAccount = mSourceAccounts.takeFirst(); + KJob *loginJob = mCurrentSourceAccount->login(); + Q_ASSERT(loginJob); + connect(loginJob, SIGNAL(result(KJob*)), this, SLOT(onLoginDone(KJob*))); + loginJob->start(); +} + +void MigrateUserJob::onLoginDone(KJob *job) +{ + if (job->error()) { + Error() << "Failed to login in source account: " << job->errorString(); + emitResult(); + return; + } + Debug() << "login successful"; + //Go to eventloop first, to ensure the session is fully initialized before running further jobs + QMetaObject::invokeMethod(this, "fetchFolders", Qt::QueuedConnection); +} + +void MigrateUserJob::onLogoutDone(KJob *job) +{ + if (job && job->error()) { + Error() << "Failed to logout" << job->errorString(); } - mSourceAccount->logout(); - mKolabAccount->logout(); emitResult(); } +void MigrateUserJob::fetchFolders() +{ + FetchFoldersJob *fetchJob = mCurrentSourceAccount->fetchFolderList(); + if (!fetchJob) { + mFolderQueue = mCurrentSourceAccount->lookupFolderList(); + migrateNextFolder(); + } else { + connect(fetchJob, SIGNAL(foldersReceived(QStringList)), this, SLOT(onFoldersReceived(QStringList))); + connect(fetchJob, SIGNAL(result(KJob*)), this, SLOT(onFoldersFetched(KJob*))); + fetchJob->start(); + } +} + +void MigrateUserJob::onFoldersReceived(const QStringList &folders) +{ + mFolderQueue.append(folders); +} + +void MigrateUserJob::onFoldersFetched(KJob* ) +{ + migrateNextFolder(); +} + +void MigrateUserJob::migrateNextFolder() +{ + if (!mCurrentFolder.isEmpty()) { + Warning() << "already migrating a folder"; + return; + } + if (mFolderQueue.isEmpty()) { + Debug() << "Account migrated, logging out"; + KJob *logoutJob = mCurrentSourceAccount->logout(); + if (logoutJob) { + connect(logoutJob, SIGNAL(result(KJob*)), this, SLOT(migrateNextAccount())); + logoutJob->start(); + } else { + QMetaObject::invokeMethod(this, "migrateNextAccount", Qt::QueuedConnection); + } + return; + } + mCurrentFolder = mFolderQueue.takeFirst(); + if (isIgnored(mCurrentFolder)) { + Debug() << "Skipping source folder: " << mCurrentFolder; + mCurrentFolder.clear(); + migrateNextFolder(); + return; + } -// #include "migrateuserjob.moc" + MigrateFolderJob *job = new MigrateFolderJob(mCurrentFolder, mCurrentSourceAccount, mKolabAccount, this); + connect(job, SIGNAL(result(KJob*)), this, SLOT(onFolderMigrated(KJob*))); + job->start(); +} + +void MigrateUserJob::onFolderMigrated(KJob *job) +{ + if (job->error()) { + Error() << "Failed to migrate folder: " << mCurrentFolder; + Error() << job->errorString(); + } + mCurrentFolder.clear(); + migrateNextFolder(); +} + +bool MigrateUserJob::isIgnored(const QString &sourceFolder) const +{ + foreach (const QString &ignoredFolder, mCurrentSourceAccount->ignoredFolders()) { + if (sourceFolder.contains(ignoredFolder)) { + return true; + } + } + return false; +}
View file
kolab-utils-3.0.5.tar.gz/migrationutility/migrateuserjob.h -> kolab-utils-3.1.tar.gz/migrationutility/migrateuserjob.h
Changed
@@ -19,20 +19,38 @@ #define MIGRATEUSERJOB_H #include <kjob.h> +#include <QStringList> class SourceAccount; class KolabAccount; + +/** + * Migrates a user to his new target account (currently limited to a kolab account as target). + * + * A user may have multiple source accounts on the source server (i.e. one imap account, one cardav account, ...) + */ class MigrateUserJob: public KJob { Q_OBJECT public: - explicit MigrateUserJob(SourceAccount *sourceAccount, KolabAccount *kolabAccount, QObject* parent = 0); + explicit MigrateUserJob(const QList<SourceAccount*> &sourceAccounts, KolabAccount *kolabAccount, QObject* parent = 0); virtual void start(); private slots: - void migrateFolders(const QStringList &); + void onLoginDone(KJob*); + void onFolderMigrated(KJob*); + void onFoldersFetched(KJob*); + void onFoldersReceived(const QStringList &); + void onLogoutDone(KJob *); + void fetchFolders(); + void migrateNextFolder(); + void migrateNextAccount(); private: - SourceAccount *mSourceAccount; + bool isIgnored(const QString &) const; + QStringList mFolderQueue; + QList<SourceAccount*> mSourceAccounts; + SourceAccount *mCurrentSourceAccount; KolabAccount *mKolabAccount; + QString mCurrentFolder; }; #endif // MIGRATEUSERJOB_H
View file
kolab-utils-3.0.5.tar.gz/migrationutility/sourceaccount.cpp -> kolab-utils-3.1.tar.gz/migrationutility/sourceaccount.cpp
Changed
@@ -30,302 +30,126 @@ #include <kcalcore/memorycalendar.h> #include <kcalcore/icalformat.h> -SourceAccount::SourceAccount(QObject* parent) -: QObject(parent) +FetchObjectsJob::FetchObjectsJob(QObject* parent) +: KJob(parent) { } -QStringList SourceAccount::lookupFolderList() +FetchFoldersJob::FetchFoldersJob(QObject* parent) +: KJob(parent) { - return QStringList(); -} -QList<Object> SourceAccount::getObjects(const QString& /* folder */) -{ - return QList<Object>(); } -void SourceAccount::logout() + +SourceAccount::SourceAccount(QObject* parent) +: QObject(parent) { } -QPair<Kolab::FolderType, QString> SourceAccount::translateFolder(const QString& folder) +KJob* SourceAccount::login() { - return QPair<Kolab::FolderType, QString>(Kolab::MailType, folder); + return 0; } - - -TestAccount::TestAccount(QObject* parent) - : SourceAccount(parent) +QStringList SourceAccount::lookupFolderList() { - mFolderList << QLatin1String("folder1"); - mFolderList << QLatin1String("folder2"); - mFolderList << QLatin1String("folder3"); + return QStringList(); } -QStringList TestAccount::lookupFolderList() +FetchFoldersJob* SourceAccount::fetchFolderList() { - return mFolderList; + return 0; } -QList<Object> TestAccount::getObjects(const QString& folder) +QList<Object> SourceAccount::getObjects(const QString &folder) { - Debug() << folder; - Q_ASSERT(mFolderList.removeAll(folder) == 1); - return QList<Object>(); + mObjectList.clear(); + FetchObjectsJob *job = fetchObjects(folder); + connect(job, SIGNAL(objectsReceived(QString,QList<Object>)), this, SLOT(onObjectsReceived(QString,QList<Object>))); + job->exec(); + QList<Object> objects; + foreach (const Object &object, mObjectList) { + objects.append(convertObject(object, folder)); + } + mObjectList.clear(); + return objects; } -//-------------------------------------------------------------- - - -KolabSourceAccount::KolabSourceAccount(KIMAP::Session *session, QObject* parent) -: SourceAccount(parent), - mSession(session) +void SourceAccount::onObjectsReceived(const QString &, const QList<Object> &objects) { - + mObjectList.append(objects); } -void KolabSourceAccount::init() +KJob *SourceAccount::logout() { - Q_ASSERT(mSession); - - ProbeKolabServerJob *probeJob = new ProbeKolabServerJob(mSession, this); - probeJob->exec(); - mKolabFolders = probeJob->kolabFolders(); - mPersonalNamespaces = probeJob->personalNamespace(); + return 0; } -Kolab::FolderType KolabSourceAccount::getFolderType(const QString &folder) +QPair<Kolab::FolderType, QString> SourceAccount::translateFolder(const QString& folder) { - if (mKolabFolders.values().contains(folder)) { - return Kolab::folderTypeFromString(mKolabFolders.key(folder).toStdString()); - } - return Kolab::MailType; + return QPair<Kolab::FolderType, QString>(Kolab::MailType, folder); } -QPair<Kolab::FolderType, QString> KolabSourceAccount::translateFolder(const QString& folder) +void SourceAccount::setStatefile(const StateFile &statefile) { - return QPair<Kolab::FolderType, QString>(getFolderType(folder), folder); + mStatefile = statefile; } -QStringList KolabSourceAccount::lookupFolderList() +void SourceAccount::recordSuccessfulMigration(const Object &object, const QString &folder) { -// Debug() << "lookupFolderList" << mHost << mPort << mUsername << mPw; - init(); - mMailboxes.clear(); - - KIMAP::ListJob *listJob = new KIMAP::ListJob(mSession); - listJob->setOption(KIMAP::ListJob::IncludeUnsubscribed); - listJob->setQueriedNamespaces(mPersonalNamespaces); - QObject::connect( listJob, SIGNAL(mailBoxesReceived(QList<KIMAP::MailBoxDescriptor>,QList<QList<QByteArray> >)), - this, SLOT(mailBoxesReceived(QList<KIMAP::MailBoxDescriptor>,QList<QList<QByteArray> >))); - listJob->exec(); - Debug() << "found " << mMailboxes.size(); - - QStringList mailboxes; - foreach (const KIMAP::MailBoxDescriptor &descriptor, mMailboxes) { - mailboxes.append(descriptor.name); - } - return mailboxes; + recordSuccessfulMigration(QList<Object>() << object, folder); } -void KolabSourceAccount::mailBoxesReceived(const QList<KIMAP::MailBoxDescriptor> &descriptors, const QList< QList< QByteArray > > &/* flags */) +void SourceAccount::recordSuccessfulMigration(const QList<Object> &/* object */, const QString &/* folder */) { - mMailboxes.append(descriptors); - //TODO store folder type from metadata -// for (int i = 0; i < descriptors.size(); i++) { -// Debug() << descriptors.at(i).name; -// foreach (const QByteArray &arr, flags.at(i)) { -// Debug() << arr; -// } -// } } -QVariant upgradeMessage(KMime::Message::Ptr msg) +void SourceAccount::setIgnoredFolders(const QStringList &ignoredFolders) { - //TODO deduplicate with upgradetool, check for errors during reading. - Kolab::KolabObjectReader reader; - switch (reader.parseMimeMessage(msg)) { - case Kolab::EventObject: - case Kolab::TodoObject: - case Kolab::JournalObject: - return QVariant::fromValue(reader.getIncidence()); - case Kolab::ContactObject: - return QVariant::fromValue(reader.getContact()); - case Kolab::DistlistObject: - return QVariant::fromValue(reader.getDistlist()); - case Kolab::NoteObject: { - Note note; - note.msg = reader.getNote(); - return QVariant::fromValue(note); - } - case Kolab::DictionaryConfigurationObject: { - Dictionary dictionary; - dictionary.dict = reader.getDictionary(dictionary.lang); - return QVariant::fromValue(dictionary); - } - case Kolab::InvalidObject: - default: - //TODO handle configuration objects - Error() << "failed to read mime file"; - } - return QVariant(); + mIgnoredFolders = ignoredFolders; } -QList<Object> KolabSourceAccount::getObjects(const QString& folder) +QStringList SourceAccount::ignoredFolders() const { - bool isKolabType = false; - if (mKolabFolders.values().contains(folder)) { - isKolabType = true; - } -// Debug() << folder; - FetchMessagesJob *fetchJob = new FetchMessagesJob(folder, mSession, this); - fetchJob->exec(); - Debug() << fetchJob->getMessages().size(); - QList<Object> messages; - foreach (const KMime::Message::Ptr &msg, fetchJob->getMessages()) { - Object obj;
View file
kolab-utils-3.0.5.tar.gz/migrationutility/sourceaccount.h -> kolab-utils-3.1.tar.gz/migrationutility/sourceaccount.h
Changed
@@ -26,69 +26,151 @@ #include <kimap/listjob.h> #include <kmime/kmime_message.h> #include "object.h" +#include "jobs/fetchmessagesjob.h" +#include "statefile.h" -class SourceAccount: public QObject +/** + * Job interface to retrieve objects from a folder. + */ +class FetchObjectsJob: public KJob { Q_OBJECT public: - explicit SourceAccount(QObject* parent = 0); - - virtual QStringList lookupFolderList(); - virtual QList<Object> getObjects(const QString &folder); - virtual void logout(); - virtual QPair<Kolab::FolderType, QString> translateFolder(const QString& folder); -signals: - void folderList(const QStringList &); -// FindFoldersJob *getFolderList(); -// GetObjectsJob *getObjects(const QString &folder); -// KolabObject convertObject(); -// QString getDestinationFolder(const QString &folder); + explicit FetchObjectsJob(QObject* parent = 0); +Q_SIGNALS: + /** + * Emitted when objects are received from a folder. + * First arument is the sourcefolder that the objects where fetched from. + */ + void objectsReceived(QString, QList<Object>); }; -class TestAccount: public SourceAccount +/** + * Job interface to retrieve folder of an account. + */ +class FetchFoldersJob: public KJob { Q_OBJECT public: - explicit TestAccount(QObject* parent = 0); - virtual QStringList lookupFolderList(); - virtual QList<Object> getObjects(const QString &folder); - QStringList mFolderList; + explicit FetchFoldersJob(QObject* parent = 0); +Q_SIGNALS: + /** + * Emitted when objects are received from a folder. + * First arument is the sourcefolder that the objects where fetched from. + */ + void foldersReceived(QStringList); }; - -class KolabSourceAccount: public SourceAccount +/** + * Represents a single users account on a server. + * + * This class is used as factory for the jobs to extract the necessary data that needs to be migrated. + * + * One account typically represents access via a single protocol (i.e. an imap account). + */ +class SourceAccount: public QObject { Q_OBJECT public: - explicit KolabSourceAccount(KIMAP::Session *session, QObject* parent = 0); + explicit SourceAccount(QObject* parent = 0); + + /** + * Login to the source account. + * + * If the job is sucessful, a session has been established and the source account can be used. + */ + virtual KJob *login(); + + /* + * Synchronous lookup of folder list + */ virtual QStringList lookupFolderList(); - virtual QList<Object> getObjects(const QString &folder); - virtual QPair<Kolab::FolderType, QString> translateFolder(const QString& folder); - void logout(); - -private slots: - void mailBoxesReceived(const QList<KIMAP::MailBoxDescriptor> &descriptors, const QList< QList< QByteArray > > &flags); + /** + * Asynchronous lookup of folders + */ + virtual FetchFoldersJob *fetchFolderList(); + + /** + * Synchronous wrapper around fetch objects + convertObject + * + * Use only for testing. + * + * Returns all objects of the source folder already converted using convertObject. + */ + QList<Object> getObjects(const QString &sourceFolder); + + /** + * Async method to retrieve objects + * + * used in combination with convertObject to stream objects. + * + * @param sourceFolder Folder on the source server to fetch objects from. + */ + virtual FetchObjectsJob *fetchObjects(const QString &sourceFolder); + + /** + * convert source object to target object. + * Used when streaming objects. + */ + virtual Object convertObject(const Object &object, const QString& sourceFolder) const; + + /** + * Close connection to source account; + */ + virtual KJob *logout(); + + /** + * Translate source folder to target folder + */ + virtual QPair<Kolab::FolderType, QString> translateFolder(const QString& sourceFolder); + + /** + * Set a statefile to record migration progress. + * This allows to resume the migration. + */ + void setStatefile(const StateFile &); + + /** + * Convenience method to record the migration of a single object. + */ + void recordSuccessfulMigration(const Object &obj, const QString &folder); + + /** + * Record the sucessful migration of an object. + */ + virtual void recordSuccessfulMigration(const QList<Object> &obj, const QString &sourceFolder); + + /** + * Specify a list of regex to ignore source folders. + */ + void setIgnoredFolders(const QStringList &); + virtual QStringList ignoredFolders() const; + protected: - void init(); - Kolab::FolderType getFolderType(const QString &folder); - KIMAP::Session *mSession; - KIMAP::LoginJob::EncryptionMode mEncryptionMode; - KIMAP::LoginJob::AuthenticationMode mAuthenticationMode; - QList<KIMAP::MailBoxDescriptor> mMailboxes; - QList<KIMAP::MailBoxDescriptor> mPersonalNamespaces; - QMultiHash<QString, QString> mKolabFolders; + StateFile mStatefile; +private slots: + void onObjectsReceived(const QString &, const QList<Object> &); + +private: + QList<Object> mObjectList; + QStringList mIgnoredFolders; }; -class ExchangeIMAPSourceAccount: public KolabSourceAccount +class TestAccount: public SourceAccount { Q_OBJECT public: - explicit ExchangeIMAPSourceAccount(KIMAP::Session *session, QObject* parent = 0); - Kolab::FolderType getFolderType(const QString &folder); - QPair<Kolab::ObjectType, KMime::Content*> getObjectType(const KMime::Message::Ptr &msg); - virtual QList<Object> getObjects(const QString &folder); - virtual QPair<Kolab::FolderType, QString> translateFolder(const QString& folder); + explicit TestAccount(QObject* parent = 0); + virtual QStringList lookupFolderList(); + virtual FetchObjectsJob *fetchObjects(const QString &sourceFolder); + virtual KJob *login(); + QStringList mFolderList; +private: + class DummyJob : public KJob { + virtual void start() {emitResult();} + }; }; + #endif // SOURCEACCOUNT_H
View file
kolab-utils-3.0.5.tar.gz/migrationutility/sourceserver.cpp -> kolab-utils-3.1.tar.gz/migrationutility/sourceserver.cpp
Changed
@@ -16,29 +16,63 @@ */ #include "sourceserver.h" -#include "uiproxy.h" #include <jobs/getuserlistjob.h> +#include "sessionfactory.h" #include <kimap/listjob.h> #include <kimap/logoutjob.h> #include <commonconversion.h> #include <errorhandler.h> +#include "kolabsourceaccount.h" +#include "exchangesourceaccount.h" -SourceServer::SourceServer(QObject* parent): QObject(parent) +UserListJob::UserListJob(QObject* parent) +: KJob(parent) { } -SourceAccount* SourceServer::getSourceAccount(const QString& /* user */) +FixedUserListJob::FixedUserListJob(const QStringList& userList, QObject* parent) +: UserListJob(parent), + mUserList(userList) { - return 0; + +} + +void FixedUserListJob::start() +{ + QMetaObject::invokeMethod(this, "doEmitResult", Qt::QueuedConnection); +} + +void FixedUserListJob::doEmitResult() +{ + emitResult(); +} + +QStringList FixedUserListJob::getUserList() const +{ + return mUserList; } -QStringList SourceServer::getUserList() +SourceServer::SourceServer(QObject* parent): QObject(parent) +{ + +} + +QList<SourceAccount*> SourceServer::getSourceAccounts(const QString &user) +{ + const QList<SourceAccount*> accounts = getSourceAccountsImpl(user); + foreach (SourceAccount * account, accounts) { + account->setIgnoredFolders(mIgnoredFolders); + } + return accounts; +} + +UserListJob *SourceServer::listUsers() { if (!mExplicitUsers.isEmpty()) { - return mExplicitUsers; + return new FixedUserListJob(mExplicitUsers, this); } return retrieveUserList(); } @@ -48,12 +82,40 @@ mExplicitUsers.append(user); } -QStringList SourceServer::retrieveUserList() +UserListJob *SourceServer::retrieveUserList() { - return QStringList(); + return 0; } +void SourceServer::setStatefile(const QString &statefile) +{ + mStatefile = statefile; +} +void SourceServer::setIgnoredFolders(const QStringList &ignoredFolders) +{ + Debug() << "Skipping source folders: " << ignoredFolders; + mIgnoredFolders = ignoredFolders; +} + +QStringList SourceServer::ignoredFolders() const +{ + return mIgnoredFolders; +} + +void SourceServer::setObjectTypesToMigrate(const QStringList &types) +{ + Debug() << "Migrating only types: " << types; + mObjectTypesToMigrate = types; +} + +bool SourceServer::shouldMigrateType(const QString &type) const +{ + if (mObjectTypesToMigrate.isEmpty()) { + return true; + } + return mObjectTypesToMigrate.contains(type, Qt::CaseInsensitive); +} TestServer::TestServer(QObject* parent) @@ -64,22 +126,90 @@ mUsers << QLatin1String("user3"); } -QStringList TestServer::retrieveUserList() -{ - return mUsers; -} - -SourceAccount* TestServer::getSourceAccount(const QString& user) +QList<SourceAccount*> TestServer::getSourceAccountsImpl(const QString& user) { Q_UNUSED(user); Q_ASSERT(mUsers.removeAll(user) == 1); - return new TestAccount(this); + return QList<SourceAccount*>() << new TestAccount(this); } +UserListJob *TestServer::retrieveUserList() +{ + return new FixedUserListJob(mUsers, this); +} //--------------------------------------------------------------------------- -KolabSourceServer::KolabSourceServer(QObject* parent) +IMAPUserListJob::IMAPUserListJob(const QString &host, qint16 port, const IMAPConnectionSettings &settings, QObject* parent) +: UserListJob(parent), + mSession(createSession(host, port, this)), + mConnectionSettings(settings) +{ +} + +IMAPUserListJob::~IMAPUserListJob() +{ + if (mSession) { + mSession->close(); + mSession->deleteLater(); + } +} + +void IMAPUserListJob::start() +{ + KIMAP::LoginJob *loginJob = new KIMAP::LoginJob(mSession); + loginJob->setUserName(mConnectionSettings.username()); + loginJob->setPassword(mConnectionSettings.password()); + loginJob->setEncryptionMode(mConnectionSettings.encryptionMode()); + loginJob->setAuthenticationMode(mConnectionSettings.authenticationMode()); + connect(loginJob, SIGNAL(result(KJob*)), this, SLOT(onLoginDone(KJob*))); + loginJob->start(); +} + +void IMAPUserListJob::onLoginDone(KJob *job) +{ + if (job->error()) { + setError(KJob::UserDefinedError); + setErrorText("Failed to login: " + job->errorString()); + emitResult(); + return; + } + GetUserListJob *userListJob = new GetUserListJob(mSession, this); + connect(userListJob, SIGNAL(result(KJob*)), this, SLOT(onUserListJobDone(KJob*))); + userListJob->start(); +} + +void IMAPUserListJob::onUserListJobDone(KJob *job) +{ + if (job->error()) { + setError(KJob::UserDefinedError); + setErrorText("Failed to retrieve user list: " + job->errorString()); + emitResult(); + return; + } + GetUserListJob *userListJob = static_cast<GetUserListJob*>(job); + mUserList = userListJob->getUserList(); + KIMAP::LogoutJob *logoutJob = new KIMAP::LogoutJob(mSession); + connect(logoutJob, SIGNAL(result(KJob*)), this, SLOT(onLogoutDone(KJob*))); + logoutJob->start(); +} + +void IMAPUserListJob::onLogoutDone(KJob *job) +{ + if (job->error()) { + setError(KJob::UserDefinedError); + setErrorText("Error during logout: " + job->errorString()); + } + emitResult();
View file
kolab-utils-3.0.5.tar.gz/migrationutility/sourceserver.h -> kolab-utils-3.1.tar.gz/migrationutility/sourceserver.h
Changed
@@ -23,19 +23,72 @@ #include <qsharedpointer.h> #include <QStringList> #include "sourceaccount.h" +#include <kolab/kolabdefinitions.h> +/** + * Job interface to retrieve users from a server. + */ +class UserListJob: public KJob +{ + Q_OBJECT +public: + explicit UserListJob(QObject* parent = 0); + virtual QStringList getUserList() const = 0; +}; + +class FixedUserListJob: public UserListJob +{ + Q_OBJECT +public: + explicit FixedUserListJob(const QStringList &userList, QObject* parent = 0); + virtual void start(); + virtual QStringList getUserList() const; + +private slots: + void doEmitResult(); + +private: + QStringList mUserList; +}; + + + +/** + * The source server represents a server with user accounts that need to be migrated. + * + * The server can support multiple access protocols per user, that are each represented by a source account. + */ class SourceServer: public QObject { Q_OBJECT public: explicit SourceServer(QObject* parent = 0); -// void setAdminCredentials(const QString &username, const QString &pw); - virtual SourceAccount *getSourceAccount(const QString &user); - QStringList getUserList(); - virtual QStringList retrieveUserList(); + QList<SourceAccount*> getSourceAccounts(const QString &user); + UserListJob *listUsers(); void setSingleUser(const QString &); + void setStatefile(const QString &); + + /** + * Specify a list of regex to ignore source folders. + */ + void setIgnoredFolders(const QStringList &); + QStringList ignoredFolders() const; + + void setObjectTypesToMigrate(const QStringList &); protected: + virtual QList<SourceAccount*> getSourceAccountsImpl(const QString &user) = 0; + /** + * Reeimplement to retrieve a user list from the server. + * Note that the retrieved username is used to login to the users account on the source server. + */ + virtual UserListJob *retrieveUserList(); + + bool shouldMigrateType(const QString &type) const; QStringList mExplicitUsers; + QString mStatefile; +private: + QStringList mIgnoredFolders; + QStringList mObjectTypesToMigrate; }; @@ -45,26 +98,61 @@ public: explicit TestServer(QObject* parent = 0); - virtual SourceAccount *getSourceAccount(const QString &user); - virtual QStringList retrieveUserList(); QStringList mUsers; +protected: + virtual UserListJob *retrieveUserList(); + virtual QList< SourceAccount* > getSourceAccountsImpl(const QString& user); +}; + +class IMAPConnectionSettings { +public: + IMAPConnectionSettings(const QString &username, const QString &pw, KIMAP::LoginJob::EncryptionMode encryptionMode, KIMAP::LoginJob::AuthenticationMode authenticationMode) + : mUsername(username), mPassword(pw), mEncryptionMode(encryptionMode), mAuthenticationMode(authenticationMode) + {} + QString username() const { return mUsername; } + QString password() const { return mPassword; } + KIMAP::LoginJob::EncryptionMode encryptionMode() const { return mEncryptionMode; } + KIMAP::LoginJob::AuthenticationMode authenticationMode() const { return mAuthenticationMode; } +private: + const QString mUsername; + const QString mPassword; + const KIMAP::LoginJob::EncryptionMode mEncryptionMode; + const KIMAP::LoginJob::AuthenticationMode mAuthenticationMode; }; -class KolabSourceServer: public SourceServer +class IMAPUserListJob: public UserListJob { Q_OBJECT public: - explicit KolabSourceServer(QObject* parent = 0); - - virtual SourceAccount *getSourceAccount(const QString &user); - virtual QStringList retrieveUserList(); + explicit IMAPUserListJob(const QString &host, qint16 port, const IMAPConnectionSettings &settings, QObject* parent = 0); + virtual ~IMAPUserListJob(); + virtual void start(); + virtual QStringList getUserList() const; + +private slots: + void onLoginDone(KJob*); + void onUserListJobDone(KJob*); + void onLogoutDone(KJob*); + +private: + KIMAP::Session *mSession; + const IMAPConnectionSettings mConnectionSettings; + QStringList mUserList; +}; + +class IMAPSourceServer: public SourceServer +{ + Q_OBJECT +public: + explicit IMAPSourceServer(QObject* parent = 0); void setHost(const QString &host, qint16 port); void setAdminCredentials(const QString &username, const QString &pw); void setEncryption(KIMAP::LoginJob::EncryptionMode); void setAuthentication(KIMAP::LoginJob::AuthenticationMode); protected: - void logout(); + virtual QList< SourceAccount* > getSourceAccountsImpl(const QString& user); + virtual UserListJob *retrieveUserList(); KIMAP::Session *mSession; QString mHost; int mPort; @@ -74,13 +162,24 @@ KIMAP::LoginJob::AuthenticationMode mAuthenticationMode; }; -class ExchangeIMAPSourceServer: public KolabSourceServer +class KolabSourceServer: public IMAPSourceServer +{ + Q_OBJECT +public: + explicit KolabSourceServer(QObject* parent = 0); + +protected: + virtual QList< SourceAccount* > getSourceAccountsImpl(const QString& user); +}; + +class ExchangeIMAPSourceServer: public IMAPSourceServer { Q_OBJECT public: explicit ExchangeIMAPSourceServer(QObject* parent = 0); - virtual SourceAccount *getSourceAccount(const QString &user); +protected: + virtual QList< SourceAccount* > getSourceAccountsImpl(const QString& user); }; #endif // SOURCESERVER_H
View file
kolab-utils-3.1.tar.gz/migrationutility/statefile.cpp
Added
@@ -0,0 +1,72 @@ +/* + * Copyright (C) 2012 Christian Mollekopf <mollekopf@kolabsys.com> + * + * 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 "statefile.h" +#include <QSettings> +#include <qdebug.h> + +Q_DECLARE_METATYPE(QList<qint64>) + +StateFile::StateFile() +{ + +} + +StateFile::StateFile(const QString &filename, const QString &user) +: mFilename(filename), + mUser(user) +{ + +} + +QList< qint64 > StateFile::getMigratedUids(const QString& folder) +{ + QSettings settings(mFilename, QSettings::IniFormat); + settings.beginGroup(mUser); + const QVariantList list = settings.value(folder).toList(); + settings.endGroup(); + QList<qint64> uids; + foreach (const QVariant &var, list) { + uids << var.value<qint64>(); + } + return uids; +} + +void StateFile::setMigratedUids(const QString& folder, const QList<qint64> &uids) +{ + QSettings settings(mFilename, QSettings::IniFormat); + settings.beginGroup(mUser); + QVariantList variantList; + foreach (qint64 uid, uids) { + qDebug() << uid; + variantList << uid; + } + settings.setValue(folder, variantList); + settings.endGroup(); +} + +void StateFile::appendMigratedUids(const QString& folder, const QList< qint64 >& uids) +{ + QList<qint64> list = getMigratedUids(folder); + list.append(uids); + setMigratedUids(folder, list); +} + +bool StateFile::isValid() +{ + return (!mFilename.isEmpty() && !mUser.isEmpty()); +}
View file
kolab-utils-3.1.tar.gz/migrationutility/statefile.h
Added
@@ -0,0 +1,43 @@ +/* + * Copyright (C) 2012 Christian Mollekopf <mollekopf@kolabsys.com> + * + * 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 STATEFILE_H +#define STATEFILE_H + +#include <QList> +#include <QString> + +/** + * Migration state + * TODO store UIDVALIDITY with file to ensure imap uids are still valid + */ +class StateFile +{ +public: + StateFile(); + StateFile(const QString &filename, const QString &user); + QList<qint64> getMigratedUids(const QString &folder); +// void addMigratedUid(const QString &folder, qint64 uid); + void setMigratedUids(const QString& folder, const QList<qint64> &uids); + void appendMigratedUids(const QString& folder, const QList<qint64> &uids); + bool isValid(); +private: + QString mFilename; + QString mUser; +}; + +#endif // STATEFILE_H
View file
kolab-utils-3.0.5.tar.gz/migrationutility/tests/CMakeLists.txt -> kolab-utils-3.1.tar.gz/migrationutility/tests/CMakeLists.txt
Changed
@@ -1,37 +1,23 @@ - -include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/.. ) -include_directories(${CMAKE_CURRENT_BINARY_DIR}) - -# QT4_WRAP_CPP(MIGRATIONTEST_MOC -# ${CMAKE_CURRENT_SOURCE_DIR}/migrationtest.cpp -# ) - - -# QT4_AUTOMOC( -# ${CMAKE_CURRENT_SOURCE_DIR}/migrationtest.cpp -# ) -qt4_generate_moc( - ${CMAKE_CURRENT_SOURCE_DIR}/migrationtest.cpp - ${CMAKE_CURRENT_BINARY_DIR}/migrationtest.moc +include_directories( + ${CMAKE_CURRENT_SOURCE_DIR}/.. + ${CMAKE_CURRENT_BINARY_DIR} ) -# message("blasbblab ${kolabproxy_shared_relative_SRCS} : ${MIGRATION_SRCS}") -# message("sdfsdf ${MIGRATIONTEST_MOC}") +set(MIGRATIONTEST_DEPENDENCIES + migration_static + ${COMMON_DEPENDENCIES} + ${QT_QTTEST_LIBRARY} + ${MIGRATION_LIBRARIES} +) -add_executable(migrationtest ${MIGRATION_SRCS} ${MIGRATION_MOC} migrationtest.cpp migrationtest.moc) -# set_target_properties(migrationtest PROPERTIES AUTOMOC TRUE) -target_link_libraries(migrationtest ${COMMON_DEPENDENCIES} ${QT_QTTEST_LIBRARY} kolabutils) +qt4_automoc(migrationtest.cpp) +add_executable(migrationtest migrationtest.cpp) +target_link_libraries(migrationtest ${MIGRATIONTEST_DEPENDENCIES}) -qt4_generate_moc( - ${CMAKE_CURRENT_SOURCE_DIR}/migrationscenariotest.cpp - ${CMAKE_CURRENT_BINARY_DIR}/migrationscenariotest.moc -) -add_executable(migrationscenariotest ${MIGRATION_SRCS} ${MIGRATION_MOC} migrationscenariotest.cpp migrationscenariotest.moc) -target_link_libraries(migrationscenariotest ${COMMON_DEPENDENCIES} ${QT_QTTEST_LIBRARY} kolabutils) +qt4_automoc(migrationscenariotest.cpp) +add_executable(migrationscenariotest migrationscenariotest.cpp) +target_link_libraries(migrationscenariotest ${MIGRATIONTEST_DEPENDENCIES}) -qt4_generate_moc( - ${CMAKE_CURRENT_SOURCE_DIR}/exchangeimaptest.cpp - ${CMAKE_CURRENT_BINARY_DIR}/exchangeimaptest.moc -) -add_executable(exchangeimaptest ${MIGRATION_SRCS} ${MIGRATION_MOC} exchangeimaptest.cpp exchangeimaptest.moc) -target_link_libraries(exchangeimaptest ${COMMON_DEPENDENCIES} ${QT_QTTEST_LIBRARY} kolabutils) +qt4_automoc(exchangeimaptest.cpp) +add_executable(exchangeimaptest exchangeimaptest.cpp) +target_link_libraries(exchangeimaptest ${MIGRATIONTEST_DEPENDENCIES})
View file
kolab-utils-3.0.5.tar.gz/migrationutility/tests/exchangeimaptest.cpp -> kolab-utils-3.1.tar.gz/migrationutility/tests/exchangeimaptest.cpp
Changed
@@ -14,8 +14,8 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "exchangeimaptest.h" -#include <QObject> #include <QTest> #include <QDebug> #include <kolabobject.h> @@ -28,274 +28,258 @@ #include "lib/kolabaccount.h" #include "lib/testlib/testutils.h" +QPair<Object, Object> ExchangeIMAPTest::createEvent(const QString &uid) +{ + KMime::Message::Ptr msg(new KMime::Message); + msg->userAgent()->from7BitString( "exchangeimaptest" ); + msg->contentType()->setMimeType( "multipart/mixed" ); + msg->contentType()->setBoundary( KMime::multiPartBoundary() ); -/** - * This test simulates an entier migration scenario. - * - * It requires two Kolab Servers, with all the required users already setup (ideally two local virtual machines, which are used for testing only) - * So this is really a complex integration test, which involves all parts of the system, and not a unittest which has to be executed all the time. - * On the other hand it should come quite close to a real world migration scenario and can also show problems with specific imap servers. - * - */ -class ExchangeIMAPTest: public QObject + KMime::Content* content = new KMime::Content(); + content->contentType()->setMimeType( "text/calendar" ); + content->contentTransferEncoding()->setEncoding( KMime::Headers::CEbase64 ); + content->contentDisposition()->setDisposition( KMime::Headers::CDattachment ); + KCalCore::Event::Ptr event(new KCalCore::Event()); + event->setUid(uid); + event->setDtStart(KDateTime::currentUtcDateTime()); + KCalCore::ICalFormat format; + KCalCore::MemoryCalendar::Ptr calendar(new KCalCore::MemoryCalendar(KDateTime::Spec::UTC())); + calendar->addEvent(event); + QByteArray decodedContent = format.toString(calendar, QString(), false).toLatin1(); + content->setBody( decodedContent ); + + msg->addContent(content); + msg->assemble(); + + Object calObj1; + calObj1.object = QVariant::fromValue(msg); + calObj1.flags << QByteArray("\\Seen"); + + Object targetObject; + targetObject.object = QVariant::fromValue(Kolab::KolabObjectWriter::writeEvent(event)); + targetObject.flags << QByteArray("\\Seen"); + return QPair<Object,Object>(calObj1, targetObject); + +} + +QPair<Object, Object> ExchangeIMAPTest::createTodo(const QString &uid) { - Q_OBJECT - - QString sourcehost; - QString targethost; - QString user; - QString admin; - QString adminpw; - qint16 port; - QList<Folder> folders; - QList<Folder> targetFolders; - - QPair<Object, Object> createEvent(const QString &uid) - { - KMime::Message::Ptr msg(new KMime::Message); - msg->userAgent()->from7BitString( "exchangeimaptest" ); - msg->contentType()->setMimeType( "multipart/mixed" ); - msg->contentType()->setBoundary( KMime::multiPartBoundary() ); - - KMime::Content* content = new KMime::Content(); - content->contentType()->setMimeType( "text/calendar" ); - content->contentTransferEncoding()->setEncoding( KMime::Headers::CEbase64 ); - content->contentDisposition()->setDisposition( KMime::Headers::CDattachment ); - KCalCore::Event::Ptr event(new KCalCore::Event()); - event->setUid(uid); - event->setDtStart(KDateTime::currentUtcDateTime()); - KCalCore::ICalFormat format; - KCalCore::MemoryCalendar::Ptr calendar(new KCalCore::MemoryCalendar(KDateTime::Spec::UTC())); - calendar->addEvent(event); - QByteArray decodedContent = format.toString(calendar, QString(), false).toLatin1(); - content->setBody( decodedContent ); - - msg->addContent(content); - msg->assemble(); - - Object calObj1; - calObj1.object = QVariant::fromValue(msg); - calObj1.flags << QByteArray("\\Seen"); - - Object targetObject; - targetObject.object = QVariant::fromValue(Kolab::KolabObjectWriter::writeEvent(event)); - targetObject.flags << QByteArray("\\Seen"); - return QPair<Object,Object>(calObj1, targetObject); + KMime::Message::Ptr msg(new KMime::Message); + msg->userAgent()->from7BitString( "exchangeimaptest" ); + msg->contentType()->setMimeType( "multipart/mixed" ); + msg->contentType()->setBoundary( KMime::multiPartBoundary() ); - } - - QPair<Object, Object> createTodo(const QString &uid) - { - KMime::Message::Ptr msg(new KMime::Message); - msg->userAgent()->from7BitString( "exchangeimaptest" ); - msg->contentType()->setMimeType( "multipart/mixed" ); - msg->contentType()->setBoundary( KMime::multiPartBoundary() ); - - KMime::Content* content = new KMime::Content(); - content->contentType()->setMimeType( "text/calendar" ); - content->contentTransferEncoding()->setEncoding( KMime::Headers::CEbase64 ); - content->contentDisposition()->setDisposition( KMime::Headers::CDattachment ); - KCalCore::Todo::Ptr event(new KCalCore::Todo()); - event->setUid(uid); - event->setDtStart(KDateTime::currentUtcDateTime()); - KCalCore::ICalFormat format; - KCalCore::MemoryCalendar::Ptr calendar(new KCalCore::MemoryCalendar(KDateTime::Spec::UTC())); - calendar->addTodo(event); - QByteArray decodedContent = format.toString(calendar, QString(), false).toLatin1(); - content->setBody( decodedContent ); - - msg->addContent(content); - msg->assemble(); - - Object calObj1; - calObj1.object = QVariant::fromValue(msg); - calObj1.flags << QByteArray("\\Seen"); - - Object targetObject; - targetObject.object = QVariant::fromValue(Kolab::KolabObjectWriter::writeTodo(event)); - targetObject.flags << QByteArray("\\Seen"); - return QPair<Object,Object>(calObj1, targetObject); + KMime::Content* content = new KMime::Content(); + content->contentType()->setMimeType( "text/calendar" ); + content->contentTransferEncoding()->setEncoding( KMime::Headers::CEbase64 ); + content->contentDisposition()->setDisposition( KMime::Headers::CDattachment ); + KCalCore::Todo::Ptr event(new KCalCore::Todo()); + event->setUid(uid); + event->setDtStart(KDateTime::currentUtcDateTime()); + KCalCore::ICalFormat format; + KCalCore::MemoryCalendar::Ptr calendar(new KCalCore::MemoryCalendar(KDateTime::Spec::UTC())); + calendar->addTodo(event); + QByteArray decodedContent = format.toString(calendar, QString(), false).toLatin1(); + content->setBody( decodedContent ); - } - - QPair<Object, Object> createContact(const QString &name) - { - - KABC::Addressee addressee; - addressee.setNameFromString(name); - - KMime::Message::Ptr msg(new KMime::Message); - msg->userAgent()->from7BitString( "exchangeimaptest" ); - msg->contentType()->setMimeType( "multipart/mixed" ); - msg->contentType()->setBoundary( KMime::multiPartBoundary() ); - - KMime::Content* content = new KMime::Content(); - content->contentType()->setMimeType( "text/vcard" ); - content->contentTransferEncoding()->setEncoding( KMime::Headers::CEbase64 ); - content->contentDisposition()->setDisposition( KMime::Headers::CDattachment ); - KABC::VCardConverter converter; - QByteArray decodedContent = converter.createVCard(addressee); - content->setBody( decodedContent ); - - msg->addContent(content); - msg->assemble(); - - Object calObj1; - calObj1.object = QVariant::fromValue(msg); - calObj1.flags << QByteArray("\\Seen"); - - Object targetObject; - targetObject.object = QVariant::fromValue(Kolab::KolabObjectWriter::writeContact(addressee)); - targetObject.flags << QByteArray("\\Seen"); - return QPair<Object,Object>(calObj1, targetObject); - } + msg->addContent(content); + msg->assemble(); - Object createMail(const QString &subject) - { - KMime::Message::Ptr msg(new KMime::Message); - msg->userAgent()->from7BitString( "exchangeimaptest" ); - msg->contentType()->setMimeType( "multipart/mixed" ); - msg->contentType()->setBoundary( KMime::multiPartBoundary() ); - msg->subject()->fromUnicodeString( subject, "utf-8" ); - msg->assemble(); - Object targetObject; - targetObject.object = QVariant::fromValue(msg); - targetObject.flags << QByteArray("\\Seen"); - return targetObject;
View file
kolab-utils-3.1.tar.gz/migrationutility/tests/exchangeimaptest.h
Added
@@ -0,0 +1,66 @@ +/* + * Copyright (C) 2012 Christian Mollekopf <mollekopf@kolabsys.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef EXCHANGEIMAPTEST_H +#define EXCHANGEIMAPTEST_H + +#include <QObject> +#include "testlib/testutils.h" + +class SourceAccount; + +/** + * This test simulates an entier migration scenario. + * + * It requires two Kolab Servers, with all the required users already setup (ideally two local virtual machines, which are used for testing only) + * So this is really a complex integration test, which involves all parts of the system, and not a unittest which has to be executed all the time. + * On the other hand it should come quite close to a real world migration scenario and can also show problems with specific imap servers. + */ +class ExchangeIMAPTest: public QObject +{ + Q_OBJECT +public: + explicit ExchangeIMAPTest(QObject* parent = 0); + virtual ~ExchangeIMAPTest(); + +private slots: + void testMigration(); + +private: + void setupSourceAccount(); + void setupTargetAccount(); + void executeMigration(); + void checkFolders(SourceAccount *account, const QList<Folder> &folders); + void checkTargetAccount(); + void checkSourceAccount(); + + QPair<Object, Object> createEvent(const QString &uid); + QPair<Object, Object> createTodo(const QString &uid); + QPair<Object, Object> createContact(const QString &name); + Object createMail(const QString &subject); + + QString sourcehost; + QString targethost; + QString user; + QString admin; + QString adminpw; + qint16 port; + QList<Folder> folders; + QList<Folder> targetFolders; +}; + +#endif
View file
kolab-utils-3.0.5.tar.gz/migrationutility/tests/migrationscenariotest.cpp -> kolab-utils-3.1.tar.gz/migrationutility/tests/migrationscenariotest.cpp
Changed
@@ -15,162 +15,246 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include <QObject> +#include "migrationscenariotest.h" + #include <QTest> #include <QDebug> +#include <QFile> #include <kolabobject.h> #include "migrationutility/coordinationjob.h" #include "migrationutility/kolabserver.h" #include "migrationutility/sourceserver.h" #include "lib/kolabaccount.h" -#include "lib/testlib/testutils.h" +MigrationScenarioTest::MigrationScenarioTest(QObject* parent) + : QObject(parent), + sourcehost("192.168.122.104"), + targethost("192.168.122.10"), + user("john.doe@example.org"), + admin("cyrus-admin"), + adminpw("admin"), + port(143), + statefilename("/tmp/migrationscenarioteststatefile") +{ +} -/** - * This test simulates an entier migration scenario. - * - * It requires two Kolab Servers, with all the required users already setup (ideally two local virtual machines, which are used for testing only) - * So this is really a complex integration test, which involves all parts of the system, and not a unittest which has to be executed all the time. - * On the other hand it should come quite close to a real world migration scenario and can also show problems with specific imap servers. - * - */ -class MigrationScenarioTest: public QObject +MigrationScenarioTest::~MigrationScenarioTest(){}; + +Object MigrationScenarioTest::createEvent(const QString &uid) { - Q_OBJECT - - QString sourcehost; - QString targethost; - QString user; - QString admin; - QString adminpw; - qint16 port; - QList<Folder> folders; - - Object createEvent(const QString &uid) - { - Object calObj1; - KCalCore::Event::Ptr event(new KCalCore::Event()); - event->setUid(uid); - event->setDtStart(KDateTime::currentUtcDateTime()); - calObj1.object = QVariant::fromValue(Kolab::KolabObjectWriter::writeEvent(event, Kolab::KolabV2, "migrationtest")); - calObj1.flags << QByteArray("\\Seen"); - return calObj1; + Object calObj1; + KCalCore::Event::Ptr event(new KCalCore::Event()); + event->setUid(uid); + event->setDtStart(KDateTime::currentUtcDateTime()); + calObj1.object = QVariant::fromValue(Kolab::KolabObjectWriter::writeEvent(event, Kolab::KolabV2, "migrationtest")); + calObj1.flags << QByteArray("\\Seen"); + return calObj1; +} - } +KolabAccount *MigrationScenarioTest::getAccount(const QString &host) +{ + KolabServer *kolabServer = new KolabServer(this); + kolabServer->setHost(host, port); + kolabServer->setAdminCredentials(admin, adminpw); + kolabServer->setWipeTargetFolders(true); + KolabAccount *account = kolabServer->getAccount(user); + Q_ASSERT(account); + return account; +} -public: - explicit MigrationScenarioTest(QObject* parent = 0) - : QObject(parent), - sourcehost("192.168.122.104"), - targethost("192.168.122.10"), - user("john.doe@example.org"), - admin("cyrus-admin"), - adminpw("admin"), - port(143) - { - folders << Folder("INBOX"); - folders << Folder("Calendar", Kolab::EventType, QList<Object>() << createEvent("uid1")); - folders << Folder("Calendar/Personal Calendar", Kolab::EventType, QList<Object>() << createEvent("uid2")); - folders << Folder("Configuration", Kolab::ConfigurationType); - folders << Folder("Contacts", Kolab::ContactType); - folders << Folder("Drafts"); - folders << Folder("Journal", Kolab::JournalType); - folders << Folder("Notes", Kolab::NoteType); - folders << Folder("Sent"); - folders << Folder("Tasks", Kolab::TaskType); - folders << Folder("Trash"); - } +void MigrationScenarioTest::setupSourceAccount() +{ + KolabAccount *account = getAccount(sourcehost); + account->cleanAccount(); + fillDefaultFolders(folders); + createFolders(account, folders); +} - virtual ~MigrationScenarioTest(){}; - -private: - void setupSourceAccount() - { - KolabServer *kolabServer = new KolabServer(this); - kolabServer->setHost(sourcehost, port); - kolabServer->setAdminCredentials(admin, adminpw); - KolabAccount *account = kolabServer->getAccount(user); - account->cleanAccount(); - createFolders(account, folders); - } +void MigrationScenarioTest::setupTargetAccount() +{ + KolabAccount *account = getAccount(targethost); + account->cleanAccount(); +} - void setupTargetAccount() - { - //Depending on the test scenario, clear target account +void MigrationScenarioTest::executeMigration(bool useStatefile) +{ + QObject obj; + //Copy main.cpp + KolabSourceServer *kolabSourceServer = new KolabSourceServer(&obj); + kolabSourceServer->setHost(sourcehost, port); + kolabSourceServer->setAdminCredentials(admin, adminpw); + kolabSourceServer->setSingleUser(user); + if (useStatefile) { + kolabSourceServer->setStatefile(statefilename); } - void executeMigration() - { - QObject obj; - //Copy main.cpp - KolabSourceServer *kolabSourceServer = new KolabSourceServer(&obj); - kolabSourceServer->setHost(sourcehost, port); - kolabSourceServer->setAdminCredentials(admin, adminpw); - kolabSourceServer->setSingleUser(user); - - KolabServer *kolabServer = new KolabServer(&obj); - kolabServer->setHost(targethost, port); - kolabServer->setAdminCredentials(admin, adminpw); - - CoordinationJob *job = new CoordinationJob(kolabSourceServer, kolabServer, &obj); - job->exec(); - } - - void checkFolders(SourceAccount *account, const QList<Folder> &folders) - { - const QStringList &receivedFolders = account->lookupFolderList(); - QStringList::const_iterator recIt = receivedFolders.constBegin(); - QList<Folder>::const_iterator foldersIt = folders.constBegin(); - QCOMPARE(receivedFolders.size(), folders.size()); - for (;foldersIt != folders.constEnd() && recIt != receivedFolders.constEnd(); ++foldersIt, ++recIt) { - qDebug() << "Folder: " << *recIt; - QCOMPARE(*recIt, foldersIt->name); - //TODO Check folder annotations - - const QList<Object> &objects = account->getObjects(foldersIt->name); - QCOMPARE(objects.size(), foldersIt->objects.size()); - - QList<Object>::const_iterator recObjIt = objects.constBegin(); - QList<Object>::const_iterator objIt = foldersIt->objects.constBegin(); - for (;objIt != foldersIt->objects.constEnd() && recObjIt != objects.constEnd(); ++objIt, ++recObjIt) { - QCOMPARE(*recObjIt->object.value<KCalCore::Incidence::Ptr>().dynamicCast<KCalCore::Event>(), *Kolab::KolabObjectReader(objIt->object.value<KMime::Message::Ptr>()).getEvent()); - foreach (const QByteArray &flag, objIt->flags) { - QVERIFY(recObjIt->flags.contains(flag)); - } + KolabServer *kolabServer = new KolabServer(&obj); + kolabServer->setHost(targethost, port); + kolabServer->setAdminCredentials(admin, adminpw); + + CoordinationJob *job = new CoordinationJob(kolabSourceServer, kolabServer, &obj); + QVERIFY(job->exec()); +} + +void MigrationScenarioTest::checkFolders(SourceAccount *account, const QList<Folder> &folders) +{ + Q_ASSERT(account); + const QStringList &receivedFolders = account->lookupFolderList(); + QStringList::const_iterator recIt = receivedFolders.constBegin(); + QList<Folder>::const_iterator foldersIt = folders.constBegin(); + QCOMPARE(receivedFolders.size(), folders.size()); + for (;foldersIt != folders.constEnd() && recIt != receivedFolders.constEnd(); ++foldersIt, ++recIt) { + qDebug() << "Folder: " << *recIt;
View file
kolab-utils-3.1.tar.gz/migrationutility/tests/migrationscenariotest.h
Added
@@ -0,0 +1,68 @@ +/* + * Copyright (C) 2012 Christian Mollekopf <mollekopf@kolabsys.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef MIGRATIONSCENARIOTEST_H +#define MIGRATIONSCENARIOTEST_H + +#include <QObject> +#include "testlib/testutils.h" + +class SourceAccount; +/** + * This test simulates an entier migration scenario. + * + * It requires two Kolab Servers, with all the required users already setup (ideally two local virtual machines, which are used for testing only) + * So this is really a complex integration test, which involves all parts of the system, and not a unittest which has to be executed all the time. + * On the other hand it should come quite close to a real world migration scenario and can also show problems with specific imap servers. + * + */ +class MigrationScenarioTest: public QObject +{ + Q_OBJECT + +public: + explicit MigrationScenarioTest(QObject* parent = 0); + virtual ~MigrationScenarioTest(); + +private slots: + void init(); + void testMigration(); + void testMassMigration(); + void testLargeAttachments(); + void testStatefile(); + +private: + Object createEvent(const QString &uid); + KolabAccount *getAccount(const QString &host); + void setupSourceAccount(); + void setupTargetAccount(); + void executeMigration(bool useStatefile = false); + void checkFolders(SourceAccount *account, const QList<Folder> &folders); + void checkTargetAccount(); + void checkSourceAccount(); + + QString sourcehost; + QString targethost; + QString user; + QString admin; + QString adminpw; + qint16 port; + QList<Folder> folders; + QString statefilename; +}; + +#endif
View file
kolab-utils-3.0.5.tar.gz/migrationutility/tests/migrationtest.cpp -> kolab-utils-3.1.tar.gz/migrationutility/tests/migrationtest.cpp
Changed
@@ -1,4 +1,21 @@ -#include <QObject> +/* + * Copyright (C) 2012 Christian Mollekopf <mollekopf@kolabsys.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +#include "migrationtest.h" + #include <QTest> #include "coordinationjob.h" #include "sourceserver.h" @@ -6,30 +23,26 @@ #include "migrateuserjob.h" #include <kolabaccount.h> -class MigrationTest : public QObject +void MigrationTest::testUsersProcessed() +{ + TestServer *server = new TestServer(this); + KolabServer *kolabServer = new KolabServer(this); + kolabServer->setDryRun(true); + CoordinationJob *job = new CoordinationJob(server, kolabServer, this); + QVERIFY(job->exec()); + QVERIFY(server->mUsers.isEmpty()); +} + +void MigrationTest::testFoldersProcessed() { - Q_OBJECT - private slots: - void testUsersProcessed() - { - TestServer *server = new TestServer(this); - KolabServer *kolabServer = new KolabServer(this); - CoordinationJob *job = new CoordinationJob(server, kolabServer, this); - job->exec(); - QVERIFY(server->mUsers.isEmpty()); - } - - void testFoldersProcessed() - { - TestAccount *server = new TestAccount(this); - KolabAccount *kolabServer = new KolabAccount(this); - MigrateUserJob *job = new MigrateUserJob(server, kolabServer, this); - job->exec(); - QVERIFY(server->mFolderList.isEmpty()); - } -}; + TestAccount *testSourceAccount = new TestAccount(this); + KolabAccount *kolabTargetAccount = new KolabAccount(this); + kolabTargetAccount->setDryRun(true); + MigrateUserJob *job = new MigrateUserJob(QList<SourceAccount*>() << testSourceAccount, kolabTargetAccount, this); + QVERIFY(job->exec()); + QVERIFY(testSourceAccount->mFolderList.isEmpty()); +} QTEST_MAIN( MigrationTest ) -// #include "moc_migrationtest.cxx" #include "migrationtest.moc" \ No newline at end of file
View file
kolab-utils-3.1.tar.gz/migrationutility/tests/migrationtest.h
Added
@@ -0,0 +1,30 @@ +/* + * Copyright (C) 2012 Christian Mollekopf <mollekopf@kolabsys.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +#ifndef MIGRATIONTEST_H +#define MIGRATIONTEST_H + +#include <QObject> + +class MigrationTest : public QObject +{ + Q_OBJECT + private slots: + void testUsersProcessed(); + void testFoldersProcessed(); +}; + +#endif
View file
kolab-utils-3.0.5.tar.gz/upgradetool/upgradetool.cpp -> kolab-utils-3.1.tar.gz/upgradetool/upgradetool.cpp
Changed
@@ -24,6 +24,7 @@ #include "upgradeutilities.h" #include "imapupgradejob.h" +#include "kolabutils-version.h" /** * Usage: @@ -41,7 +42,7 @@ int main(int argc, char *argv[]) { - KCmdLineArgs::init(argc, argv, "upgradetool", "upgradetool",ki18n("upgradetool"), "0.1"); + KCmdLineArgs::init(argc, argv, "upgradetool", "upgradetool",ki18n("upgradetool"), KOLABUTILS_VERSION); KCmdLineOptions options; options.add("mime", ki18n("Read mime from stdin or file"));
View file
kolab-utils.dsc
Changed
@@ -2,7 +2,7 @@ Source: kolab-utils Binary: kolab-utils Architecture: any -Version: 3.0.5-2 +Version: 3.1~dev20140624-0~kolab1 Maintainer: Paul Klos <kolab@klos2day.nl> Homepage: http://git.kolab.org/kolab-utils Standards-Version: 3.9.3 @@ -21,5 +21,5 @@ Package-List: kolab-utils deb libs optional Files: - 00000000000000000000000000000000 0 kolab-utils-3.0.5.tar.gz + 00000000000000000000000000000000 0 kolab-utils-3.1.tar.gz 00000000000000000000000000000000 0 debian.tar.gz
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.