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 <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
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
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() );
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