Commit dada69fb authored by Volker Krause's avatar Volker Krause
Browse files

- provide some status information

- remove bridges that we replaced with native backends
- some cleanups

svn path=/trunk/KDE/kdepim/akonadi/; revision=847425
parent 90d01a99
......@@ -3,6 +3,7 @@ set(kres-migrator_srcs
kabcmigrator.cpp
kcalmigrator.cpp
kresmigratorbase.cpp
infodialog.cpp
)
kcfg_generate_dbus_interface(${CMAKE_SOURCE_DIR}/akonadi/resources/vcard/vcardresource.kcfg org.kde.Akonadi.VCard.Settings)
......
/*
Copyright (c) 2008 Volker Krause <vkrause@kde.org>
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 "infodialog.h"
#include <KGlobal>
#include <QListWidget>
InfoDialog::InfoDialog() :
mMigratorCount( 0 )
{
KGlobal::ref();
setButtons( Close );
enableButton( Close, false );
mList = new QListWidget( this );
mList->setMinimumWidth( 640 );
setMainWidget( mList );
connect( this, SIGNAL(closeClicked()), SLOT(deleteLater()) );
}
InfoDialog::~InfoDialog()
{
KGlobal::deref();
}
void InfoDialog::successMessage(const QString & msg)
{
new QListWidgetItem( KIcon( "dialog-ok" ), msg, mList );
}
void InfoDialog::infoMessage(const QString & msg)
{
new QListWidgetItem( KIcon( "dialog-information" ), msg, mList );
}
void InfoDialog::errorMessage(const QString & msg)
{
new QListWidgetItem( KIcon( "dialog-errror" ), msg, mList );
}
void InfoDialog::migratorAdded()
{
++mMigratorCount;
}
void InfoDialog::migratorDone()
{
--mMigratorCount;
if ( mMigratorCount == 0 )
enableButton( Close, true );
}
/*
Copyright (c) 2008 Volker Krause <vkrause@kde.org>
This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
*/
#ifndef INFODIALOG_H
#define INFODIALOG_H
#include <KDialog>
class QListWidget;
class InfoDialog : public KDialog
{
Q_OBJECT
public:
InfoDialog();
~InfoDialog();
public slots:
void successMessage( const QString &msg );
void infoMessage( const QString &msg );
void errorMessage( const QString &msg );
void migratorAdded();
void migratorDone();
private:
QListWidget *mList;
int mMigratorCount;
};
#endif
......@@ -32,19 +32,18 @@
using namespace Akonadi;
KABCMigrator::KABCMigrator() :
KResMigrator<KABC::Resource>( "contact" )
KResMigrator<KABC::Resource>( "contact", "akonadi_kabc_resource" )
{
}
void KABCMigrator::migrateResource( KABC::Resource* res)
bool KABCMigrator::migrateResource( KABC::Resource* res)
{
kDebug() << res->identifier() << res->type();
if ( res->type() == "file" && !mBridgeOnly )
if ( res->type() == "file" )
migrateFileResource( res );
else if ( migrationState( res ) == None )
migrateToBridge( res, "akonadi_kabc_resource" );
else
migrateNext();
return false;
return true;
}
void KABCMigrator::migrateFileResource(KABC::Resource * res)
......@@ -61,7 +60,6 @@ void KABCMigrator::migrateFileResource(KABC::Resource * res)
}
AgentInstanceCreateJob *job = new AgentInstanceCreateJob( type, this );
connect( job, SIGNAL(result(KJob*)), SLOT(fileResourceCreated(KJob*)) );
setResourceForJob( job, res );
job->start();
}
......@@ -71,7 +69,7 @@ void KABCMigrator::fileResourceCreated(KJob * job)
kDebug() << "Failed to create vcard resource!";
return;
}
KABC::Resource *res = resourceForJob( job );
KABC::Resource *res = currentResource();
AgentInstance instance = static_cast<AgentInstanceCreateJob*>( job )->instance();
const KConfigGroup kresCfg = kresConfig( res );
instance.setName( kresCfg.readEntry( "ResourceName", "Migrated Addressbook" ) );
......@@ -85,8 +83,7 @@ void KABCMigrator::fileResourceCreated(KJob * job)
iface->setPath( kresCfg.readPathEntry( "FileName", "" ) );
iface->setReadOnly( res->readOnly() );
instance.reconfigure();
setMigrationState( res, Complete, instance.identifier() );
migrateNext();
migrationCompleted( instance );
}
#include "kabcmigrator.moc"
......@@ -37,7 +37,7 @@ class KABCMigrator : public KResMigrator<KABC::Resource>
public:
KABCMigrator();
void migrateResource( KABC::Resource *res );
bool migrateResource( KABC::Resource *res );
private slots:
void fileResourceCreated( KJob* job );
......
......@@ -32,19 +32,18 @@
using namespace Akonadi;
KCalMigrator::KCalMigrator() :
KResMigrator<KCal::ResourceCalendar>( "calendar" )
KResMigrator<KCal::ResourceCalendar>( "calendar", "akonadi_kcal_resource" )
{
}
void KCalMigrator::migrateResource( KCal::ResourceCalendar* res)
bool KCalMigrator::migrateResource( KCal::ResourceCalendar* res)
{
kDebug() << res->identifier() << res->type();
if ( res->type() == "file" && !mBridgeOnly )
if ( res->type() == "file" )
migrateFileResource( res );
else if ( migrationState( res ) == None )
migrateToBridge( res, "akonadi_kcal_resource" );
else
migrateNext();
return false;
return true;
}
void KCalMigrator::migrateFileResource(KCal::ResourceCalendar * res)
......@@ -61,7 +60,6 @@ void KCalMigrator::migrateFileResource(KCal::ResourceCalendar * res)
}
AgentInstanceCreateJob *job = new AgentInstanceCreateJob( type, this );
connect( job, SIGNAL(result(KJob*)), SLOT(fileResourceCreated(KJob*)) );
setResourceForJob( job, res );
job->start();
}
......@@ -71,7 +69,7 @@ void KCalMigrator::fileResourceCreated(KJob * job)
kDebug() << "Failed to create ical resource!";
return;
}
KCal::ResourceCalendar *res = resourceForJob( job );
KCal::ResourceCalendar *res = currentResource();
AgentInstance instance = static_cast<AgentInstanceCreateJob*>( job )->instance();
const KConfigGroup kresCfg = kresConfig( res );
instance.setName( kresCfg.readEntry( "ResourceName", "Migrated Calendar" ) );
......@@ -86,8 +84,7 @@ void KCalMigrator::fileResourceCreated(KJob * job)
iface->setPath( kresCfg.readPathEntry( "CalendarURL", "" ) );
iface->setReadOnly( res->readOnly() );
instance.reconfigure();
setMigrationState( res, Complete, instance.identifier() );
migrateNext();
migrationCompleted( instance );
}
#include "kcalmigrator.moc"
......@@ -37,7 +37,7 @@ class KCalMigrator : public KResMigrator<KCal::ResourceCalendar>
public:
KCalMigrator();
void migrateResource( KCal::ResourceCalendar *res );
bool migrateResource( KCal::ResourceCalendar *res );
private slots:
void fileResourceCreated( KJob* job );
......
......@@ -33,8 +33,8 @@
template <typename T> class KResMigrator : public KResMigratorBase
{
public:
KResMigrator( const QString &type ) :
KResMigratorBase( type ),
KResMigrator( const QString &type, const QString &bridgeType ) :
KResMigratorBase( type, bridgeType ),
mConfig( 0 ),
mManager( 0 ),
mBridgeManager( 0 )
......@@ -62,14 +62,22 @@ template <typename T> class KResMigrator : public KResMigratorBase
while ( mIt != mManager->end() ) {
KConfigGroup cfg( KGlobal::config(), "Resource " + (*mIt)->identifier() );
if ( migrationState( *mIt ) == None ) {
emit infoMessage( i18n( "Trying to migrate '%1'...", (*mIt)->resourceName() ) );
mPendingBridgedResources.removeAll( (*mIt)->identifier() );
T* res = *mIt;
mCurrentKResource = res;
++mIt;
migrateResource( res );
bool nativeAvailable = mBridgeOnly ? false : migrateResource( res );
if ( !nativeAvailable ) {
emit infoMessage( i18n( "No native backend for '%1' available.", res->resourceName() ) );
migrateToBridge( res, mBridgeType );
}
return;
}
if ( migrationState( *mIt ) == Bridged && !mPendingBridgedResources.contains( (*mIt)->identifier() ) )
mPendingBridgedResources << (*mIt)->identifier();
if ( migrationState( *mIt ) == Complete )
emit successMessage( i18n( "'%1' has already been migrated.", (*mIt)->resourceName() ) );
++mIt;
}
if ( mIt == mManager->end() ) {
......@@ -110,22 +118,27 @@ template <typename T> class KResMigrator : public KResMigratorBase
}
T *res = mBridgeManager->standardResource();
migrateResource( res );
emit infoMessage( i18n( "Trying to migrate '%1' from compatibility bridge to native backend...", res->resourceName() ) );
mCurrentKResource = res;
bool nativeAvailable = migrateResource( res );
if ( !nativeAvailable ) {
emit successMessage( i18n( "No native backend avaiable, keeping compatibility bridge for '%1'", res->resourceName() ) );
migrateNext();
}
}
virtual void migrateResource( T *res ) = 0;
virtual bool migrateResource( T *res ) = 0;
KConfigGroup kresConfig( KRES::Resource* res ) const
{
return KConfigGroup( mConfig, "Resource_" + res->identifier() );
}
T* resourceForJob( KJob *job )
T* currentResource()
{
if ( mJobResMap.contains( job ) )
return static_cast<T*>( mJobResMap.value( job ) );
Q_ASSERT( false );
return 0;
T* res = dynamic_cast<T*>( mCurrentKResource );
Q_ASSERT( res );
return res;
}
private:
......
......@@ -36,8 +36,10 @@
using namespace Akonadi;
KResMigratorBase::KResMigratorBase(const QString & type) :
mType( type )
KResMigratorBase::KResMigratorBase(const QString & type, const QString &bridgeType) :
mType( type ),
mBridgeType( bridgeType ),
mCurrentKResource( 0 )
{
KGlobal::ref();
......@@ -91,11 +93,6 @@ void KResMigratorBase::setMigrationState( KRES::Resource * res, MigrationState s
cfg.sync();
}
void KResMigratorBase::setResourceForJob(KJob * job, KRES::Resource * res)
{
mJobResMap.insert( job, res );
}
void KResMigratorBase::migrateToBridge( KRES::Resource *res, const QString & typeId)
{
kDebug() << res->type() << res->identifier() << typeId;
......@@ -105,6 +102,7 @@ void KResMigratorBase::migrateToBridge( KRES::Resource *res, const QString & typ
return;
}
emit infoMessage( i18n( "Trying to migragte '%1' to compatibility bridge...", res->resourceName() ) );
const AgentType type = AgentManager::self()->type( typeId );
if ( !type.isValid() ) {
kDebug() << "Unable to obtain kabc bridge resource type!" << typeId;
......@@ -112,7 +110,6 @@ void KResMigratorBase::migrateToBridge( KRES::Resource *res, const QString & typ
}
AgentInstanceCreateJob *job = new AgentInstanceCreateJob( type, this );
connect( job, SIGNAL(result(KJob*)), SLOT(resourceBridgeCreated(KJob*)) );
setResourceForJob( job, res );
job->start();
}
......@@ -124,7 +121,7 @@ void KResMigratorBase::resourceBridgeCreated(KJob * job)
migrateNext();
return;
}
KRES::Resource *res = mJobResMap.value( job );
KRES::Resource *res = mCurrentKResource;
Q_ASSERT( res );
AgentInstance instance = static_cast<AgentInstanceCreateJob*>( job )->instance();
const KConfigGroup kresCfg = kresConfig( res );
......@@ -145,9 +142,7 @@ void KResMigratorBase::resourceBridgeCreated(KJob * job)
delete akoResConfig;
instance.reconfigure();
setMigrationState( res, Bridged, instance.identifier() );
migrateNext();
migratedToBridge( instance );
}
void KResMigratorBase::setBridgingOnly(bool b)
......@@ -155,4 +150,38 @@ void KResMigratorBase::setBridgingOnly(bool b)
mBridgeOnly = b;
}
void KResMigratorBase::migrationCompleted( const Akonadi::AgentInstance &instance )
{
// check if this one was previously bridged and remove the bridge
KConfigGroup cfg( KGlobal::config(), "Resource " + mCurrentKResource->identifier() );
const QString bridgeId = cfg.readEntry( "ResourceIdentifier", "" );
if ( bridgeId != instance.identifier() ) {
const AgentInstance bridge = AgentManager::self()->instance( bridgeId );
AgentManager::self()->removeInstance( bridge );
}
setMigrationState( mCurrentKResource, Complete, instance.identifier() );
emit successMessage( i18n( "Migration of '%1' succeeded.", mCurrentKResource->resourceName() ) );
mCurrentKResource = 0;
migrateNext();
}
void KResMigratorBase::migratedToBridge(const Akonadi::AgentInstance & instance)
{
setMigrationState( mCurrentKResource, Bridged, instance.identifier() );
emit successMessage( i18n( "Migration of '%1' to compatibility bridge succeeded.", mCurrentKResource->resourceName() ) );
mCurrentKResource = 0;
migrateNext();
}
void KResMigratorBase::migrationFailed(const QString & errorMsg, const Akonadi::AgentInstance & instance)
{
emit errorMessage( i18n( "Migration of '%1' failed: %2", mCurrentKResource->resourceName(), errorMsg ) );
if ( instance.isValid() ) {
AgentManager::self()->removeInstance( instance );
}
mCurrentKResource = 0;
migrateNext();
}
#include "kresmigratorbase.moc"
......@@ -20,9 +20,10 @@
#ifndef KRESMIGRATORBASE_H
#define KRESMIGRATORBASE_H
#include <akonadi/agentinstance.h>
#include <KConfigGroup>
#include <QHash>
#include <QObject>
namespace KRES {
......@@ -47,13 +48,10 @@ class KResMigratorBase : public QObject
Q_ENUMS( MigrationState )
KResMigratorBase( const QString &type );
KResMigratorBase( const QString &type, const QString &bridgeType );
~KResMigratorBase();
MigrationState migrationState( KRES::Resource *res ) const;
void setMigrationState( KRES::Resource *res, MigrationState state, const QString &resId );
void setResourceForJob( KJob* job, KRES::Resource *res );
virtual void migrateNext() = 0;
void migrateToBridge( KRES::Resource* res, const QString &typeId );
......@@ -62,14 +60,27 @@ class KResMigratorBase : public QObject
void setBridgingOnly( bool b );
void migrationCompleted( const Akonadi::AgentInstance &instance );
void migratedToBridge( const Akonadi::AgentInstance &instance );
void migrationFailed( const QString &errorMsg, const Akonadi::AgentInstance &instance = Akonadi::AgentInstance() );
signals:
void successMessage( const QString &msg );
void infoMessage( const QString &msg );
void errorMessage( const QString &msg );
protected slots:
virtual void migrate() = 0;
protected:
QString mType;
QHash<KJob*, KRES::Resource*> mJobResMap;
QString mBridgeType;
QStringList mPendingBridgedResources;
bool mBridgeOnly;
KRES::Resource *mCurrentKResource;
private:
void setMigrationState( KRES::Resource *res, MigrationState state, const QString &resId );
private slots:
void resourceBridgeCreated( KJob *job );
......
......@@ -19,6 +19,7 @@
#include "kabcmigrator.h"
#include "kcalmigrator.h"
#include "infodialog.h"
#include <akonadi/control.h>
......@@ -27,6 +28,17 @@
#include <kcmdlineargs.h>
#include <kglobal.h>
void connectMigrator( KResMigratorBase *m, InfoDialog *dlg )
{
if ( !dlg || !m )
return;
dlg->migratorAdded();
QObject::connect( m, SIGNAL(successMessage(QString)), dlg, SLOT(successMessage(QString)) );
QObject::connect( m, SIGNAL(infoMessage(QString)), dlg, SLOT(infoMessage(QString)) );
QObject::connect( m, SIGNAL(errorMessage(QString)), dlg, SLOT(errorMessage(QString)) );
QObject::connect( m, SIGNAL(destroyed()), dlg, SLOT(migratorDone()) );
}
int main( int argc, char **argv )
{
KAboutData aboutData( "kres-migrator", 0,
......@@ -45,6 +57,7 @@ int main( int argc, char **argv )
options.add( "bridge-only", ki18n("Only migrate to Akonadi KResource bridges") );
options.add( "contacts-only", ki18n("Only migrate contact resources") );
options.add( "calendar-only", ki18n("Only migrate calendar resources") );
options.add( "interactive", ki18n( "Do not show reporting dialog") );
KCmdLineArgs::addCmdLineOptions( options );
KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
......@@ -55,13 +68,21 @@ int main( int argc, char **argv )
Akonadi::Control::start();
InfoDialog *infoDialog = 0;
if ( args->isSet( "interactive" ) ) {
infoDialog = new InfoDialog();
infoDialog->show();
}
if ( !args->isSet( "calendar-only" ) ) {
KABCMigrator *m = new KABCMigrator();
m->setBridgingOnly( args->isSet( "bridge-only" ) );
connectMigrator( m, infoDialog );
}
if ( !args->isSet( "contacts-only" ) ) {
KCalMigrator *m = new KCalMigrator();
m->setBridgingOnly( args->isSet( "bridge-only" ) );
connectMigrator( m, infoDialog );
}
return app.exec();
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment