/* * Copyright (c) 2012 Christian Mollekopf * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to the * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. */ #include "upgradejob.h" #include "kolabdefs.h" #include "kolabhandler.h" #include "collectionannotationsattribute.h" //from shared #include #include #include #include #include #define IMAP_COLLECTION "IMAP_COLLECTION" #define FOLDER_TYPE "FOLDER_TYPE" UpgradeJob::UpgradeJob( Kolab::Version targetVersion, const Akonadi::AgentInstance &instance, QObject *parent ) : Akonadi::Job( parent ), m_agentInstance( instance ), m_targetVersion( targetVersion ) { kDebug() << targetVersion; } void UpgradeJob::doStart() { kDebug(); //Get all subdirectories of kolab resource Akonadi::CollectionFetchJob *job = new Akonadi::CollectionFetchJob( Akonadi::Collection::root(), Akonadi::CollectionFetchJob::Recursive, this ); job->fetchScope().setResource( m_agentInstance.identifier() ); connect( job, SIGNAL(result(KJob*)), this, SLOT(collectionFetchResult(KJob*)) ); } void UpgradeJob::collectionFetchResult( KJob *job ) { kDebug(); if ( job->error() ) { kDebug() << job->errorString(); emitResult(); return; } int collCount = 0; Akonadi::Collection::List collections = static_cast( job )->collections(); foreach ( const Akonadi::Collection &col, collections ) { //FIXME: // find a way to properly detect shared folders. // Collection::CanCreateCollection never applies to shared folders, // but that's just a workaround. if ( !( col.rights() & Akonadi::Collection::CanCreateCollection ) || !( col.rights() & Akonadi::Collection::CanChangeItem ) ) { kDebug() << "skipping shared/non-editable folder"; continue; } KolabV2::FolderType folderType = KolabV2::Mail; Akonadi::CollectionAnnotationsAttribute *attr = 0; if ( ( attr = col.attribute() ) ) { folderType = KolabV2::folderTypeFromString( Kolab::getFolderTypeAnnotation( attr->annotations() ) ); } if ( folderType == KolabV2::Mail ) { //kWarning() << "Wrong folder annotation " // << "(this should never happen, the annotation is probably not available)"; continue; } kDebug() << "upgrading " << col.id(); collCount++; Akonadi::ItemFetchJob *itemFetchJob = new Akonadi::ItemFetchJob( col, this ); itemFetchJob->fetchScope().fetchFullPayload( true ); itemFetchJob->fetchScope().setCacheOnly( false ); itemFetchJob->setProperty( IMAP_COLLECTION, QVariant::fromValue( col ) ); itemFetchJob->setProperty( FOLDER_TYPE, QVariant::fromValue( static_cast(folderType) ) ); connect( itemFetchJob, SIGNAL(result(KJob*)), this, SLOT(itemFetchResult(KJob*)) ); } //Percent is only emitted when Bytes is the unit setTotalAmount( Bytes, collCount ); if ( !collCount ) { emitResult(); } } void UpgradeJob::itemFetchResult( KJob *job ) { if ( job->error() ) { kDebug() << job->errorString(); checkResult(); return; // Akonadi::Job propagates that automatically } Akonadi::ItemFetchJob *j = static_cast( job ); if ( j->items().isEmpty() ) { qWarning() << "no items fetched "; checkResult(); return; } const Akonadi::Collection imapCollection = j->property( IMAP_COLLECTION ).value(); if ( !imapCollection.isValid() ) { qWarning() << "invalid imap collection"; checkResult(); return; } KolabV2::FolderType folderType = static_cast( j->property(FOLDER_TYPE).toInt() ); KolabHandler::Ptr handler = KolabHandler::createHandler( folderType, imapCollection ); if ( !handler ) { qWarning() << "invalid handler"; checkResult(); return; } handler->setKolabFormatVersion( m_targetVersion ); foreach ( Akonadi::Item imapItem, j->items() ) { //krazy:exclude=foreach if ( !imapItem.isValid() ) { qWarning() << "invalid item"; continue; } kDebug() << "updating item " << imapItem.id(); const Akonadi::Item::List &translatedItems = handler->translateItems( Akonadi::Item::List() << imapItem ); if ( translatedItems.size() != 1 ) { qWarning() << "failed to translateItems" << translatedItems.size(); continue; } handler->toKolabFormat( translatedItems.first(), imapItem ); Akonadi::ItemModifyJob *modJob = new Akonadi::ItemModifyJob( imapItem, this ); connect( modJob, SIGNAL(result(KJob*)), this, SLOT(itemModifyResult(KJob*)) ); } checkResult(); } void UpgradeJob::checkResult() { setProcessedAmount( Bytes, processedAmount( Bytes ) + 1 ); if ( processedAmount( Bytes ) >= totalAmount( Bytes ) ) { emitResult(); } } void UpgradeJob::itemModifyResult( KJob *job ) { if ( job->error() ) { kDebug() << job->errorString(); return; // Akonadi::Job propagates that automatically } kDebug() << "modjob done"; }