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