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 if (str.isEmpty())
00166 return true;
00167
00168 bool endldif = false, end = false;
00169 LDIF ldif;
00170 LDIF::ParseVal ret;
00171 const char *latinstr = str.latin1();
00172 int latinstrlen = qstrlen( latinstr );
00173 QByteArray data;
00174 Addressee a;
00175 Address homeAddr, workAddr;
00176
00177 data.setRawData( latinstr, latinstrlen );
00178 ldif.setLDIF( data );
00179 if (!dt.isValid())
00180 dt = QDateTime::currentDateTime();
00181 a.setRevision(dt);
00182 homeAddr = Address( Address::Home );
00183 workAddr = Address( Address::Work );
00184
00185 do {
00186 ret = ldif.nextItem();
00187 switch ( ret ) {
00188 case LDIF::Item: {
00189 QString fieldname = ldif.attr().lower();
00190 QString value = QString::fromUtf8( ldif.val(), ldif.val().size() );
00191 evaluatePair( a, homeAddr, workAddr, fieldname, value );
00192 break;
00193 }
00194 case LDIF::EndEntry:
00195
00196 if ( !a.formattedName().isEmpty() || !a.name().isEmpty() ||
00197 !a.familyName().isEmpty() ) {
00198 if ( !homeAddr.isEmpty() )
00199 a.insertAddress( homeAddr );
00200 if ( !workAddr.isEmpty() )
00201 a.insertAddress( workAddr );
00202 addrList.append( a );
00203 }
00204 a = Addressee();
00205 a.setRevision(dt);
00206 homeAddr = Address( Address::Home );
00207 workAddr = Address( Address::Work );
00208 break;
00209 case LDIF::MoreData: {
00210 if ( endldif )
00211 end = true;
00212 else {
00213 ldif.endLDIF();
00214 endldif = true;
00215 break;
00216 }
00217 }
00218 default:
00219 break;
00220 }
00221 } while ( !end );
00222
00223 data.resetRawData( latinstr, latinstrlen );
00224
00225 return true;
00226 }
00227
00228 bool LDIFConverter::evaluatePair( Addressee &a, Address &homeAddr,
00229 Address &workAddr,
00230 QString &fieldname, QString &value )
00231 {
00232 if ( fieldname == QString::fromLatin1( "dn" ) )
00233 return false;
00234
00235 if ( fieldname.startsWith("#") ) {
00236 return true;
00237 }
00238
00239 if ( fieldname.isEmpty() && !a.note().isEmpty() ) {
00240
00241
00242 a.setNote( a.note() + "\n" + value );
00243 return true;
00244 }
00245
00246 if ( fieldname == QString::fromLatin1( "givenname" ) ) {
00247 a.setGivenName( value );
00248 return true;
00249 }
00250
00251 if ( fieldname == QString::fromLatin1( "xmozillanickname") ||
00252 fieldname == QString::fromLatin1( "nickname") ) {
00253 a.setNickName( value );
00254 return true;
00255 }
00256
00257 if ( fieldname == QString::fromLatin1( "sn" ) ) {
00258 a.setFamilyName( value );
00259 return true;
00260 }
00261
00262 if ( fieldname == QString::fromLatin1( "uid" ) ) {
00263 a.setUid( value );
00264 return true;
00265 }
00266 if ( fieldname == QString::fromLatin1( "mail" ) ||
00267 fieldname == QString::fromLatin1( "mozillasecondemail" ) ) {
00268 if ( a.emails().findIndex( value ) == -1 )
00269 a.insertEmail( value );
00270 return true;
00271 }
00272
00273 if ( fieldname == QString::fromLatin1( "title" ) ) {
00274 a.setTitle( value );
00275 return true;
00276 }
00277
00278 if ( fieldname == QString::fromLatin1( "vocation" ) ) {
00279 a.setPrefix( value );
00280 return true;
00281 }
00282
00283 if ( fieldname == QString::fromLatin1( "cn" ) ) {
00284 a.setFormattedName( value );
00285 return true;
00286 }
00287
00288 if ( fieldname == QString::fromLatin1( "o" ) ||
00289 fieldname == QString::fromLatin1( "organization" ) ||
00290 fieldname == QString::fromLatin1( "organizationname" ) ) {
00291 a.setOrganization( value );
00292 return true;
00293 }
00294
00295 if ( fieldname == QString::fromLatin1( "description" ) ) {
00296 addComment:
00297 if ( !a.note().isEmpty() )
00298 a.setNote( a.note() + "\n" );
00299 a.setNote( a.note() + value );
00300 return true;
00301 }
00302
00303 if ( fieldname == QString::fromLatin1( "custom1" ) ||
00304 fieldname == QString::fromLatin1( "custom2" ) ||
00305 fieldname == QString::fromLatin1( "custom3" ) ||
00306 fieldname == QString::fromLatin1( "custom4" ) ) {
00307 goto addComment;
00308 }
00309
00310 if ( fieldname == QString::fromLatin1( "homeurl" ) ||
00311 fieldname == QString::fromLatin1( "workurl" ) ) {
00312 if (a.url().isEmpty()) {
00313 a.setUrl( KURL( value ) );
00314 return true;
00315 }
00316 if ( a.url().prettyURL() == KURL(value).prettyURL() )
00317 return true;
00318
00319
00320 }
00321
00322 if ( fieldname == QString::fromLatin1( "homephone" ) ) {
00323 a.insertPhoneNumber( PhoneNumber( value, PhoneNumber::Home ) );
00324 return true;
00325 }
00326
00327 if ( fieldname == QString::fromLatin1( "telephonenumber" ) ) {
00328 a.insertPhoneNumber( PhoneNumber( value, PhoneNumber::Work ) );
00329 return true;
00330 }
00331
00332 if ( fieldname == QString::fromLatin1( "mobile" ) ) {
00333 a.insertPhoneNumber( PhoneNumber( value, PhoneNumber::Cell ) );
00334 return true;
00335 }
00336
00337 if ( fieldname == QString::fromLatin1( "cellphone" ) ) {
00338 a.insertPhoneNumber( PhoneNumber( value, PhoneNumber::Cell ) );
00339 return true;
00340 }
00341
00342 if ( fieldname == QString::fromLatin1( "pager" ) ||
00343 fieldname == QString::fromLatin1( "pagerphone" ) ) {
00344 a.insertPhoneNumber( PhoneNumber( value, PhoneNumber::Pager ) );
00345 return true;
00346 }
00347
00348 if ( fieldname == QString::fromLatin1( "facsimiletelephonenumber" ) ) {
00349 a.insertPhoneNumber( PhoneNumber( value, PhoneNumber::Fax ) );
00350 return true;
00351 }
00352
00353 if ( fieldname == QString::fromLatin1( "xmozillaanyphone" ) ) {
00354 a.insertPhoneNumber( PhoneNumber( value, PhoneNumber::Work ) );
00355 return true;
00356 }
00357
00358 if ( fieldname == QString::fromLatin1( "street" ) ||
00359 fieldname == QString::fromLatin1( "streethomeaddress" ) ) {
00360 homeAddr.setStreet( value );
00361 return true;
00362 }
00363
00364 if ( fieldname == QString::fromLatin1( "postaladdress" ) ) {
00365 workAddr.setStreet( value );
00366 return true;
00367 }
00368
00369 if ( fieldname == QString::fromLatin1( "mozillapostaladdress2" ) ) {
00370 workAddr.setStreet( workAddr.street() + QString::fromLatin1( "\n" ) + value );
00371 return true;
00372 }
00373
00374 if ( fieldname == QString::fromLatin1( "postalcode" ) ) {
00375 workAddr.setPostalCode( value );
00376 return true;
00377 }
00378
00379 if ( fieldname == QString::fromLatin1( "postofficebox" ) ) {
00380 workAddr.setPostOfficeBox( value );
00381 return true;
00382 }
00383
00384 if ( fieldname == QString::fromLatin1( "homepostaladdress" ) ) {
00385 homeAddr.setStreet( value );
00386 return true;
00387 }
00388
00389 if ( fieldname == QString::fromLatin1( "mozillahomepostaladdress2" ) ) {
00390 homeAddr.setStreet( homeAddr.street() + QString::fromLatin1( "\n" ) + value );
00391 return true;
00392 }
00393
00394 if ( fieldname == QString::fromLatin1( "mozillahomelocalityname" ) ) {
00395 homeAddr.setLocality( value );
00396 return true;
00397 }
00398
00399 if ( fieldname == QString::fromLatin1( "mozillahomestate" ) ) {
00400 homeAddr.setRegion( value );
00401 return true;
00402 }
00403
00404 if ( fieldname == QString::fromLatin1( "mozillahomepostalcode" ) ) {
00405 homeAddr.setPostalCode( value );
00406 return true;
00407 }
00408
00409 if ( fieldname == QString::fromLatin1( "mozillahomecountryname" ) ) {
00410 if ( value.length() <= 2 )
00411 value = Address::ISOtoCountry(value);
00412 homeAddr.setCountry( value );
00413 return true;
00414 }
00415
00416 if ( fieldname == QString::fromLatin1( "locality" ) ) {
00417 workAddr.setLocality( value );
00418 return true;
00419 }
00420
00421 if ( fieldname == QString::fromLatin1( "streetaddress" ) ) {
00422 workAddr.setStreet( value );
00423 return true;
00424 }
00425
00426 if ( fieldname == QString::fromLatin1( "countryname" ) ||
00427 fieldname == QString::fromLatin1( "c" ) ) {
00428 if ( value.length() <= 2 )
00429 value = Address::ISOtoCountry(value);
00430 workAddr.setCountry( value );
00431 return true;
00432 }
00433
00434 if ( fieldname == QString::fromLatin1( "l" ) ) {
00435 workAddr.setLocality( value );
00436 return true;
00437 }
00438
00439 if ( fieldname == QString::fromLatin1( "st" ) ) {
00440 workAddr.setRegion( value );
00441 return true;
00442 }
00443
00444 if ( fieldname == QString::fromLatin1( "ou" ) ) {
00445 a.setRole( value );
00446 return true;
00447 }
00448
00449 if ( fieldname == QString::fromLatin1( "department" ) ) {
00450 a.insertCustom( "KADDRESSBOOK", "X-Department", value );
00451 return true;
00452 }
00453
00454 if ( fieldname == QString::fromLatin1( "member" ) ) {
00455
00456 QStringList list( QStringList::split( ',', value ) );
00457 QString name, email;
00458
00459 QStringList::Iterator it;
00460 for ( it = list.begin(); it != list.end(); ++it ) {
00461 if ( (*it).startsWith( "cn=" ) )
00462 name = (*it).mid( 3 ).stripWhiteSpace();
00463 if ( (*it).startsWith( "mail=" ) )
00464 email = (*it).mid( 5 ).stripWhiteSpace();
00465 }
00466 if ( !name.isEmpty() && !email.isEmpty() )
00467 email = " <" + email + ">";
00468 a.insertEmail( name + email );
00469 a.insertCategory( i18n( "List of Emails" ) );
00470 return true;
00471 }
00472
00473 if ( fieldname == QString::fromLatin1( "modifytimestamp" ) ) {
00474 if (value == QString::fromLatin1("0Z"))
00475 return true;
00476 QDateTime dt = VCardStringToDate( value );
00477 if ( dt.isValid() ) {
00478 a.setRevision(dt);
00479 return true;
00480 }
00481 }
00482
00483 if ( fieldname == QString::fromLatin1( "objectclass" ) )
00484 return true;
00485
00486 kdWarning() << QString("LDIFConverter: Unknown field for '%1': '%2=%3'\n")
00487 .arg(a.formattedName()).arg(fieldname).arg(value);
00488
00489 return true;
00490 }
00491
00492
00493
00494
00495 bool LDIFConverter::parseSingleLine( Addressee &a, Address &homeAddr,
00496 Address &workAddr, QString &line )
00497 {
00498 if ( line.isEmpty() )
00499 return true;
00500
00501 QString fieldname, value;
00502 QByteArray val;
00503
00504 LDIF::splitLine( line.latin1(), fieldname, val );
00505 value = QString::fromUtf8( val.data(), val.size() );
00506 return evaluatePair( a, homeAddr, workAddr, fieldname, value);
00507 }
00508
00509
00510 bool LDIFConverter::splitLine( QString &line, QString &fieldname, QString &value)
00511 {
00512 QByteArray val;
00513 bool ret = LDIF::splitLine( line.latin1(), fieldname, val );
00514 value = QString::fromUtf8( val.data(), val.size() );
00515 return ret;
00516 }
00517
00518
00519 QString LDIFConverter::makeLDIFfieldString( QString formatStr, QString value, bool allowEncode )
00520 {
00521 if ( value.isEmpty() )
00522 return QString();
00523
00524
00525 if (formatStr.find(':') == -1)
00526 formatStr.append(": %1\n");
00527
00528
00529 bool printable = true;
00530 unsigned int i, len;
00531 len = value.length();
00532 for (i = 0; i<len; ++i ) {
00533 if (!value[i].isPrint()) {
00534 printable = false;
00535 break;
00536 }
00537 }
00538
00539 if (printable)
00540 printable = (value.find('\n') == -1);
00541
00542 if (!printable && allowEncode) {
00543
00544 value = KCodecs::base64Encode( value.utf8() );
00545 int p = formatStr.find(':');
00546 if (p>=0)
00547 formatStr.insert(p, ':');
00548 }
00549
00550
00551 QCString txt = (formatStr.arg(value)).utf8();
00552
00553 if (allowEncode) {
00554 len = txt.length();
00555 if (len && txt[len-1] == '\n')
00556 --len;
00557 i = 72;
00558 while (i < len) {
00559 txt.insert(i, "\n ");
00560 i += 72+1;
00561 len += 2;
00562 }
00563 }
00564
00565 return QString::fromUtf8(txt);
00566 }
00567