kab2kabc.cpp

00001 /*
00002     This file is part of libkabc.
00003     Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
00004 
00005     This library is free software; you can redistribute it and/or
00006     modify it under the terms of the GNU Library General Public
00007     License as published by the Free Software Foundation; either
00008     version 2 of the License, or (at your option) any later version.
00009 
00010     This library is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013     Library General Public License for more details.
00014 
00015     You should have received a copy of the GNU Library General Public License
00016     along with this library; see the file COPYING.LIB.  If not, write to
00017     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018     Boston, MA 02110-1301, USA.
00019 */
00020 
00021 #include <qfile.h>
00022 #include <qtextstream.h>
00023 
00024 #include <kabapi.h>
00025 #include <kaboutdata.h>
00026 #include <kapplication.h>
00027 #include <kcmdlineargs.h>
00028 #include <kconfig.h>
00029 #include <kdebug.h>
00030 #include <kglobal.h>
00031 #include <klocale.h>
00032 #include <kmessagebox.h>
00033 #include <kstandarddirs.h>
00034 
00035 #include "addressbook.h"
00036 #include "stdaddressbook.h"
00037 
00038 using namespace KABC;
00039 
00040 static const KCmdLineOptions options[] =
00041 {
00042   { "disable-autostart", I18N_NOOP( "Disable automatic startup on login" ), 0 },
00043   { "quiet", "", 0 },
00044   { "o", 0, 0 },
00045   { "override", I18N_NOOP( "Override existing entries" ), "1" },
00046   KCmdLineLastOption
00047 };
00048 
00049 void readKMailEntry( const QString &kmailEntry, KABC::AddressBook *ab )
00050 {
00051   kdDebug() << "KMAILENTRY: " << kmailEntry << endl;
00052 
00053   QString entry = kmailEntry.simplifyWhiteSpace();
00054   if ( entry.isEmpty() ) return;
00055 
00056   QString email;
00057   QString name;
00058   QString comment;
00059 
00060   if ( entry.at( entry.length() -1 ) == ')' ) {
00061     int br = entry.findRev( '(' );
00062     if ( br >= 0 ) {
00063       comment = entry.mid( br + 1, entry.length() - br - 2 );
00064       entry.truncate( br );
00065       if ( entry.at( entry.length() - 1 ).isSpace() ) {
00066         entry.truncate( br - 1 );
00067       }
00068     }
00069   }
00070 
00071   int posSpace = entry.findRev( ' ' );
00072   if ( posSpace < 0 ) {
00073     email = entry;
00074     if ( !comment.isEmpty() ) {
00075       name = comment;
00076       comment = "";
00077     }
00078   } else {
00079     email = entry.mid( posSpace + 1 );
00080     name = entry.left( posSpace );
00081   }
00082 
00083   if ( email.at( 0 ) == '<' && email.at( email.length() - 1) == '>' ) {
00084     email = email.mid( 1, email.length() - 2 );
00085   }
00086   if ( name.at( 0 ) == '"' && name.at( name.length() - 1) == '"' ) {
00087     name = name.mid( 1, name.length() - 2 );
00088   }
00089   if ( name.at( 0 ) == '\'' && name.at( name.length() - 1) == '\'' ) {
00090     name = name.mid( 1, name.length() - 2 );
00091   }
00092 
00093   if ( name.at( name.length() -1 ) == ')' ) {
00094     int br = name.findRev( '(' );
00095     if ( br >= 0 ) {
00096       comment = name.mid( br + 1, name.length() - br - 2 ) + " " + comment;
00097       name.truncate( br );
00098       if ( name.at( name.length() - 1 ).isSpace() ) {
00099         name.truncate( br - 1 );
00100       }
00101     }
00102   }
00103 
00104   kdDebug() << "  EMAIL   : " << email   << endl;
00105   kdDebug() << "  NAME    : " << name    << endl;
00106   kdDebug() << "  COMMENT : " << comment << endl;
00107 
00108   KABC::Addressee::List al = ab->findByEmail( email );
00109   if ( al.isEmpty() ) {
00110     KABC::Addressee a;
00111     a.setNameFromString( name );
00112     a.insertEmail( email );
00113     a.setNote( comment );
00114 
00115     ab->insertAddressee( a );
00116 
00117     kdDebug() << "--INSERTED: " << a.realName() << endl;
00118   }
00119 }
00120 
00121 void importKMailAddressBook( KABC::AddressBook *ab )
00122 {
00123   QString fileName = locateLocal( "data", "kmail/addressbook" );
00124   QString kmailConfigName = locate( "config", "kmailrc" );
00125   if ( !kmailConfigName.isEmpty() ) {
00126     KConfig cfg( kmailConfigName );
00127     cfg.setGroup( "Addressbook" );
00128     fileName = cfg.readPathEntry( "default", fileName );
00129   }
00130   if ( !KStandardDirs::exists( fileName ) ) {
00131     kdDebug(5700) << "Couldn't find KMail addressbook." << endl;
00132     return;
00133   }
00134 
00135   QFile f( fileName );
00136   if ( !f.open(IO_ReadOnly) ) {
00137     kdDebug(5700) << "Couldn't open file '" << fileName << "'" << endl;
00138     return;
00139   }
00140 
00141   QStringList kmailEntries;
00142 
00143   QTextStream t( &f );
00144   while ( !t.eof() ) {
00145     kmailEntries.append( t.readLine() );
00146   }
00147   f.close();
00148 
00149   QStringList::ConstIterator it;
00150   for ( it = kmailEntries.begin(); it != kmailEntries.end(); ++it ) {
00151     if ( (*it).at( 0 ) == '#' ) continue;
00152     bool insideQuote = false;
00153     int end = (*it).length() - 1;
00154     for ( int i = end; i; i-- ) {
00155       if ( (*it).at( i ) == '"' ) {
00156         if ( insideQuote )
00157           insideQuote = false;
00158         else
00159           insideQuote = true;
00160       } else if ( (*it).at( i ) == ',' && !insideQuote ) {
00161         readKMailEntry( (*it).mid( i + 1, end - i ), ab );
00162         end = i - 1;
00163       }
00164     }
00165 
00166     readKMailEntry( (*it).mid( 0, end + 1 ), ab );
00167   }
00168 }
00169 
00170 void readKAddressBookEntries( const QString &dataString, Addressee &a )
00171 {
00172   // Strip "KMail:1.0" prefix and "[EOS]" suffix.
00173   QString str = dataString.mid( 11, dataString.length() - 24 );
00174 
00175   QStringList entries = QStringList::split( "\n[EOR]\n ", str );
00176 
00177   Address homeAddress( Address::Home );
00178   Address businessAddress( Address::Work );
00179   Address otherAddress;
00180 
00181   QStringList::ConstIterator it;
00182   for ( it = entries.begin(); it != entries.end(); ++it ) {
00183     int pos = (*it).find( "\n" );
00184     QString fieldName = (*it).left( pos );
00185     QString fieldValue = (*it).mid( pos + 2 );
00186 
00187     if ( fieldName == "X-HomeFax" ) {
00188       a.insertPhoneNumber( PhoneNumber( fieldValue, PhoneNumber::Home |
00189                                                     PhoneNumber::Fax ) );
00190     } else if ( fieldName == "X-OtherPhone" ) {
00191       a.insertPhoneNumber( PhoneNumber( fieldValue, 0 ) );
00192     } else if ( fieldName == "X-PrimaryPhone" ) {
00193       a.insertPhoneNumber( PhoneNumber( fieldValue, PhoneNumber::Pref ) );
00194     } else if ( fieldName == "X-BusinessFax" ) {
00195       a.insertPhoneNumber( PhoneNumber( fieldValue, PhoneNumber::Work |
00196                                                     PhoneNumber::Fax ) );
00197     } else if ( fieldName == "X-CarPhone" ) {
00198       a.insertPhoneNumber( PhoneNumber( fieldValue, PhoneNumber::Car ) );
00199     } else if ( fieldName == "X-MobilePhone" ) {
00200       a.insertPhoneNumber( PhoneNumber( fieldValue, PhoneNumber::Cell ) );
00201     } else if ( fieldName == "X-ISDN" ) {
00202       a.insertPhoneNumber( PhoneNumber( fieldValue, PhoneNumber::Isdn ) );
00203     } else if ( fieldName == "X-OtherFax" ) {
00204       a.insertPhoneNumber( PhoneNumber( fieldValue, PhoneNumber::Fax ) );
00205     } else if ( fieldName == "X-Pager" ) {
00206       a.insertPhoneNumber( PhoneNumber( fieldValue, PhoneNumber::Pager ) );
00207     } else if ( fieldName == "X-BusinessPhone" ) {
00208       a.insertPhoneNumber( PhoneNumber( fieldValue, PhoneNumber::Work ) );
00209     } else if ( fieldName == "X-HomePhone" ) {
00210       a.insertPhoneNumber( PhoneNumber( fieldValue, PhoneNumber::Home ) );
00211     } else if ( fieldName == "X-HomeAddress" ) {
00212       homeAddress.setLabel( fieldValue );
00213     } else if ( fieldName == "X-HomeAddressStreet" ) {
00214       homeAddress.setStreet( fieldValue );
00215     } else if ( fieldName == "X-HomeAddressCity" ) {
00216       homeAddress.setLocality( fieldValue );
00217     } else if ( fieldName == "X-HomeAddressPostalCode" ) {
00218       homeAddress.setPostalCode( fieldValue );
00219     } else if ( fieldName == "X-HomeAddressState" ) {
00220       homeAddress.setRegion( fieldValue );
00221     } else if ( fieldName == "X-HomeAddressCountry" ) {
00222       homeAddress.setCountry( fieldValue );
00223     } else if ( fieldName == "X-BusinessAddress" ) {
00224       businessAddress.setLabel( fieldValue );
00225     } else if ( fieldName == "X-BusinessAddressStreet" ) {
00226       businessAddress.setStreet( fieldValue );
00227     } else if ( fieldName == "X-BusinessAddressCity" ) {
00228       businessAddress.setLocality( fieldValue );
00229     } else if ( fieldName == "X-BusinessAddressPostalCode" ) {
00230       businessAddress.setPostalCode( fieldValue );
00231     } else if ( fieldName == "X-BusinessAddressState" ) {
00232       businessAddress.setRegion( fieldValue );
00233     } else if ( fieldName == "X-BusinessAddressCountry" ) {
00234       businessAddress.setCountry( fieldValue );
00235     } else if ( fieldName == "X-OtherAddress" ) {
00236       otherAddress.setLabel( fieldValue );
00237     } else if ( fieldName == "X-OtherAddressStreet" ) {
00238       otherAddress.setStreet( fieldValue );
00239     } else if ( fieldName == "X-OtherAddressCity" ) {
00240       otherAddress.setLocality( fieldValue );
00241     } else if ( fieldName == "X-OtherAddressPostalCode" ) {
00242       otherAddress.setPostalCode( fieldValue );
00243     } else if ( fieldName == "X-OtherAddressState" ) {
00244       otherAddress.setRegion( fieldValue );
00245     } else if ( fieldName == "X-OtherAddressCountry" ) {
00246       otherAddress.setCountry( fieldValue );
00247     } else if ( fieldName == "NICKNAME" ) {
00248       a.setNickName( fieldValue );
00249     } else if ( fieldName == "ORG" ) {
00250       a.setOrganization( fieldValue );
00251     } else if ( fieldName == "ROLE" ) {
00252       a.setRole( fieldValue );
00253     } else if ( fieldName == "BDAY" ) {
00254       a.setBirthday( KGlobal::locale()->readDate( fieldValue ) );
00255     } else if ( fieldName == "WEBPAGE" ) {
00256       a.setUrl( KURL( fieldValue ) );
00257     } else if ( fieldName == "N" ) {
00258     } else if ( fieldName == "X-FirstName" ) {
00259     } else if ( fieldName == "X-MiddleName" ) {
00260     } else if ( fieldName == "X-LastName" ) {
00261     } else if ( fieldName == "X-Title" ) {
00262     } else if ( fieldName == "X-Suffix" ) {
00263     } else if ( fieldName == "X-FileAs" ) {
00264     } else if ( fieldName == "EMAIL" ) {
00265       a.insertEmail( fieldValue, true );
00266     } else if ( fieldName == "X-E-mail2" ) {
00267       a.insertEmail( fieldValue );
00268     } else if ( fieldName == "X-E-mail3" ) {
00269       a.insertEmail( fieldValue );
00270     } else if ( fieldName == "X-Notes" ) {
00271     } else {
00272       a.insertCustom( "KADDRESSBOOK", fieldName, fieldValue );
00273     }
00274   }
00275 
00276   if ( !homeAddress.isEmpty() ) a.insertAddress( homeAddress );
00277   if ( !businessAddress.isEmpty() ) a.insertAddress( businessAddress );
00278   if ( !otherAddress.isEmpty() ) a.insertAddress( otherAddress );
00279 }
00280 
00281 void importKab( KABC::AddressBook *ab, bool override, bool quiet )
00282 {
00283   QString fileName = KGlobal::dirs()->saveLocation( "data", "kab/" );
00284   fileName += "addressbook.kab";
00285   if ( !QFile::exists( fileName ) ) {
00286     if ( !quiet ) {
00287       KMessageBox::error( 0, "<qt>" + i18n( "Address book file <b>%1</b> not found! Make sure the old address book is located there and you have read permission for this file." )
00288                           .arg( fileName ) + "</qt>" );
00289     }
00290     kdDebug(5700) << "No KDE 2 addressbook found." << endl;
00291     return;
00292   }
00293 
00294   kdDebug(5700) << "Converting old-style kab addressbook to "
00295                "new-style kabc addressbook." << endl;
00296 
00297   KabAPI kab( 0 );
00298   if ( kab.init() != ::AddressBook::NoError ) {
00299     kdDebug(5700) << "Error initing kab" << endl;
00300     exit( 1 );
00301   }
00302 
00303   KabKey key;
00304   ::AddressBook::Entry entry;
00305 
00306   int num = kab.addressbook()->noOfEntries();
00307 
00308   kdDebug(5700) << "kab Addressbook has " << num << " entries." << endl;
00309 
00310   for ( int i = 0; i < num; ++i ) {
00311     if ( ::AddressBook::NoError != kab.addressbook()->getKey( i, key ) ) {
00312       kdDebug(5700) << "Error getting key for index " << i << " from kab." << endl;
00313       continue;
00314     }
00315     if ( ::AddressBook::NoError != kab.addressbook()->getEntry( key, entry ) ) {
00316       kdDebug(5700) << "Error getting entry for index " << i << " from kab." << endl;
00317       continue;
00318     }
00319 
00320     Addressee a;
00321 
00322     // Convert custom entries
00323     int count = 0;
00324     bool idFound = false;
00325     QStringList::ConstIterator customIt;
00326     for ( customIt = entry.custom.begin(); customIt != entry.custom.end(); ++customIt ) {
00327       if ( (*customIt).startsWith( "X-KABC-UID:" ) ) {
00328         a.setUid( (*customIt).mid( (*customIt).find( ":" ) + 1 ) );
00329         idFound = true;
00330       } else if ( (*customIt).startsWith( "KMail:1.0\n" ) ) {
00331         readKAddressBookEntries( *customIt, a );
00332       } else {
00333         a.insertCustom( "kab2kabc", QString::number( count++ ), *customIt );
00334       }
00335     }
00336     if ( idFound ) {
00337       if ( !override ) continue;
00338     } else {
00339       entry.custom << "X-KABC-UID:" + a.uid();
00340       ::AddressBook::ErrorCode error = kab.addressbook()->change( key, entry );
00341       if ( error != ::AddressBook::NoError ) {
00342         kdDebug(5700) << "kab.change returned with error " << error << endl;
00343       } else {
00344         kdDebug(5700) << "Wrote back to kab uid " << a.uid() << endl;
00345       }
00346     }
00347 
00348     a.setTitle( entry.title );
00349     a.setFormattedName( entry.fn );
00350     a.setPrefix( entry.nameprefix );
00351     a.setGivenName( entry.firstname );
00352     a.setAdditionalName( entry.middlename );
00353     a.setFamilyName( entry.lastname );
00354     a.setBirthday( entry.birthday );
00355 
00356     QStringList::ConstIterator emailIt;
00357     for ( emailIt = entry.emails.begin(); emailIt != entry.emails.end(); ++emailIt )
00358       a.insertEmail( *emailIt );
00359 
00360     QStringList::ConstIterator phoneIt;
00361     for ( phoneIt = entry.telephone.begin(); phoneIt != entry.telephone.end(); ++phoneIt ) {
00362       int kabType = (*phoneIt++).toInt();
00363       if ( phoneIt == entry.telephone.end() ) break;
00364       QString number = *phoneIt;
00365       int type = 0;
00366       if ( kabType == ::AddressBook::Fixed ) type = PhoneNumber::Voice;
00367       else if ( kabType == ::AddressBook::Mobile ) type = PhoneNumber::Cell | PhoneNumber::Voice;
00368       else if ( kabType == ::AddressBook::Fax ) type = PhoneNumber::Fax;
00369       else if ( kabType == ::AddressBook::Modem ) type = PhoneNumber::Modem;
00370       a.insertPhoneNumber( PhoneNumber( number, type ) );
00371     }
00372 
00373     if ( entry.URLs.count() > 0 ) {
00374       a.setUrl( KURL( entry.URLs.first() ) );
00375       if ( entry.URLs.count() > 1 ) {
00376         kdWarning() << "More than one URL. Ignoring all but the first." << endl;
00377       }
00378     }
00379 
00380     int noAdr = entry.noOfAddresses();
00381     for ( int j = 0; j < noAdr; ++j ) {
00382       ::AddressBook::Entry::Address kabAddress;
00383       entry.getAddress( j, kabAddress );
00384 
00385       Address adr;
00386 
00387       adr.setStreet( kabAddress.address );
00388       adr.setPostalCode( kabAddress.zip );
00389       adr.setLocality( kabAddress.town );
00390       adr.setCountry( kabAddress.country );
00391       adr.setRegion( kabAddress.state );
00392 
00393       QString label;
00394       if ( !kabAddress.headline.isEmpty() ) label += kabAddress.headline + "\n";
00395       if ( !kabAddress.position.isEmpty() ) label += kabAddress.position + "\n";
00396       if ( !kabAddress.org.isEmpty() ) label += kabAddress.org + "\n";
00397       if ( !kabAddress.orgUnit.isEmpty() ) label += kabAddress.orgUnit + "\n";
00398       if ( !kabAddress.orgSubUnit.isEmpty() ) label += kabAddress.orgSubUnit + "\n";
00399       if ( !kabAddress.deliveryLabel.isEmpty() ) label += kabAddress.deliveryLabel + "\n";
00400       adr.setLabel( label );
00401 
00402       a.insertAddress( adr );
00403     }
00404 
00405     QString note = entry.comment;
00406 
00407     if ( !entry.user1.isEmpty() ) note += "\nUser1: " + entry.user1;
00408     if ( !entry.user2.isEmpty() ) note += "\nUser2: " + entry.user2;
00409     if ( !entry.user3.isEmpty() ) note += "\nUser3: " + entry.user3;
00410     if ( !entry.user4.isEmpty() ) note += "\nUser4: " + entry.user4;
00411 
00412     if ( !entry.keywords.count() == 0 ) note += "\nKeywords: " + entry.keywords.join( ", " );
00413 
00414     QStringList::ConstIterator talkIt;
00415     for ( talkIt = entry.talk.begin(); talkIt != entry.talk.end(); ++talkIt ) {
00416       note += "\nTalk: " + (*talkIt);
00417     }
00418 
00419     a.setNote( note );
00420 
00421     a.setPrefix( entry.rank + a.prefix() );  // Add rank to prefix
00422 
00423     a.setCategories( entry.categories );
00424 
00425     kdDebug(5700) << "Addressee: " << a.familyName() << endl;
00426 
00427     ab->insertAddressee( a );
00428   }
00429 
00430   kab.save( true );
00431 }
00432 
00433 int main( int argc, char **argv )
00434 {
00435   KAboutData aboutData( "kab2kabc", I18N_NOOP( "Kab to Kabc Converter" ), "0.1" );
00436   aboutData.addAuthor( "Cornelius Schumacher", 0, "schumacher@kde.org" );
00437 
00438   KCmdLineArgs::init( argc, argv, &aboutData );
00439   KCmdLineArgs::addCmdLineOptions( options );
00440 
00441   KApplication app;
00442 
00443   KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
00444 
00445   bool override = false;
00446 
00447   if ( args->isSet( "override" ) ) {
00448     kdDebug() << "Override existing entries." << endl;
00449 
00450     override = true;
00451   }
00452 
00453   bool quiet = false;
00454 
00455   if ( args->isSet( "quiet" ) )
00456     quiet = true;
00457 
00458   if ( args->isSet( "disable-autostart" ) ) {
00459     kdDebug() << "Disable autostart." << endl;
00460 
00461     KConfig *config = app.config();
00462     config->setGroup( "Startup" );
00463     config->writeEntry( "EnableAutostart", false );
00464   }
00465 
00466   KABC::AddressBook *kabcBook = StdAddressBook::self();
00467 
00468   importKMailAddressBook( kabcBook );
00469 
00470   importKab( kabcBook, override, quiet );
00471 
00472   StdAddressBook::save();
00473 
00474   kdDebug(5700) << "Saved kabc addressbook to '" << kabcBook->identifier() << "'" << endl;
00475 }
00476 
KDE Home | KDE Accessibility Home | Description of Access Keys