00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include <qstring.h>
00037 #include <qstringlist.h>
00038 #include <qregexp.h>
00039 #include <qtextstream.h>
00040
00041 #include <klocale.h>
00042 #include <kdebug.h>
00043 #include <kmdcodec.h>
00044
00045 #include "addressee.h"
00046 #include "address.h"
00047
00048 #include "ldif.h"
00049 #include "ldifconverter.h"
00050 #include "vcardconverter.h"
00051
00052 using namespace KABC;
00053
00054
00055
00056 bool LDIFConverter::addresseeToLDIF( const AddresseeList &addrList, QString &str )
00057 {
00058 AddresseeList::ConstIterator it;
00059 for ( it = addrList.begin(); it != addrList.end(); ++it ) {
00060 addresseeToLDIF( *it, str );
00061 }
00062 return true;
00063 }
00064
00065
00066
00067 static void ldif_out( QTextStream &t, QString formatStr, QString value )
00068 {
00069 if ( value.isEmpty() )
00070 return;
00071
00072 QCString txt = LDIF::assembleLine( formatStr, value, 72 );
00073
00074
00075 t << QString::fromUtf8(txt) << "\n";
00076 }
00077
00078 bool LDIFConverter::addresseeToLDIF( const Addressee &addr, QString &str )
00079 {
00080 if ( addr.isEmpty() )
00081 return false;
00082
00083 QTextStream t( str, IO_WriteOnly|IO_Append );
00084 t.setEncoding( QTextStream::UnicodeUTF8 );
00085
00086 const Address homeAddr = addr.address( Address::Home );
00087 const Address workAddr = addr.address( Address::Work );
00088
00089 ldif_out( t, "dn", QString( "cn=%1,mail=%2" )
00090 .arg( addr.formattedName().simplifyWhiteSpace() )
00091 .arg( addr.preferredEmail() ) );
00092 ldif_out( t, "givenname", addr.givenName() );
00093 ldif_out( t, "sn", addr.familyName() );
00094 ldif_out( t, "cn", addr.formattedName().simplifyWhiteSpace() );
00095 ldif_out( t, "uid", addr.uid() );
00096 ldif_out( t, "nickname", addr.nickName() );
00097 ldif_out( t, "xmozillanickname", addr.nickName() );
00098
00099 ldif_out( t, "mail", addr.preferredEmail() );
00100 if ( addr.emails().count() > 1 )
00101 ldif_out( t, "mozillasecondemail", addr.emails()[ 1 ] );
00102
00103
00104 ldif_out( t, "telephonenumber", addr.phoneNumber( PhoneNumber::Work ).number() );
00105 ldif_out( t, "facsimiletelephonenumber", addr.phoneNumber( PhoneNumber::Fax ).number() );
00106 ldif_out( t, "homephone", addr.phoneNumber( PhoneNumber::Home ).number() );
00107 ldif_out( t, "mobile", addr.phoneNumber( PhoneNumber::Cell ).number() );
00108 ldif_out( t, "cellphone", addr.phoneNumber( PhoneNumber::Cell ).number() );
00109 ldif_out( t, "pager", addr.phoneNumber( PhoneNumber::Pager ).number() );
00110 ldif_out( t, "pagerphone", addr.phoneNumber( PhoneNumber::Pager ).number() );
00111
00112 ldif_out( t, "streethomeaddress", homeAddr.street() );
00113 ldif_out( t, "postalcode", workAddr.postalCode() );
00114 ldif_out( t, "postofficebox", workAddr.postOfficeBox() );
00115
00116 QStringList streets = QStringList::split( '\n', homeAddr.street() );
00117 if ( streets.count() > 0 )
00118 ldif_out( t, "homepostaladdress", streets[ 0 ] );
00119 if ( streets.count() > 1 )
00120 ldif_out( t, "mozillahomepostaladdress2", streets[ 1 ] );
00121 ldif_out( t, "mozillahomelocalityname", homeAddr.locality() );
00122 ldif_out( t, "mozillahomestate", homeAddr.region() );
00123 ldif_out( t, "mozillahomepostalcode", homeAddr.postalCode() );
00124 ldif_out( t, "mozillahomecountryname", Address::ISOtoCountry(homeAddr.country()) );
00125 ldif_out( t, "locality", workAddr.locality() );
00126 ldif_out( t, "streetaddress", workAddr.street() );
00127
00128 streets = QStringList::split( '\n', workAddr.street() );
00129 if ( streets.count() > 0 )
00130 ldif_out( t, "postaladdress", streets[ 0 ] );
00131 if ( streets.count() > 1 )
00132 ldif_out( t, "mozillapostaladdress2", streets[ 1 ] );
00133 ldif_out( t, "countryname", Address::ISOtoCountry(workAddr.country()) );
00134 ldif_out( t, "l", workAddr.locality() );
00135 ldif_out( t, "c", Address::ISOtoCountry(workAddr.country()) );
00136 ldif_out( t, "st", workAddr.region() );
00137
00138 ldif_out( t, "title", addr.title() );
00139 ldif_out( t, "vocation", addr.prefix() );
00140 ldif_out( t, "ou", addr.role() );
00141 ldif_out( t, "o", addr.organization() );
00142 ldif_out( t, "organization", addr.organization() );
00143 ldif_out( t, "organizationname", addr.organization() );
00144 ldif_out( t, "department", addr.custom("KADDRESSBOOK", "X-Department") );
00145 ldif_out( t, "workurl", addr.url().prettyURL() );
00146 ldif_out( t, "homeurl", addr.url().prettyURL() );
00147 ldif_out( t, "description", addr.note() );
00148 if (addr.revision().isValid())
00149 ldif_out(t, "modifytimestamp", dateToVCardString( addr.revision()) );
00150
00151 t << "objectclass: top\n";
00152 t << "objectclass: person\n";
00153 t << "objectclass: organizationalPerson\n";
00154
00155 t << "\n";
00156
00157 return true;
00158 }
00159
00160
00161
00162
00163 bool LDIFConverter::LDIFToAddressee( const QString &str, AddresseeList &addrList, QDateTime dt )
00164 {
00165 bool endldif = false, end = false;
00166 LDIF ldif;
00167 LDIF::ParseVal ret;
00168 const char *latinstr = str.latin1();
00169 QByteArray data;
00170 Addressee a;
00171 Address homeAddr, workAddr;
00172
00173 data.setRawData( latinstr, qstrlen( latinstr ) );
00174 ldif.setLDIF( data );
00175 if (!dt.isValid())
00176 dt = QDateTime::currentDateTime();
00177 a.setRevision(dt);
00178 homeAddr = Address( Address::Home );
00179 workAddr = Address( Address::Work );
00180
00181 do {
00182 ret = ldif.nextItem();
00183 switch ( ret ) {
00184 case LDIF::Item: {
00185 QString fieldname = ldif.attr().lower();
00186 QString value = QString::fromUtf8( ldif.val(), ldif.val().size() );
00187 evaluatePair( a, homeAddr, workAddr, fieldname, value );
00188 break;
00189 }
00190 case LDIF::EndEntry:
00191
00192 if ( !a.formattedName().isEmpty() || !a.name().isEmpty() ||
00193 !a.familyName().isEmpty() ) {
00194 if ( !homeAddr.isEmpty() )
00195 a.insertAddress( homeAddr );
00196 if ( !workAddr.isEmpty() )
00197 a.insertAddress( workAddr );
00198 addrList.append( a );
00199 }
00200 a = Addressee();
00201 a.setRevision(dt);
00202 homeAddr = Address( Address::Home );
00203 workAddr = Address( Address::Work );
00204 break;
00205 case LDIF::MoreData: {
00206 if ( endldif )
00207 end = true;
00208 else {
00209 ldif.endLDIF();
00210 endldif = true;
00211 break;
00212 }
00213 }
00214 default:
00215 break;
00216 }
00217 } while ( !end );
00218
00219 data.resetRawData( latinstr, qstrlen( latinstr ) );
00220
00221 return true;
00222 }
00223
00224 bool LDIFConverter::evaluatePair( Addressee &a, Address &homeAddr,
00225 Address &workAddr,
00226 QString &fieldname, QString &value )
00227 {
00228 if ( fieldname == QString::fromLatin1( "dn" ) )
00229 return false;
00230
00231 if ( fieldname.startsWith("#") ) {
00232 return true;
00233 }
00234
00235 if ( fieldname.isEmpty() && !a.note().isEmpty() ) {
00236
00237
00238 a.setNote( a.note() + "\n" + value );
00239 return true;
00240 }
00241
00242 if ( fieldname == QString::fromLatin1( "givenname" ) ) {
00243 a.setGivenName( value );
00244 return true;
00245 }
00246
00247 if ( fieldname == QString::fromLatin1( "xmozillanickname") ||
00248 fieldname == QString::fromLatin1( "nickname") ) {
00249 a.setNickName( value );
00250 return true;
00251 }
00252
00253 if ( fieldname == QString::fromLatin1( "sn" ) ) {
00254 a.setFamilyName( value );
00255 return true;
00256 }
00257
00258 if ( fieldname == QString::fromLatin1( "uid" ) ) {
00259 a.setUid( value );
00260 return true;
00261 }
00262 if ( fieldname == QString::fromLatin1( "mail" ) ||
00263 fieldname == QString::fromLatin1( "mozillasecondemail" ) ) {
00264 if ( a.emails().findIndex( value ) == -1 )
00265 a.insertEmail( value );
00266 return true;
00267 }
00268
00269 if ( fieldname == QString::fromLatin1( "title" ) ) {
00270 a.setTitle( value );
00271 return true;
00272 }
00273
00274 if ( fieldname == QString::fromLatin1( "vocation" ) ) {
00275 a.setPrefix( value );
00276 return true;
00277 }
00278
00279 if ( fieldname == QString::fromLatin1( "cn" ) ) {
00280 a.setFormattedName( value );
00281 return true;
00282 }
00283
00284 if ( fieldname == QString::fromLatin1( "o" ) ||
00285 fieldname == QString::fromLatin1( "organization" ) ||
00286 fieldname == QString::fromLatin1( "organizationname" ) ) {
00287 a.setOrganization( value );
00288 return true;
00289 }
00290
00291 if ( fieldname == QString::fromLatin1( "description" ) ) {
00292 addComment:
00293 if ( !a.note().isEmpty() )
00294 a.setNote( a.note() + "\n" );
00295 a.setNote( a.note() + value );
00296 return true;
00297 }
00298
00299 if ( fieldname == QString::fromLatin1( "custom1" ) ||
00300 fieldname == QString::fromLatin1( "custom2" ) ||
00301 fieldname == QString::fromLatin1( "custom3" ) ||
00302 fieldname == QString::fromLatin1( "custom4" ) ) {
00303 goto addComment;
00304 }
00305
00306 if ( fieldname == QString::fromLatin1( "homeurl" ) ||
00307 fieldname == QString::fromLatin1( "workurl" ) ) {
00308 if (a.url().isEmpty()) {
00309 a.setUrl( KURL( value ) );
00310 return true;
00311 }
00312 if ( a.url().prettyURL() == KURL(value).prettyURL() )
00313 return true;
00314
00315
00316 }
00317
00318 if ( fieldname == QString::fromLatin1( "homephone" ) ) {
00319 a.insertPhoneNumber( PhoneNumber( value, PhoneNumber::Home ) );
00320 return true;
00321 }
00322
00323 if ( fieldname == QString::fromLatin1( "telephonenumber" ) ) {
00324 a.insertPhoneNumber( PhoneNumber( value, PhoneNumber::Work ) );
00325 return true;
00326 }
00327
00328 if ( fieldname == QString::fromLatin1( "mobile" ) ) {
00329 a.insertPhoneNumber( PhoneNumber( value, PhoneNumber::Cell ) );
00330 return true;
00331 }
00332
00333 if ( fieldname == QString::fromLatin1( "cellphone" ) ) {
00334 a.insertPhoneNumber( PhoneNumber( value, PhoneNumber::Cell ) );
00335 return true;
00336 }
00337
00338 if ( fieldname == QString::fromLatin1( "pager" ) ||
00339 fieldname == QString::fromLatin1( "pagerphone" ) ) {
00340 a.insertPhoneNumber( PhoneNumber( value, PhoneNumber::Pager ) );
00341 return true;
00342 }
00343
00344 if ( fieldname == QString::fromLatin1( "facsimiletelephonenumber" ) ) {
00345 a.insertPhoneNumber( PhoneNumber( value, PhoneNumber::Fax ) );
00346 return true;
00347 }
00348
00349 if ( fieldname == QString::fromLatin1( "xmozillaanyphone" ) ) {
00350 a.insertPhoneNumber( PhoneNumber( value, PhoneNumber::Work ) );
00351 return true;
00352 }
00353
00354 if ( fieldname == QString::fromLatin1( "street" ) ||
00355 fieldname == QString::fromLatin1( "streethomeaddress" ) ) {
00356 homeAddr.setStreet( value );
00357 return true;
00358 }
00359
00360 if ( fieldname == QString::fromLatin1( "postaladdress" ) ) {
00361 workAddr.setStreet( value );
00362 return true;
00363 }
00364
00365 if ( fieldname == QString::fromLatin1( "mozillapostaladdress2" ) ) {
00366 workAddr.setStreet( workAddr.street() + QString::fromLatin1( "\n" ) + value );
00367 return true;
00368 }
00369
00370 if ( fieldname == QString::fromLatin1( "postalcode" ) ) {
00371 workAddr.setPostalCode( value );
00372 return true;
00373 }
00374
00375 if ( fieldname == QString::fromLatin1( "postofficebox" ) ) {
00376 workAddr.setPostOfficeBox( value );
00377 return true;
00378 }
00379
00380 if ( fieldname == QString::fromLatin1( "homepostaladdress" ) ) {
00381 homeAddr.setStreet( value );
00382 return true;
00383 }
00384
00385 if ( fieldname == QString::fromLatin1( "mozillahomepostaladdress2" ) ) {
00386 homeAddr.setStreet( homeAddr.street() + QString::fromLatin1( "\n" ) + value );
00387 return true;
00388 }
00389
00390 if ( fieldname == QString::fromLatin1( "mozillahomelocalityname" ) ) {
00391 homeAddr.setLocality( value );
00392 return true;
00393 }
00394
00395 if ( fieldname == QString::fromLatin1( "mozillahomestate" ) ) {
00396 homeAddr.setRegion( value );
00397 return true;
00398 }
00399
00400 if ( fieldname == QString::fromLatin1( "mozillahomepostalcode" ) ) {
00401 homeAddr.setPostalCode( value );
00402 return true;
00403 }
00404
00405 if ( fieldname == QString::fromLatin1( "mozillahomecountryname" ) ) {
00406 if ( value.length() <= 2 )
00407 value = Address::ISOtoCountry(value);
00408 homeAddr.setCountry( value );
00409 return true;
00410 }
00411
00412 if ( fieldname == QString::fromLatin1( "locality" ) ) {
00413 workAddr.setLocality( value );
00414 return true;
00415 }
00416
00417 if ( fieldname == QString::fromLatin1( "streetaddress" ) ) {
00418 workAddr.setStreet( value );
00419 return true;
00420 }
00421
00422 if ( fieldname == QString::fromLatin1( "countryname" ) ||
00423 fieldname == QString::fromLatin1( "c" ) ) {
00424 if ( value.length() <= 2 )
00425 value = Address::ISOtoCountry(value);
00426 workAddr.setCountry( value );
00427 return true;
00428 }
00429
00430 if ( fieldname == QString::fromLatin1( "l" ) ) {
00431 workAddr.setLocality( value );
00432 return true;
00433 }
00434
00435 if ( fieldname == QString::fromLatin1( "st" ) ) {
00436 workAddr.setRegion( value );
00437 return true;
00438 }
00439
00440 if ( fieldname == QString::fromLatin1( "ou" ) ) {
00441 a.setRole( value );
00442 return true;
00443 }
00444
00445 if ( fieldname == QString::fromLatin1( "department" ) ) {
00446 a.insertCustom( "KADDRESSBOOK", "X-Department", value );
00447 return true;
00448 }
00449
00450 if ( fieldname == QString::fromLatin1( "member" ) ) {
00451
00452 QStringList list( QStringList::split( ',', value ) );
00453 QString name, email;
00454
00455 QStringList::Iterator it;
00456 for ( it = list.begin(); it != list.end(); ++it ) {
00457 if ( (*it).startsWith( "cn=" ) )
00458 name = (*it).mid( 3 ).stripWhiteSpace();
00459 if ( (*it).startsWith( "mail=" ) )
00460 email = (*it).mid( 5 ).stripWhiteSpace();
00461 }
00462 if ( !name.isEmpty() && !email.isEmpty() )
00463 email = " <" + email + ">";
00464 a.insertEmail( name + email );
00465 a.insertCategory( i18n( "List of Emails" ) );
00466 return true;
00467 }
00468
00469 if ( fieldname == QString::fromLatin1( "modifytimestamp" ) ) {
00470 if (value == QString::fromLatin1("0Z"))
00471 return true;
00472 QDateTime dt = VCardStringToDate( value );
00473 if ( dt.isValid() ) {
00474 a.setRevision(dt);
00475 return true;
00476 }
00477 }
00478
00479 if ( fieldname == QString::fromLatin1( "objectclass" ) )
00480 return true;
00481
00482 kdWarning() << QString("LDIFConverter: Unknown field for '%1': '%2=%3'\n")
00483 .arg(a.formattedName()).arg(fieldname).arg(value);
00484
00485 return true;
00486 }
00487
00488
00489
00490
00491 bool LDIFConverter::parseSingleLine( Addressee &a, Address &homeAddr,
00492 Address &workAddr, QString &line )
00493 {
00494 if ( line.isEmpty() )
00495 return true;
00496
00497 QString fieldname, value;
00498 QByteArray val;
00499
00500 LDIF::splitLine( line.latin1(), fieldname, val );
00501 value = QString::fromUtf8( val.data(), val.size() );
00502 return evaluatePair( a, homeAddr, workAddr, fieldname, value);
00503 }
00504
00505
00506 bool LDIFConverter::splitLine( QString &line, QString &fieldname, QString &value)
00507 {
00508 QByteArray val;
00509 bool ret = LDIF::splitLine( line.latin1(), fieldname, val );
00510 value = QString::fromUtf8( val.data(), val.size() );
00511 return ret;
00512 }
00513
00514
00515 QString LDIFConverter::makeLDIFfieldString( QString formatStr, QString value, bool allowEncode )
00516 {
00517 if ( value.isEmpty() )
00518 return QString();
00519
00520
00521 if (formatStr.find(':') == -1)
00522 formatStr.append(": %1\n");
00523
00524
00525 bool printable = true;
00526 unsigned int i, len;
00527 len = value.length();
00528 for (i = 0; i<len; ++i ) {
00529 if (!value[i].isPrint()) {
00530 printable = false;
00531 break;
00532 }
00533 }
00534
00535 if (printable)
00536 printable = (value.find('\n') == -1);
00537
00538 if (!printable && allowEncode) {
00539
00540 value = KCodecs::base64Encode( value.utf8() );
00541 int p = formatStr.find(':');
00542 if (p>=0)
00543 formatStr.insert(p, ':');
00544 }
00545
00546
00547 QCString txt = (formatStr.arg(value)).utf8();
00548
00549 if (allowEncode) {
00550 len = txt.length();
00551 if (len && txt[len-1] == '\n')
00552 --len;
00553 i = 72;
00554 while (i < len) {
00555 txt.insert(i, "\n ");
00556 i += 72+1;
00557 len += 2;
00558 }
00559 }
00560
00561 return QString::fromUtf8(txt);
00562 }
00563