Projects
Kolab:Winterfell
kolab-utils
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 24
View file
kolab-utils.spec
Changed
@@ -10,7 +10,7 @@ %endif Name: kolab-utils -Version: 3.1.2 +Version: 3.1.3 Release: 1%{?dist} Summary: Kolab Utilities @@ -88,6 +88,10 @@ %attr(0750,root,%{httpd_group}) %dir %{_sharedstatedir}/kolab-freebusy %changelog +* Fri Sep 2 2016 Christian Mollekopf <mollekopf@kolabsys.com> - 3.1.3-1 +- Release version 3.1.3 +- Format checking capabilities in kolab-formatupgrade + * Fri Apr 15 2016 Jeroen van Meeuwen <vanmeeuwen@kolabsys.com> - 3.1.2-1 - Release version 3.1.2
View file
debian.changelog
Changed
@@ -1,3 +1,9 @@ +kolab-utils (3.1.3-0~kolab1) unstable; urgency=low + + * Release of version 3.1.3 + + -- Christian Mollekopf (Kolab Systems) <mollekopf@kolabsys.com> Fri, 2 Sep 2016 23:00:55 +0100 + kolab-utils (3.1.2-0~kolab1) unstable; urgency=low * Release of version 3.1.2
View file
kolab-utils-3.1.2.tar.gz/CMakeLists.txt -> kolab-utils-3.1.3.tar.gz/CMakeLists.txt
Changed
@@ -18,7 +18,7 @@ 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 2) +set(Kolabutils_VERSION_PATCH 3) 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})
View file
kolab-utils-3.1.2.tar.gz/fbdaemon/tests/CMakeLists.txt -> kolab-utils-3.1.3.tar.gz/fbdaemon/tests/CMakeLists.txt
Changed
@@ -1,4 +1,4 @@ -add_definitions (-DSCENARIO_DATA_DIR="${CMAKE_CURRENT_SOURCE_DIR}/data") +add_definitions (-DSCENARIO_DATA_DIR="\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\"") include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/..
View file
kolab-utils-3.1.2.tar.gz/lib/jobs/findkolabfoldersjob.cpp -> kolab-utils-3.1.3.tar.gz/lib/jobs/findkolabfoldersjob.cpp
Changed
@@ -59,6 +59,11 @@ return m_kolabFolders; } +QMultiHash<QString, QString> FindKolabFoldersJob::getAllFolders() +{ + return m_allFolders; +} + void FindKolabFoldersJob::onMailBoxesReceived( const QList< KIMAP::MailBoxDescriptor > &descriptors, const QList< QList<QByteArray> > &/* flags */ ) { @@ -136,6 +141,7 @@ //TODO default flag? const QByteArray &kolabType = rawAnnotations[annotation][attribute]; // Debug() << meta->mailBox() << kolabType; + m_allFolders.insertMulti(kolabType, meta->mailBox()); if (!kolabType.isEmpty()) { if (kolabType.contains(KOLAB_FOLDER_TYPE_CONTACT)) { m_kolabFolders.insertMulti(KOLAB_FOLDER_TYPE_CONTACT, meta->mailBox());
View file
kolab-utils-3.1.2.tar.gz/lib/jobs/findkolabfoldersjob.h -> kolab-utils-3.1.3.tar.gz/lib/jobs/findkolabfoldersjob.h
Changed
@@ -37,8 +37,8 @@ public: explicit FindKolabFoldersJob(const QStringList &serverCapabilities, const QList<KIMAP::MailBoxDescriptor> &personalNamespaces, const QList<KIMAP::MailBoxDescriptor> &excluded, KIMAP::Session *session, QObject* parent = 0); virtual void start(); -// QStringList getKolabFolders(); QMultiHash<QString, QString> getKolabFolders(); + QMultiHash<QString, QString> getAllFolders(); private slots: void onMailBoxesReceived( const QList< KIMAP::MailBoxDescriptor > &descriptors, const QList< QList<QByteArray> > &flags ); @@ -49,6 +49,7 @@ QList<KIMAP::MailBoxDescriptor> m_mailboxes; QHash<QString, QString> m_kolabFolders; + QHash<QString, QString> m_allFolders; int m_metadataRetrieveJobs; bool m_mailBoxReceiveDone; QList<KIMAP::MailBoxDescriptor> m_personalNamespaces;
View file
kolab-utils-3.1.2.tar.gz/lib/jobs/probekolabserverjob.cpp -> kolab-utils-3.1.3.tar.gz/lib/jobs/probekolabserverjob.cpp
Changed
@@ -68,6 +68,7 @@ FindKolabFoldersJob *findJob = static_cast<FindKolabFoldersJob*>(job); // qDebug() << "Found kolab folders: " << findJob->getKolabFolders(); mKolabFolders = findJob->getKolabFolders(); + mAllFolders = findJob->getAllFolders(); emitResult(); } @@ -76,6 +77,11 @@ return mKolabFolders; } +QMultiHash<QString, QString> ProbeKolabServerJob::allFolders() const +{ + return mAllFolders; +} + QStringList ProbeKolabServerJob::capabilities() const { return mCapabilities;
View file
kolab-utils-3.1.2.tar.gz/lib/jobs/probekolabserverjob.h -> kolab-utils-3.1.3.tar.gz/lib/jobs/probekolabserverjob.h
Changed
@@ -37,6 +37,7 @@ QList<KIMAP::MailBoxDescriptor> excludedNamespaces() const; QStringList capabilities() const; QMultiHash<QString, QString> kolabFolders() const; + QMultiHash<QString, QString> allFolders() const; protected Q_SLOTS: void onProbeJobDone(KJob *job); @@ -48,6 +49,7 @@ QList<KIMAP::MailBoxDescriptor> mPersonalNamespace; QList<KIMAP::MailBoxDescriptor> mExcludedNamespace; QMultiHash<QString, QString> mKolabFolders; + QMultiHash<QString, QString> mAllFolders; }; #endif // PROBEKOLABSERVERJOB_H
View file
kolab-utils-3.1.2.tar.gz/upgradetool/imapupgradejob.cpp -> kolab-utils-3.1.3.tar.gz/upgradetool/imapupgradejob.cpp
Changed
@@ -121,19 +121,9 @@ return; } - if (m_folderToUpgrade.isEmpty()) { - ProbeKolabServerJob *probeJob = new ProbeKolabServerJob(m_session, this); - connect(probeJob, SIGNAL(result(KJob*)), this, SLOT(onProbeDone(KJob*))); - probeJob->start(); - } else { - SequentialCompositeJob *seqJob = new SequentialCompositeJob(this); - KolabFormatUpgradeJob *upgradeJob = new KolabFormatUpgradeJob(m_folderToUpgrade, m_session, this); - upgradeJob->setUpgradeOptions(m_upgradeOptions); - seqJob->addSubjob(upgradeJob); - seqJob->addSubjob(new KIMAP::LogoutJob(m_session)); - connect(seqJob, SIGNAL(result(KJob*)), this, SLOT(modifyDone(KJob*))); - seqJob->start(); - } + ProbeKolabServerJob *probeJob = new ProbeKolabServerJob(m_session, this); + connect(probeJob, SIGNAL(result(KJob*)), this, SLOT(onProbeDone(KJob*))); + probeJob->start(); } void ImapUpgradeJob::onProbeDone(KJob* job) @@ -147,13 +137,26 @@ Q_ASSERT(capabilitiesJob); SequentialCompositeJob *seqJob = new SequentialCompositeJob(this); + + QMultiHash<QString,QString> folders; + if (!m_upgradeOptions.validateMode) { + folders = capabilitiesJob->kolabFolders(); + } else { + folders = capabilitiesJob->allFolders(); + } QMultiHash<QString, QString>::const_iterator it; - QMultiHash<QString, QString>::const_iterator end = capabilitiesJob->kolabFolders().constEnd(); - for (it = capabilitiesJob->kolabFolders().constBegin(); it != end; ++it) { - if (it.key() == QLatin1String(KOLAB_FOLDER_TYPE_FREEBUSY)) { + QMultiHash<QString, QString>::const_iterator end = folders.constEnd(); + for (it = folders.constBegin(); it != end; ++it) { + if (!m_upgradeOptions.validateMode && it.key() == QLatin1String(KOLAB_FOLDER_TYPE_FREEBUSY)) { + continue; + } + if (!m_folderToUpgrade.isEmpty() && it.value() != m_folderToUpgrade) { continue; } - seqJob->addSubjob(new KolabFormatUpgradeJob(it.value(), m_session, this)); + KolabFormatUpgradeJob *upgradeJob = new KolabFormatUpgradeJob(it.value(), m_session, this); + upgradeJob->setUpgradeOptions(m_upgradeOptions); + upgradeJob->setFolderType(it.key()); + seqJob->addSubjob(upgradeJob); } connect(seqJob, SIGNAL(result(KJob*)), this, SLOT(modifyDone(KJob*)));
View file
kolab-utils-3.1.2.tar.gz/upgradetool/kolabformatupgradejob.cpp -> kolab-utils-3.1.3.tar.gz/upgradetool/kolabformatupgradejob.cpp
Changed
@@ -23,13 +23,20 @@ #include "jobs/sequentialcompositejob.h" #include "jobs/messagemodifyjob.h" #include <kolabobject.h> +#include <kolabdefinitions.h> +#include <formathelpers.h> #include <errorhandler.h> #include <kimap/selectjob.h> #include <kimap/fetchjob.h> #include <kimap/expungejob.h> +#include <kimap/storejob.h> #include <QStringList> +#include <QFile> +#include <QDir> + +const char* FlagDeleted = "\\Deleted"; KolabFormatUpgradeJob::KolabFormatUpgradeJob(const QString& folder, KIMAP::Session* session, QObject* parent) : KJob(parent), @@ -45,9 +52,14 @@ m_upgradeOptions = upgradeOptions; } +void KolabFormatUpgradeJob::setFolderType(const QString &folderType) +{ + m_folderType = folderType; +} + void KolabFormatUpgradeJob::start() { - Debug() << "Processing Mailbox....... " << m_folder; + Debug() << "Processing Mailbox....... " << m_folder << " of type: " << m_folderType; if (m_session->state() == KIMAP::Session::Disconnected) { Warning() << "Session is not connected, skipping"; emitResult(); @@ -94,24 +106,89 @@ fetch->start(); } +static QList<Kolab::ObjectType> getExpectedTypeFromFolderType(const QString &folderType) +{ + switch(Kolab::folderTypeFromString(folderType.toStdString())) { + case Kolab::MailType: + return QList<Kolab::ObjectType>(); + case Kolab::ContactType: + return QList<Kolab::ObjectType>() << Kolab::ContactObject << Kolab::DistlistObject; + case Kolab::EventType: + return QList<Kolab::ObjectType>() << Kolab::EventObject; + case Kolab::TaskType: + return QList<Kolab::ObjectType>() << Kolab::TodoObject; + case Kolab::JournalType: + return QList<Kolab::ObjectType>() << Kolab::JournalObject; + case Kolab::NoteType: + return QList<Kolab::ObjectType>() << Kolab::NoteObject; + case Kolab::ConfigurationType: + return QList<Kolab::ObjectType>() << Kolab::DictionaryConfigurationObject << Kolab::RelationConfigurationObject; + case Kolab::FreebusyType: + return QList<Kolab::ObjectType>() << Kolab::FreebusyObject; + case Kolab::FileType: + return QList<Kolab::ObjectType>(); + case Kolab::LastType: + break; + } + return QList<Kolab::ObjectType>(); +} + void KolabFormatUpgradeJob::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 ) -{ -// Debug() << mailBox; +{ foreach ( qint64 number, uids.keys() ) { -// Debug() << "preparing for upgrade " << uids[number]; const KMime::Message::Ptr &message = messages[number]; - //TODO implement different target folder - KMime::Message::Ptr msg = Kolab::Upgrade::upgradeMessage(message, m_upgradeOptions); - //Skip messages that we're already kolabv3 - if (!msg.get()) { - Error() << "failed to convert message with uid " << QString::number(uids[number]); - continue; + if (m_upgradeOptions.validateMode) { + const qint64 uid = uids[number]; + if (m_folderType.isEmpty() || m_folderType.contains("mail")) { + //TODO validate emails if possible? + } else { + if (Kolab::Upgrade::validateMessage(message, getExpectedTypeFromFolderType(m_folderType))) { + Debug() << "Checked the message with the uid " << uid; + } else { + Error() << "The message with the uid " << uid << " in the folder: " << m_folder << " is invalid!"; + if (!m_upgradeOptions.saveTo.isEmpty()) { + const QString directory = m_upgradeOptions.saveTo + "/" + m_folder; + const QString path = directory + "/" + QString::number(uid) + ".eml"; + Debug() << "Saving message to: " << path; + QDir dir; + if (!dir.mkpath(directory)) { + Warning() << "Failed to create the directory " << directory; + } + QFile file(path); + if (!file.open(QIODevice::WriteOnly|QIODevice::Text)) { + Warning() << "Failed to store the message" << uid; + } else { + QTextStream out(&file); + out << message->encodedContent(); + } + } + if (!m_upgradeOptions.noDelete) { + Debug() << "Deleting message " << uid; + + KIMAP::StoreJob *store = new KIMAP::StoreJob( m_session ); + store->setUidBased( true ); + store->setSequenceSet( KIMAP::ImapSet(uid) ); + store->setFlags( QList<QByteArray>() << FlagDeleted ); + store->setMode( KIMAP::StoreJob::AppendFlags ); + seqJob->addSubjob(store); + } + } + } + } else { + Debug() << "Upgrading message"; + //TODO implement different target folder + KMime::Message::Ptr msg = Kolab::Upgrade::upgradeMessage(message, m_upgradeOptions); + //Skip messages that we're already kolabv3 + if (!msg.get()) { + Error() << "failed to convert message with uid " << QString::number(uids[number]); + continue; + } + seqJob->addSubjob(new MessageModifyJob(msg, mailBox, flags[number], uids[number], m_session, this)); } - seqJob->addSubjob(new MessageModifyJob(msg, mailBox, flags[number], uids[number], m_session, this)); } } @@ -122,11 +199,15 @@ emitResult(); return; } - + + if (m_upgradeOptions.validateMode) { + Debug() << "Finished validating the folder: " << m_folder; + } + //Run expunge after every modify, while the folder is still selected Q_ASSERT(m_session->state() & KIMAP::Session::Selected); seqJob->addSubjob(new KIMAP::ExpungeJob(m_session)); - + connect(seqJob, SIGNAL(finished(KJob*)), this, SLOT(onModifyFinished(KJob*))); seqJob->start(); }
View file
kolab-utils-3.1.2.tar.gz/upgradetool/kolabformatupgradejob.h -> kolab-utils-3.1.3.tar.gz/upgradetool/kolabformatupgradejob.h
Changed
@@ -37,6 +37,7 @@ public: explicit KolabFormatUpgradeJob(const QString &folder, KIMAP::Session *session, QObject* parent = 0); void setUpgradeOptions(const Kolab::Upgrade::UpgradeOptions &); + void setFolderType(const QString &); virtual void start(); private slots: void onSelectDone(KJob*); @@ -49,6 +50,7 @@ private: KIMAP::Session *m_session; QString m_folder; + QString m_folderType; SequentialCompositeJob *seqJob; Kolab::Upgrade::UpgradeOptions m_upgradeOptions; };
View file
kolab-utils-3.1.2.tar.gz/upgradetool/upgradetool.cpp -> kolab-utils-3.1.3.tar.gz/upgradetool/upgradetool.cpp
Changed
@@ -18,7 +18,10 @@ #include <QtCore/qcoreapplication.h> #include <QtCore/QStringList> #include <QtCore/qfile.h> +#include <QtCore/QDir> #include <kdebug.h> +#include <kglobal.h> +#include <kapplication.h> #include <kcmdlineargs.h> #include <errorhandler.h> @@ -60,9 +63,14 @@ // options.add("f").add options.add("fix-utc-incidences-offset <offset>", ki18n("Uses a UTC offset to convert the times. If not provided the local timezone get's used instead. The offset is in seconds."), "0"); options.add("fix-utc-incidences-timezone <timezone>", ki18n("Uses the specified timezone to convert the times. If not provided the local timezone get's used instead. Timezones are read from zone.tab")); + + options.add("validate", ki18n("Validate all kolab-objects and mails, and delete the ones that are invalid.")); + options.add("delete", ki18n("Delete invalid objects from the server. Applies to validate mode.")); + options.add("save-to <folder>", ki18n("Store invalid objects under the given path. Applies to validate mode.")); + options.add("+[server/file]", ki18n("IMAP Server/File")); KCmdLineArgs::addCmdLineOptions( options ); - QCoreApplication app(argc, argv); + KApplication app; KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); @@ -94,14 +102,37 @@ upgradeOptions.fixUtcIncidencesTimezone = KSystemTimeZones::readZone(args->getOption("fix-utc-incidences-timezone")); } upgradeOptions.overrideObjectType = overrideType; - QString folderToUpgrade; if (args->isSet("folder")) { folderToUpgrade = args->getOption("folder"); } - - if (!args->isSet("mime")) { + + if (args->isSet("validate")) { + kDebug() << "Running in validation mode."; + upgradeOptions.validateMode = true; + Q_ASSERT(upgradeOptions.validateMode); + } + if (!args->isSet("delete")) { + kDebug() << "Running in no-delete mode."; + upgradeOptions.noDelete = true; + } else { + kDebug() << "Running in delete mode."; + upgradeOptions.noDelete = false; + } + + if (args->isSet("save-to")) { + kDebug() << "Saving faulty messages to: " << args->getOption("save-to"); + upgradeOptions.saveTo = args->getOption("save-to"); + QDir dir; + if (!dir.mkpath(upgradeOptions.saveTo)) { + kWarning() << "Failed to create the given folder: " << upgradeOptions.saveTo; + return -1; + } + } + + const bool operatingOnMimeFile = args->isSet("mime"); + if (!operatingOnMimeFile) { if (args->count() == 0) { kWarning() << "specify imap server"; return -1; @@ -152,32 +183,31 @@ if (app.exec() || Kolab::ErrorHandler::instance().error() >= Kolab::ErrorHandler::Error) { return -1; } - return 0; - } - - QTextStream s(stdout); - s.setCodec( "UTF-8" ); - QTextStream stream(stdin); - stream.setCodec( "UTF-8" ); + } else { + QTextStream s(stdout); + s.setCodec( "UTF-8" ); + QTextStream stream(stdin); + stream.setCodec( "UTF-8" ); - if (args->isSet("mime")) { - if (args->count() > 0) { - const QString &filename = args->arg(0); - QFile file( filename ); - if (!file.open( QFile::ReadOnly )) { - kWarning() << "failed to open the file: " << filename; - return -1; - } - const QByteArray data = file.readAll(); - Q_ASSERT( !data.isEmpty() ); + if (operatingOnMimeFile) { + if (args->count() > 0) { + const QString &filename = args->arg(0); + QFile file( filename ); + if (!file.open( QFile::ReadOnly )) { + kWarning() << "failed to open the file: " << filename; + return -1; + } + const QByteArray data = file.readAll(); + Q_ASSERT( !data.isEmpty() ); - s << Kolab::Upgrade::upgradeMime(data, upgradeOptions); - } else { - s << Kolab::Upgrade::upgradeMime(stream.readAll().toUtf8(), upgradeOptions); + s << Kolab::Upgrade::upgradeMime(data, upgradeOptions); + } else { + s << Kolab::Upgrade::upgradeMime(stream.readAll().toUtf8(), upgradeOptions); + } + } + if (Kolab::ErrorHandler::instance().error() >= Kolab::ErrorHandler::Error) { + return -1; } - } - if (Kolab::ErrorHandler::instance().error() >= Kolab::ErrorHandler::Error) { - return -1; } return 0; }
View file
kolab-utils-3.1.2.tar.gz/upgradetool/upgradeutilities.cpp -> kolab-utils-3.1.3.tar.gz/upgradetool/upgradeutilities.cpp
Changed
@@ -46,6 +46,21 @@ } } +bool validateMessage(KMime::Message::Ptr msg, const QList<Kolab::ObjectType> &expectedType) +{ + Kolab::KolabObjectReader reader; + const Kolab::ObjectType type = reader.parseMimeMessage(msg); + if (Kolab::ErrorHandler::errorOccured()) { + Error() << "Error while parsing message."; + return false; + } + if (!expectedType.isEmpty() && !expectedType.contains(type)) { + Error() << "The object has the wrong type. Expected " << expectedType << " but got " << type; + return false; + } + return true; +} + KMime::Message::Ptr upgradeMessage(KMime::Message::Ptr msg, UpgradeOptions upgradeOptions) { Kolab::ObjectType overrideObjectType = upgradeOptions.overrideObjectType;
View file
kolab-utils-3.1.2.tar.gz/upgradetool/upgradeutilities.h -> kolab-utils-3.1.3.tar.gz/upgradetool/upgradeutilities.h
Changed
@@ -34,7 +34,9 @@ :overrideObjectType(Kolab::InvalidObject), fixUtcIncidences(false), fixUtcIncidencesWithOffset(false), - fixUtcIncidencesOffset(0) + fixUtcIncidencesOffset(0), + validateMode(false), + noDelete(false) { } @@ -44,12 +46,17 @@ bool fixUtcIncidencesWithOffset; int fixUtcIncidencesOffset; KTimeZone fixUtcIncidencesTimezone; + + bool validateMode; + bool noDelete; + QString saveTo; }; /** * Takes a v2 mime message and returns a v3 version */ KMime::Message::Ptr upgradeMessage(KMime::Message::Ptr msg, UpgradeOptions upgradeOptions = UpgradeOptions()); +bool validateMessage(KMime::Message::Ptr msg, const QList<Kolab::ObjectType> &expectedType); QString upgradeMime(const QByteArray &, UpgradeOptions upgradeOptions = UpgradeOptions());
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
.