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