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