kitchensync

socket.cpp

00001 /*
00002     This file is part of KitchenSync.
00003 
00004     Copyright (c) 2002,2003 Holger Freyther <freyther@kde.org>
00005 
00006     This library is free software; you can redistribute it and/or
00007     modify it under the terms of the GNU Library General Public
00008     License as published by the Free Software Foundation; either
00009     version 2 of the License, or (at your option) any later version.
00010 
00011     This library is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014     Library General Public License for more details.
00015 
00016     You should have received a copy of the GNU Library General Public License
00017     along with this library; see the file COPYING.LIB.  If not, write to
00018     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00019     Boston, MA 02110-1301, USA.
00020 */
00021 
00022 #include <qsocket.h>
00023 #include <qdir.h>
00024 #include <qtimer.h>
00025 
00026 #include <kdebug.h>
00027 #include <klocale.h>
00028 #include <kio/netaccess.h>
00029 #include <libkcal/calendarlocal.h>
00030 #include <libkdepim/kpimprefs.h>
00031 #include <libkdepim/progressmanager.h>
00032 
00033 #include <addressbooksyncee.h>
00034 #include <calendarsyncee.h>
00035 #include <unknownsyncee.h>
00036 
00037 #include <idhelper.h>
00038 
00039 #include "device.h"
00040 #include "desktop.h"
00041 #include "datebook.h"
00042 #include "addressbook.h"
00043 
00044 #include "metaaddressbook.h"
00045 #include "metacalendar.h"
00046 
00047 #include "todo.h"
00048 
00049 #include "socket.h"
00050 
00051 using namespace KSync;
00052 
00053 namespace {
00054     void outputIt( int area, Syncee* );
00055 }
00056 
00057 class QtopiaSocket::Private
00058 {
00059   public:
00060     enum CallIt
00061     {
00062         NotStarted = 0,
00063         Handshake  = 0,
00064         ABook,
00065         Todo,
00066         Calendar,
00067         Transactions,
00068         Files,
00069         Desktops,
00070         Flush
00071     };
00072 
00073     enum Status {
00074         Start = 0,
00075         User,
00076         Pass,
00077         Call,
00078         Noop,
00079         Done,
00080         Connected
00081     };
00082 
00083     Private(){}
00084 
00085     bool connected    : 1;
00086     bool startSync    : 1;
00087     bool isSyncing    : 1;
00088     bool isConnecting : 1;
00089     bool first        : 1;
00090     QString src;
00091     QString dest;
00092     QSocket* socket;
00093     QTimer* timer;
00094     QString path;
00095     QString storagePath;
00096     int mode;
00097     int getMode;
00098     SynceeList m_sync;
00099 
00100     QValueList<OpieCategories> categories;
00101     QString partnerId;
00102     QStringList files;
00103     QString tz;
00104     OpieHelper::CategoryEdit* edit;
00105     KonnectorUIDHelper* helper;
00106     OpieHelper::Device* device;
00107     OpieHelper::ExtraMap extras;
00108 };
00109 
00110 namespace {
00111     void parseTZ( const QString& fileName,  QString& tz );
00112 }
00113 
00119 QtopiaSocket::QtopiaSocket( QObject* obj, const char* name )
00120     : QObject( obj, name )
00121 {
00122     d = new Private;
00123     d->socket = 0;
00124     d->timer  = 0;
00125     d->connected    = false;
00126     d->startSync    = false;
00127     d->isSyncing    = false;
00128     d->isConnecting = false;
00129     d->helper  = 0;
00130     d->edit    = 0;
00131     d->first   = false;
00132     d->device = new OpieHelper::Device;
00133     m_flushedApps = 0;
00134 }
00135 
00136 QtopiaSocket::~QtopiaSocket()
00137 {
00138     delete d->device;
00139     delete d;
00140 }
00141 
00142 QString QtopiaSocket::storagePath()const
00143 {
00144   return d->storagePath;
00145 }
00146 
00147 void QtopiaSocket::setStoragePath( const QString& str )
00148 {
00149   d->storagePath = str;
00150 }
00151 
00152 
00153 void QtopiaSocket::setUser( const QString& user )
00154 {
00155     d->device->setUser( user );
00156 }
00157 
00158 void QtopiaSocket::setPassword( const QString& pass )
00159 {
00160     d->device->setPassword( pass );
00161 }
00162 
00163 void QtopiaSocket::setSrcIP( const QString& src)
00164 {
00165     d->src = src;
00166 }
00167 
00168 void QtopiaSocket::setDestIP( const QString& dest)
00169 {
00170     d->dest = dest;
00171 }
00172 
00173 void QtopiaSocket::setModel( const QString& model, const QString& name )
00174 {
00175     if( model == QString::fromLatin1("Sharp Zaurus ROM") ){
00176     d->device->setDistribution( OpieHelper::Device::Zaurus );
00177     }else
00178     d->device->setDistribution( OpieHelper::Device::Opie );
00179 
00180     d->device->setMeta( name );
00181 }
00182 
00183 void QtopiaSocket::startUp()
00184 {
00185   mProgressItem = KPIM::ProgressManager::instance()->createProgressItem(
00186       KPIM::ProgressManager::getUniqueID(), i18n( "Connecting" ) );
00187 
00188     delete d->socket;
00189     d->socket = new QSocket(this, "Qtopia Socket" );
00190 
00191     /* now connect to some slots */
00192     connect(d->socket, SIGNAL(error(int) ),
00193             this, SLOT(slotError(int) ) );
00194     connect(d->socket, SIGNAL(connected() ),
00195             this, SLOT(slotConnected() ) );
00196     connect(d->socket, SIGNAL(connectionClosed() ),
00197             this, SLOT(slotClosed() ) );
00198     connect(d->socket, SIGNAL(readyRead() ),
00199             this, SLOT(process() ) );
00200 
00201     d->connected    = false;
00202     d->startSync    = false;
00203     d->isConnecting = true;
00204 
00205     d->categories.clear();
00206     d->isSyncing = false;
00207     d->socket->connectToHost(d->dest, 4243 );
00208 }
00209 
00210 void QtopiaSocket::hangUp()
00211 {
00212     if (d->isSyncing ) {
00213 //        emit error( Error(Error::CouldNotDisconnect, i18n("Can not disconnect now. Try again after syncing was finished") ) );
00214         return;
00215     }
00216 
00217     disconnect(d->socket, SIGNAL(error(int) ),
00218             this, SLOT(slotError(int) ) );
00219     disconnect(d->socket, SIGNAL(connected() ),
00220             this, SLOT(slotConnected() ) );
00221     disconnect(d->socket, SIGNAL(connectionClosed() ),
00222             this, SLOT(slotClosed() ) );
00223     disconnect(d->socket, SIGNAL(readyRead() ),
00224             this, SLOT(process() ) );
00225 
00226     d->socket->close();
00227     d->isSyncing = false;
00228     d->connected = false;
00229     d->startSync = false;
00230     d->isConnecting = false;
00231     d->categories.clear();
00232     d->getMode = d->NotStarted;
00233     d->mode = d->Start;
00234 //    emit prog( Progress(i18n("Disconnected from the device.") ) );
00235   mProgressItem->setComplete();
00236 }
00237 
00238 void QtopiaSocket::setResources( const QStringList& list )
00239 {
00240     d->files = list;
00241 }
00242 
00243 bool QtopiaSocket::startSync()
00244 {
00245     if ( d->isSyncing )
00246       return false;
00247     d->isSyncing = true;
00248     d->getMode   = d->NotStarted;
00249 
00250     if (d->isConnecting ) {
00251       d->startSync = true;
00252       return true;
00253     }
00254 
00255     if (!isConnected() ) {
00256       startUp();
00257       d->startSync = true;
00258       return true;
00259     }
00260 
00261     slotStartSync();
00262 
00263     return true;
00264 }
00265 
00266 /*
00267  * check if we're connected
00268  */
00269 bool QtopiaSocket::isConnected()
00270 {
00271     if ( d->connected || d->mode == d->Call || d->mode  == d->Noop || d->mode == d->Connected )
00272         return true;
00273     else
00274         return false;
00275 }
00276 
00277 void QtopiaSocket::write( SynceeList list )
00278 {
00279     if (!isConnected() ) {
00280 //        emit error( Error( i18n("<qt>Can not write the data back.\n There is no connection to the device") ) );
00281 //        emit prog( StdProgress::done() );
00282         return;
00283     }
00284 
00285 
00286     AddressBookSyncee *abSyncee = list.addressBookSyncee();
00287     if ( abSyncee ) writeAddressbook( abSyncee );
00288 
00289     CalendarSyncee *calSyncee = list.calendarSyncee();
00290     if ( calSyncee ) {
00291       writeDatebook( calSyncee );
00292       writeTodoList( calSyncee );
00293 
00294       /*
00295        * Now write the common meta information for
00296        * todo/event as they're shared
00297        */
00298       OpieHelper::MetaCalendar  metaBook(calSyncee, storagePath() + "/" + d->partnerId + "/calendar_todolist.md5.qtopia" );
00299       metaBook.save();
00300     }
00301 
00302 
00303     /*
00304      * write new category information
00305      */
00306     writeCategory();
00307     d->helper->save();
00308 
00309     /*
00310      * Upload custom files
00311      */
00312     KSync::UnknownSyncee *unk = list.unknownSyncee();
00313     if ( unk )
00314       writeUnknown( unk );
00315 
00316     /* trigger reload for apps on pda */
00317     sendCommand( "call QPE/Application/datebook reload()" );
00318     sendCommand( "call QPE/Application/addressbook reload()" );
00319     sendCommand( "call QPE/Application/todolist reload()" );
00320 
00321     /*
00322      * tell Opie/Qtopia that we're ready
00323      */
00324     sendCommand( "call QPE/System stopSync()" );
00325     d->isSyncing = false;
00326 
00327     /*
00328      * now we need that it's not first sync
00329      */
00330     d->first = false;
00331 //    emit prog(StdProgress::done() );
00332 
00333     /*
00334      * Delete the Syncee
00335      */
00336 //    list.deleteAndClear();
00337 }
00338 
00339 QString QtopiaSocket::metaId() const
00340 {
00341     return d->partnerId;
00342 }
00343 
00344 void QtopiaSocket::slotError( int )
00345 {
00346   mProgressItem->setStatus( i18n( "Error during connect" ) );
00347     d->isSyncing = false;
00348     d->isConnecting = false;
00349 
00350 //    emit error( StdError::connectionLost() );
00351 }
00352 
00353 void QtopiaSocket::slotConnected()
00354 {
00355   mProgressItem->setStatus( i18n( "Connected" ) );
00356     d->connected = true;
00357     delete d->timer;
00358     d->mode = d->Start;
00359 }
00360 
00361 void QtopiaSocket::slotClosed()
00362 {
00363   mProgressItem->setStatus( i18n( "Connecting closed" ) );
00364     d->connected    = false;
00365     d->isConnecting = false;
00366     d->isSyncing    = false;
00367 //    emit error( StdError::connectionLost() );
00368 }
00369 
00370 void QtopiaSocket::slotNOOP()
00371 {
00372     if (!d->socket ) return;
00373     sendCommand( "NOOP" );
00374 }
00375 
00376 void QtopiaSocket::process()
00377 {
00378   // it can happen that the socket emitted a signal before we deleted it
00379   if ( d->socket == 0 )
00380     return;
00381 
00382   while ( d->socket->canReadLine() ) {
00383     QTextStream stream( d->socket );
00384     QString line = d->socket->readLine();
00385     switch( d->mode ) {
00386       case QtopiaSocket::Private::Start:
00387         start(line);
00388         break;
00389       case QtopiaSocket::Private::User:
00390         user(line);
00391         break;
00392       case QtopiaSocket::Private::Pass:
00393         pass(line);
00394         break;
00395       case QtopiaSocket::Private::Call:
00396         call(line);
00397         break;
00398       case QtopiaSocket::Private::Noop:
00399         noop(line);
00400         break;
00401       default:
00402         break;
00403     }
00404   }
00405 }
00406 
00407 void QtopiaSocket::slotStartSync()
00408 {
00409 //    emit prog( Progress( i18n("Starting to sync now") ) );
00410     d->startSync = false;
00411     sendCommand( "call QPE/System sendHandshakeInfo()" );
00412     d->getMode = d->Handshake;
00413     d->mode = d->Call;
00414 }
00415 
00416 KURL QtopiaSocket::url( Type t )
00417 {
00418     QString uri;
00419     uri = d->path + "/Applications/";
00420     switch( t ) {
00421     case AddressBook:
00422         uri += "addressbook/addressbook.xml";
00423         break;
00424     case TodoList:
00425         uri += "todolist/todolist.xml";
00426         break;
00427     case DateBook:
00428         uri += "datebook/datebook.xml";
00429         break;
00430     }
00431     return url( uri );
00432 }
00433 
00434 KURL QtopiaSocket::url( const QString& path )
00435 {
00436     KURL url;
00437     url.setProtocol("ftp" );
00438     url.setUser( d->device->user() );
00439     url.setPass( d->device->password() );
00440     url.setHost( d->dest );
00441     url.setPort( 4242 );
00442     url.setPath( path );
00443 
00444     return url;
00445 }
00446 
00447 /*
00448  * write the categories file
00449  */
00450 void QtopiaSocket::writeCategory()
00451 {
00452     QString fileName = QDir::homeDirPath() + "/.kitchensync/meta/" +d->partnerId + "/categories.xml";
00453     d->edit->save( fileName );
00454     KURL uri = url(  d->path + "/Settings/Categories.xml" );
00455     KIO::NetAccess::upload( fileName,  uri, 0 );
00456 }
00457 
00458 void QtopiaSocket::writeAddressbook( AddressBookSyncee* syncee )
00459 {
00460 //    emit prog(Progress(i18n("Writing AddressBook back to the device") ) );
00461     OpieHelper::AddressBook abDB(d->edit, d->helper, d->tz, d->device );
00462     KTempFile* file = abDB.fromKDE( syncee, d->extras );
00463     KURL uri = url( AddressBook );
00464 
00465     KIO::NetAccess::upload( file->name(), uri, 0 );
00466     file->unlink();
00467     delete file;
00468 
00469 
00470     OpieHelper::MetaAddressbook metaBook( syncee, storagePath() + "/" + d->partnerId + "/contacts.md5.qtopia" );
00471     metaBook.save();
00472 }
00473 
00474 void QtopiaSocket::writeDatebook( CalendarSyncee* syncee )
00475 {
00476     OpieHelper::DateBook dbDB(d->edit, d->helper, d->tz, d->device );
00477     KTempFile* file = dbDB.fromKDE( syncee, d->extras );
00478     KURL uri = url( DateBook );
00479 
00480     KIO::NetAccess::upload( file->name(), uri, 0 );
00481     file->unlink();
00482     delete file;
00483 
00484     /*
00485      * The SyncHistory is saved after both datebook and todo
00486      * was written
00487      */
00488 }
00489 
00490 void QtopiaSocket::writeTodoList( CalendarSyncee* syncee)
00491 {
00492     OpieHelper::ToDo toDB(d->edit, d->helper, d->tz, d->device );
00493     KTempFile* file = toDB.fromKDE( syncee, d->extras );
00494     KURL uri = url( TodoList );
00495 
00496     KIO::NetAccess::upload( file->name(), uri, 0 );
00497     file->unlink();
00498     delete file;
00499 
00500     /*
00501      * The SyncHistory is saved after both datebook and todo
00502      * was written
00503      */
00504 }
00505 
00506 void QtopiaSocket::writeUnknown( KSync::UnknownSyncee *syncee )
00507 {
00508   for ( KSync::UnknownSyncEntry* entry = syncee->firstEntry();
00509         entry; entry = syncee->nextEntry() ) {
00510     QString baseName = QFileInfo( entry->fileName() ).fileName();
00511     KIO::NetAccess::upload(entry->fileName(),
00512                            url(d->path+"/"+baseName), 0 );
00513   }
00514 }
00515 
00516 void QtopiaSocket::readAddressbook()
00517 {
00518     KSync::AddressBookSyncee* syncee = 0;
00519 //    emit prog( StdProgress::downloading(i18n("Addressbook") ) );
00520     QString tempfile;
00521 
00522     if (!downloadFile( "/Applications/addressbook/addressbook.xml", tempfile ) ) {
00523 //        emit error( StdError::downloadError(i18n("Addressbook") ) );
00524         syncee = new KSync::AddressBookSyncee;
00525         tempfile = QString::null;
00526     }
00527 
00528 //    emit prog( StdProgress::converting(i18n("Addressbook") ) );
00529 
00530     if (!syncee) {
00531         OpieHelper::AddressBook abDB( d->edit, d->helper, d->tz, d->device );
00532         syncee = abDB.toKDE( tempfile, d->extras );
00533         syncee->setMerger( d->device ? d->device->merger( OpieHelper::Device::Addressbook ) : 0l );
00534     }
00535 
00536     if (!syncee ) {
00537         KIO::NetAccess::removeTempFile( tempfile );
00538 //         emit error( i18n("Cannot read the addressbook file. It is corrupted.") );
00539         return;
00540     }
00541 
00542 
00543     /*
00544      * If in meta mode but not the first syncee
00545      * collect some meta infos
00546      */
00547 //    emit prog( Progress(i18n("Collecting the changes now") ) );
00548 
00549     OpieHelper::MetaAddressbook metaBook( syncee, storagePath() + "/" + d->partnerId + "/contacts.md5.qtopia" );
00550     metaBook.load();
00551 
00552     d->m_sync.append( syncee );
00553 
00554     if (!tempfile.isEmpty() )
00555         KIO::NetAccess::removeTempFile( tempfile );
00556 }
00557 
00558 CalendarSyncee *QtopiaSocket::defaultCalendarSyncee()
00559 {
00560   CalendarSyncee* syncee = d->m_sync.calendarSyncee();
00561   if ( syncee == 0 ) {
00562     syncee = new KSync::CalendarSyncee( new KCal::CalendarLocal(KPimPrefs::timezone()) );
00563 
00564     /* if we've a device lets set the merger */
00565     syncee->setMerger( d->device ? d->device->merger( OpieHelper::Device::Calendar ) : 0);
00566 
00567     /*  Set title */
00568     syncee->setTitle( i18n("Opie") );
00569     syncee->setIdentifier( "Opie Todolist and Datebook" );
00570   }
00571 
00572   return syncee;
00573 }
00574 
00575 void QtopiaSocket::readDatebook()
00576 {
00577     KSync::CalendarSyncee* syncee = defaultCalendarSyncee();
00578 //    emit prog( StdProgress::downloading(i18n("Datebook") ) );
00579     QString tempfile;
00580 
00581     bool ok = downloadFile( "/Applications/datebook/datebook.xml", tempfile );
00582     if ( !ok ) {
00583 //      emit error( StdError::downloadError(i18n("Datebook") ) );
00584       tempfile = QString::null;
00585     }
00586 //    emit prog( StdProgress::converting(i18n("Datebook") ) );
00587 
00588     /* the datebook.xml might not exist in this case we created an empty Entry
00589      * and there is no need to parse a non existint file
00590      */
00591     if ( ok ) {
00592       OpieHelper::DateBook dateDB( d->edit, d->helper, d->tz, d->device );
00593       ok = dateDB.toKDE( tempfile, d->extras, syncee );
00594     }
00595 
00596     if ( !ok ) {
00597         KIO::NetAccess::removeTempFile( tempfile );
00598 //        emit error( i18n("Cannot read the datebook file. It is corrupted.") );
00599         return;
00600     }
00601 
00602     /*
00603      * for meta mode get meta info
00604      */
00605 //    emit prog( StdProgress::converting(i18n("Datebook") ) );
00606 
00607     /*
00608      * SyncHistory applying is done after both calendar and todo
00609      * are read and before emitting the records
00610      * in download() for now
00611      */
00612 
00613     if ( d->m_sync.find( syncee ) == d->m_sync.end() )
00614       d->m_sync.append( syncee );
00615 
00616     if (!tempfile.isEmpty() )
00617         KIO::NetAccess::removeTempFile( tempfile );
00618 }
00619 
00620 void QtopiaSocket::readTodoList()
00621 {
00622     KSync::CalendarSyncee* syncee = defaultCalendarSyncee();
00623     QString tempfile;
00624 //    emit prog( StdProgress::downloading(i18n("TodoList") ) );
00625 
00626     bool ok = downloadFile( "/Applications/todolist/todolist.xml", tempfile );
00627     if ( !ok ) {
00628 //      emit error( StdError::downloadError(i18n("TodoList") ) );
00629       tempfile = QString::null;
00630     }
00631 
00632     if ( ok ) {
00633         OpieHelper::ToDo toDB( d->edit, d->helper, d->tz, d->device );
00634         ok = toDB.toKDE( tempfile, d->extras, syncee );
00635     }
00636 
00637     if ( !ok ) {
00638         KIO::NetAccess::removeTempFile( tempfile );
00639 //        emit error( i18n("Cannot read the TodoList file. It is corrupted.") );
00640         return;
00641     }
00642 
00643 //    emit prog( Progress(i18n("Collection changes for todolist") ) );
00644 
00645     /*
00646      * SyncHistory applying is done after both calendar and todo
00647      * are read and before emitting the records
00648      * in download() for now
00649      */
00650 
00651     if ( d->m_sync.find( syncee ) == d->m_sync.end() )
00652       d->m_sync.append( syncee );
00653 
00654     if (!tempfile.isEmpty() )
00655         KIO::NetAccess::removeTempFile( tempfile );
00656 }
00657 
00658 void QtopiaSocket::start( const QString& line )
00659 {
00660     if ( line.left(3) != QString::fromLatin1("220") ) {
00661 //        emit error( Error(i18n("The device returned bogus data. giving up now.") ) );
00662         // something went wrong
00663         d->socket->close();
00664         d->mode = d->Done;
00665         d->connected    = false;
00666         d->isConnecting = false;
00667     } else {
00668         /*
00669          * parse the uuid
00670          * here if not zaurus
00671          */
00672         if( d->device->distribution() == OpieHelper::Device::Zaurus ){
00673             d->partnerId = d->device->meta();
00674         } else {
00675             QStringList list = QStringList::split(";", line );
00676             QString uid = list[1];
00677             uid = uid.mid(11, uid.length()-12 );
00678               d->partnerId = uid;
00679         }
00680         initFiles();
00681         sendCommand( "USER " + d->device->user() );
00682         d->mode = d->User;
00683     }
00684 }
00685 
00686 void QtopiaSocket::user( const QString &line )
00687 {
00688 //    emit prog( StdProgress::connected() );
00689 //    emit prog( StdProgress::authentication() );
00690     if ( line.left(3) != QString::fromLatin1("331") ) {
00691 //        emit error( StdError::wrongUser( d->device->user() ) );
00692         // wrong user name
00693         d->socket->close();
00694         d->mode = d->Done;
00695         d->connected    = false;
00696         d->isConnecting = false;
00697     } else{
00698         sendCommand( "PASS " + d->device->password() );
00699         d->mode = d->Pass;
00700     }
00701 }
00702 
00703 void QtopiaSocket::pass( const QString& line)
00704 {
00705     if ( line.left(3) != QString::fromLatin1("230") ) {
00706 //        emit error( StdError::wrongPassword() );
00707         // wrong password
00708         d->socket->close();
00709         d->mode = d->Done;
00710         d->connected    = false;
00711         d->isConnecting = false;
00712     } else {
00713 //        emit prog( StdProgress::authenticated() );
00714         d->mode = d->Noop;
00715         QTimer::singleShot(10000, this, SLOT(slotNOOP() ) );
00716     }
00717 }
00718 
00719 void QtopiaSocket::call( const QString& line)
00720 {
00721     if ( line.contains("220 Command okay" ) &&
00722          ( d->getMode == d->Handshake || d->getMode == d->ABook ) )
00723         return;
00724 
00725     if ( line.startsWith("CALL QPE/Desktop docLinks(QString)") ) {
00726 //        emit prog( Progress(i18n("Getting the Document Links of the Document Tab") ) );
00727         OpieHelper::Desktop desk( d->edit );
00728         Syncee* sync = desk.toSyncee( line );
00729         if ( sync )
00730             d->m_sync.append( sync );
00731     }
00732 
00733 
00734     switch( d->getMode ) {
00735     case QtopiaSocket::Private::Handshake:
00736         handshake( line );
00737         break;
00738     case QtopiaSocket::Private::Flush:
00739         flush( line );
00740         break;
00741     case QtopiaSocket::Private::ABook:
00742         download();
00743         break;
00744     case QtopiaSocket::Private::Desktops:
00745         initSync( line );
00746         break;
00747     }
00748 }
00749 
00750 void QtopiaSocket::flush( const QString& _line )
00751 {
00752     if ( _line.startsWith("CALL QPE/Desktop flushDone(QString)") ||
00753          _line.startsWith("599 ChannelNotRegistered") ) {
00754 
00755         QString line = _line.stripWhiteSpace();
00756         QString appName;
00757 
00758         if ( line.endsWith( "datebook" ) ) {
00759             readDatebook();
00760             appName = i18n( "datebook" );
00761             m_flushedApps++;
00762         } else if ( line.endsWith( "todolist" ) ) {
00763             readTodoList();
00764             appName = i18n( "todolist" );
00765             m_flushedApps++;
00766         } else if ( line.endsWith( "addressbook" ) )  {
00767             readAddressbook();
00768             appName = i18n( "addressbook" );
00769             m_flushedApps++;
00770         }
00771 //        emit prog( Progress( i18n( "Flushed " ) + appName ) );
00772     }
00773 
00774     /* all apps have been flushed or have not been running */
00775     if ( m_flushedApps == 3 ) {
00776         /*
00777          * now we can progress during sync
00778          */
00779         d->getMode  = d->ABook;
00780         sendCommand( "call QPE/System getAllDocLinks()" );
00781         m_flushedApps = 0;
00782     }
00783 }
00784 
00785 void QtopiaSocket::noop( const QString & )
00786 {
00787     d->isConnecting = false;
00788     if (!d->startSync ) {
00789         d->mode = d->Noop;
00790         QTimer::singleShot(10000, this, SLOT(slotNOOP() ) );
00791     }else
00792         slotStartSync();
00793 }
00794 
00795 void QtopiaSocket::handshake( const QString &line )
00796 {
00797     QStringList list = QStringList::split( QString::fromLatin1(" "), line );
00798     d->path = list[3];
00799     if (!d->path.isEmpty() ) {
00800         d->getMode = d->Desktops;
00801         sendCommand( "call QPE/System startSync(QString) KitchenSync" );
00802     }
00803 }
00804 
00805 void QtopiaSocket::download()
00806 {
00807   /*
00808    * As Calendar and Todo are shared in one Syncee we need
00809    * to do the sync information getting and applying here
00810    *
00811    */
00812   KSync::CalendarSyncee* syncee = defaultCalendarSyncee();
00813   OpieHelper::MetaCalendar  metaBook(syncee, storagePath() + "/" + d->partnerId + "/calendar_todolist.md5.qtopia" );
00814   metaBook.load();
00815   kdDebug(5227) << "Did Meta " << endl;
00816   outputIt(5227, syncee );
00817 
00818 
00819     /*
00820      * we're all set now
00821      * start sync
00822      * and clear our list
00823      */
00824     emit sync( d->m_sync );
00825     d->mode = d->Noop;
00826     d->m_sync.clear();
00827 }
00828 
00829 void QtopiaSocket::initSync( const QString& )
00830 {
00831     /* clear the extra map for the next round */
00832     d->extras.clear();
00833 //    emit prog( StdProgress::downloading("Categories.xml") );
00834     QString tmpFileName;
00835     downloadFile( "/Settings/Categories.xml", tmpFileName );
00836 
00837     /* Category Edit */
00838     delete d->edit;
00839     d->edit = new OpieHelper::CategoryEdit( tmpFileName );
00840     KIO::NetAccess::removeTempFile( tmpFileName );
00841 
00842     /* KonnectorUIDHelper */
00843     delete d->helper;
00844     d->helper = new KonnectorUIDHelper( partnerIdPath() );
00845 
00846     /* TimeZones */
00847     readTimeZones();
00848 
00849     /* flush the data on pda side to make sure to get the latest version */
00850     sendCommand( "call QPE/Application/datebook flush()" );
00851     sendCommand( "call QPE/Application/addressbook flush()" );
00852     sendCommand( "call QPE/Application/todolist flush()" );
00853     d->getMode  = d->Flush;
00854 }
00855 
00856 void QtopiaSocket::initFiles()
00857 {
00858     QDir di( QDir::homeDirPath() + "/.kitchensync/meta/" + d->partnerId );
00859     /*
00860      * if our meta path exists do not recreate it
00861      */
00862     if ( di.exists() ) {
00863         d->first = false;
00864         return;
00865     }
00866 
00867     d->first = true;
00868     QDir dir;
00869     dir.mkdir(QDir::homeDirPath() + "/.kitchensync");
00870     dir.mkdir(QDir::homeDirPath() + "/.kitchensync/meta");
00871     dir.mkdir(QDir::homeDirPath() + "/.kitchensync/meta/" + d->partnerId );
00872 }
00873 
00874 
00875 QString QtopiaSocket::partnerIdPath() const
00876 {
00877     QString str = QDir::homeDirPath();
00878     str += "/.kitchensync/meta/";
00879     str += d->partnerId;
00880 
00881     return str;
00882 }
00883 
00884 /*
00885  * As long as Qtopia/Opie is broken
00886  * in regards to handling timezones and events
00887  * we set the TimeZone to the one from Korganizer
00888  * for evolution we need to fix that!!!
00889  *
00890  */
00891 void QtopiaSocket::readTimeZones()
00892 {
00893     QString pref = KPimPrefs::timezone();
00894     d->tz = pref.isEmpty() ?
00895             QString::fromLatin1("Europe/London") : pref;
00896 }
00897 
00898 bool QtopiaSocket::downloadFile( const QString& str, QString& dest )
00899 {
00900     KURL uri = url( d->path + str );
00901     bool b = KIO::NetAccess::download( uri, dest, 0 );
00902     return b;
00903 }
00904 
00905 void QtopiaSocket::download( const QString& res )
00906 {
00907   Q_UNUSED( res );
00908 }
00909 
00910 void QtopiaSocket::sendCommand( const QString& cmd )
00911 {
00912   if ( !d->socket )
00913     kdError() << "No socket available" << endl;
00914 
00915 
00916   QTextStream stream( d->socket );
00917   stream << cmd << endl;
00918 }
00919 
00920 namespace {
00921 
00922 void outputAll( int area, QPtrList<SyncEntry> list )
00923 {
00924     for (SyncEntry* entry = list.first(); entry != 0; entry = list.next() ) {
00925         kdDebug(area) << "State " << entry->state() << endl;
00926         kdDebug(area) << "Summary " << entry->name() << endl;
00927         kdDebug(area) << "Uid " << entry->id() << endl;
00928     kdDebug(area) << "----" << endl;
00929     }
00930 }
00931 
00932 void outputIt( int area, Syncee *s )
00933 {
00934     kdDebug(area) << "Added entries" << endl;
00935     outputAll( area, s->added() );
00936 
00937     kdDebug(area) << "Modified " <<endl;
00938     outputAll( area, s->modified() );
00939 
00940     kdDebug(area) << "Removed " << endl;
00941     outputAll( area, s->removed() );
00942 }
00943 
00944 }
00945 
00946 #include "socket.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys