• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdepimlibs-4.8.5 API Reference
  • KDE Home
  • Contact Us
 

kabc

ldifconverter.cpp
00001 /*
00002     This file is part of libkabc.
00003     Copyright (c) 2003  Helge Deller <deller@kde.org>
00004 
00005     This library is free software; you can redistribute it and/or
00006     modify it under the terms of the GNU Library General Public
00007     License as published by the Free Software Foundation; either
00008     version 2 of the License, or (at your option) any later version.
00009 
00010     This library is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013     Library General Public License for more details.
00014 
00015     You should have received a copy of the GNU Library General Public License
00016     along with this library; see the file COPYING.LIB.  If not, write to
00017     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018     Boston, MA 02110-1301, USA.
00019 */
00020 
00021 /*
00022     Useful links:
00023         - http://tldp.org/HOWTO/LDAP-Implementation-HOWTO/schemas.html
00024         - http://www.faqs.org/rfcs/rfc2849.html
00025 
00026     Not yet handled items:
00027         - objectclass microsoftaddressbook
00028                 - info,
00029                 - initials,
00030                 - otherfacsimiletelephonenumber,
00031                 - otherpager,
00032                 - physicaldeliveryofficename,
00033 */
00034 
00035 #include "ldifconverter.h"
00036 #include "vcardconverter.h"
00037 #include "address.h"
00038 #include "addressee.h"
00039 
00040 #include "ldif_p.h"
00041 
00042 #include <kdebug.h>
00043 #include <klocale.h>
00044 
00045 #include <QtCore/QRegExp>
00046 #include <QtCore/QStringList>
00047 #include <QtCore/QTextCodec>
00048 #include <QtCore/QTextStream>
00049 
00050 using namespace KABC;
00051 
00052 /* generate LDIF stream */
00053 
00054 bool LDIFConverter::addresseeToLDIF( const AddresseeList &addrList, QString &str )
00055 {
00056   AddresseeList::ConstIterator it;
00057   for ( it = addrList.begin(); it != addrList.end(); ++it ) {
00058     addresseeToLDIF( *it, str );
00059   }
00060   return true;
00061 }
00062 
00063 static void ldif_out( QTextStream &t, const QString &formatStr,
00064                       const QString &value )
00065 {
00066   if ( value.isEmpty() ) {
00067     return;
00068   }
00069 
00070   QByteArray txt = Ldif::assembleLine( formatStr, value, 72 );
00071 
00072   // write the string
00073   t << QString::fromUtf8( txt ) << "\n";
00074 }
00075 
00076 bool LDIFConverter::addresseeToLDIF( const Addressee &addr, QString &str )
00077 {
00078   if ( addr.isEmpty() ) {
00079     return false;
00080   }
00081 
00082   QTextStream t( &str, QIODevice::WriteOnly|QIODevice::Append );
00083   t.setCodec( QTextCodec::codecForName( "UTF-8" ) );
00084 
00085   const Address homeAddr = addr.address( Address::Home );
00086   const Address workAddr = addr.address( Address::Work );
00087 
00088   ldif_out( t, QLatin1String( "dn" ), QString::fromLatin1( "cn=%1,mail=%2" ).
00089             arg( addr.formattedName().simplified() ).
00090             arg( addr.preferredEmail() ) );
00091   ldif_out( t, QLatin1String( "givenname" ), addr.givenName() );
00092   ldif_out( t, QLatin1String( "sn" ), addr.familyName() );
00093   ldif_out( t, QLatin1String( "cn" ), addr.formattedName().simplified() );
00094   ldif_out( t, QLatin1String( "uid" ), addr.uid() );
00095   ldif_out( t, QLatin1String( "nickname" ), addr.nickName() );
00096   ldif_out( t, QLatin1String( "xmozillanickname" ), addr.nickName() );
00097   ldif_out( t, QLatin1String( "mozillanickname" ), addr.nickName() );
00098 
00099   ldif_out( t, QLatin1String( "mail" ), addr.preferredEmail() );
00100   if ( addr.emails().count() > 1 ) {
00101     ldif_out( t, QLatin1String( "mozillasecondemail" ), addr.emails()[ 1 ] );
00102   }
00103 //ldif_out( t, "mozilla_AIMScreenName: %1\n", "screen_name" );
00104 
00105   ldif_out( t, QLatin1String( "telephonenumber" ),
00106             addr.phoneNumber( PhoneNumber::Work ).number() );
00107   ldif_out( t, QLatin1String( "facsimiletelephonenumber" ),
00108             addr.phoneNumber( PhoneNumber::Fax ).number() );
00109   ldif_out( t, QLatin1String( "homephone" ),
00110             addr.phoneNumber( PhoneNumber::Home ).number() );
00111   ldif_out( t, QLatin1String( "mobile" ),
00112             addr.phoneNumber( PhoneNumber::Cell ).number() ); // Netscape 7
00113   ldif_out( t, QLatin1String( "cellphone" ),
00114             addr.phoneNumber( PhoneNumber::Cell ).number() ); // Netscape 4.x
00115   ldif_out( t, QLatin1String( "pager" ),
00116             addr.phoneNumber( PhoneNumber::Pager ).number() );
00117   ldif_out( t, QLatin1String( "pagerphone" ),
00118             addr.phoneNumber( PhoneNumber::Pager ).number() );
00119 
00120   ldif_out( t, QLatin1String( "streethomeaddress" ), homeAddr.street() );
00121   ldif_out( t, QLatin1String( "postalcode" ), workAddr.postalCode() );
00122   ldif_out( t, QLatin1String( "postofficebox" ), workAddr.postOfficeBox() );
00123 
00124   QStringList streets = homeAddr.street().split( QLatin1Char( '\n' ) );
00125   const int numberOfStreets(streets.count());
00126   if ( numberOfStreets > 0 ) {
00127     ldif_out( t, QLatin1String( "homepostaladdress" ), streets[ 0 ] ); // Netscape 7
00128   }
00129   if ( numberOfStreets > 1 ) {
00130     ldif_out( t, QLatin1String( "mozillahomepostaladdress2" ), streets[ 1 ] ); // Netscape 7
00131   }
00132   ldif_out( t, QLatin1String( "mozillahomelocalityname" ), homeAddr.locality() ); // Netscape 7
00133   ldif_out( t, QLatin1String( "mozillahomestate" ), homeAddr.region() );
00134   ldif_out( t, QLatin1String( "mozillahomepostalcode" ), homeAddr.postalCode() );
00135   ldif_out( t, QLatin1String( "mozillahomecountryname" ),
00136             Address::ISOtoCountry( homeAddr.country() ) );
00137   ldif_out( t, QLatin1String( "locality" ), workAddr.locality() );
00138   ldif_out( t, QLatin1String( "streetaddress" ), workAddr.street() ); // Netscape 4.x
00139 
00140   streets = workAddr.street().split( QLatin1Char( '\n' ) );
00141   if ( streets.count() > 0 ) {
00142     ldif_out( t, QLatin1String( "postaladdress" ), streets[ 0 ] );
00143   }
00144   if ( streets.count() > 1 ) {
00145     ldif_out( t, QLatin1String( "mozillapostaladdress2" ), streets[ 1 ] );
00146   }
00147   ldif_out( t, QLatin1String( "countryname" ), Address::ISOtoCountry( workAddr.country() ) );
00148   ldif_out( t, QLatin1String( "l" ), workAddr.locality() );
00149   ldif_out( t, QLatin1String( "c" ), Address::ISOtoCountry( workAddr.country() ) );
00150   ldif_out( t, QLatin1String( "st" ), workAddr.region() );
00151 
00152   ldif_out( t, QLatin1String( "title" ), addr.title() );
00153   ldif_out( t, QLatin1String( "vocation" ), addr.prefix() );
00154   ldif_out( t, QLatin1String( "ou" ), addr.role() );
00155   ldif_out( t, QLatin1String( "o" ), addr.organization() );
00156   ldif_out( t, QLatin1String( "organization" ), addr.organization() );
00157   ldif_out( t, QLatin1String( "organizationname" ), addr.organization() );
00158 
00159   // Compatibility with older kabc versions.
00160   if ( !addr.department().isEmpty() ) {
00161     ldif_out( t, QLatin1String( "department" ), addr.department() );
00162   } else {
00163     ldif_out( t, QLatin1String( "department" ), addr.custom( QLatin1String( "KADDRESSBOOK" ),
00164                                                              QLatin1String( "X-Department" ) ) );
00165   }
00166 
00167   ldif_out( t, QLatin1String( "workurl" ), addr.url().prettyUrl() );
00168   ldif_out( t, QLatin1String( "homeurl" ), addr.url().prettyUrl() );
00169   ldif_out( t, QLatin1String( "mozillahomeurl" ), addr.url().prettyUrl() );
00170 
00171   ldif_out( t, QLatin1String( "description" ), addr.note() );
00172   if ( addr.revision().isValid() ) {
00173     ldif_out( t, QLatin1String( "modifytimestamp" ), dateToVCardString( addr.revision() ) );
00174   }
00175 
00176   const QDateTime birthday = addr.birthday();
00177   if ( birthday.isValid() ) {
00178     const QDate date = birthday.date();
00179     ldif_out( t, QLatin1String( "birthyear" ), QString::number( date.year() ) );
00180     ldif_out( t, QLatin1String( "birthmonth" ), QString::number( date.month() ) );
00181     ldif_out( t, QLatin1String( "birthday" ), QString::number( date.day() ) );
00182   }
00183 
00184   t << "objectclass: top\n";
00185   t << "objectclass: person\n";
00186   t << "objectclass: organizationalPerson\n";
00187 
00188   t << "\n";
00189 
00190   return true;
00191 }
00192 
00193 /* convert from LDIF stream */
00194 
00195 bool LDIFConverter::LDIFToAddressee( const QString &str, AddresseeList &addrList,
00196                                      const QDateTime &dt )
00197 {
00198   if ( str.isEmpty() ) {
00199     return true;
00200   }
00201 
00202   bool endldif = false, end = false;
00203   Ldif ldif;
00204   Ldif::ParseValue ret;
00205   Addressee a;
00206   Address homeAddr, workAddr;
00207   int birthday = -1;
00208   int birthmonth = -1;
00209   int birthyear = -1;
00210 
00211   ldif.setLdif( str.toLatin1() );
00212   QDateTime qdt = dt;
00213   if ( !qdt.isValid() ) {
00214     qdt = QDateTime::currentDateTime();
00215   }
00216   a.setRevision( qdt );
00217   homeAddr = Address( Address::Home );
00218   workAddr = Address( Address::Work );
00219 
00220   do {
00221     ret = ldif.nextItem();
00222     switch ( ret ) {
00223       case Ldif::Item:
00224       {
00225         QString fieldname = ldif.attr().toLower();
00226         QString value = QString::fromUtf8( ldif.value(), ldif.value().size() );
00227         evaluatePair( a, homeAddr, workAddr, fieldname, value, birthday, birthmonth,birthyear );
00228         break;
00229       }
00230       case Ldif::EndEntry:
00231       {
00232         // if the new address is not empty, append it
00233         QDateTime birthDate( QDate( birthyear, birthmonth, birthday ) );
00234         if ( birthDate.isValid() ) {
00235           a.setBirthday( birthDate );
00236         }
00237 
00238         if ( !a.formattedName().isEmpty() || !a.name().isEmpty() ||
00239           !a.familyName().isEmpty() ) {
00240           if ( !homeAddr.isEmpty() ) {
00241             a.insertAddress( homeAddr );
00242           }
00243           if ( !workAddr.isEmpty() ) {
00244             a.insertAddress( workAddr );
00245           }
00246           addrList.append( a );
00247         }
00248         a = Addressee();
00249         a.setRevision( qdt );
00250         homeAddr = Address( Address::Home );
00251         workAddr = Address( Address::Work );
00252       }
00253       break;
00254       case Ldif::MoreData:
00255       {
00256         if ( endldif ) {
00257           end = true;
00258         } else {
00259           ldif.endLdif();
00260           endldif = true;
00261           break;
00262         }
00263       }
00264       default:
00265         break;
00266     }
00267   } while ( !end );
00268 
00269   return true;
00270 }
00271 
00272 bool LDIFConverter::evaluatePair( Addressee &a, Address &homeAddr,
00273                                   Address &workAddr,
00274                                   QString &fieldname, QString &value, int &birthday, int &birthmonth, int &birthyear )
00275 {
00276   if ( fieldname == QLatin1String( "dn" ) ) { // ignore & return false!
00277     return false;
00278   }
00279 
00280   if ( fieldname.startsWith( QLatin1Char( '#' ) ) ) {
00281     return true;
00282   }
00283 
00284   if ( fieldname.isEmpty() && !a.note().isEmpty() ) {
00285     // some LDIF export filters are borken and add additional
00286     // comments on stand-alone lines. Just add them to the notes for now.
00287     a.setNote( a.note() + QLatin1Char( '\n' ) + value );
00288     return true;
00289   }
00290 
00291   if ( fieldname == QLatin1String( "givenname" ) ) {
00292     a.setGivenName( value );
00293     return true;
00294   }
00295 
00296   if ( fieldname == QLatin1String( "xmozillanickname" ) ||
00297        fieldname == QLatin1String( "nickname" ) ||
00298        fieldname == QLatin1String( "mozillanickname" ) ) {
00299     a.setNickName( value );
00300     return true;
00301   }
00302 
00303   if ( fieldname == QLatin1String( "sn" ) ) {
00304     a.setFamilyName( value );
00305     return true;
00306   }
00307 
00308   if ( fieldname == QLatin1String( "uid" ) ) {
00309     a.setUid( value );
00310     return true;
00311   }
00312   if ( fieldname == QLatin1String( "mail" ) ||
00313        fieldname == QLatin1String( "mozillasecondemail" ) ) { // mozilla
00314     if ( a.emails().indexOf( value ) == -1 ) {
00315       a.insertEmail( value );
00316     }
00317     return true;
00318   }
00319 
00320   if ( fieldname == QLatin1String( "title" ) ) {
00321     a.setTitle( value );
00322     return true;
00323   }
00324 
00325   if ( fieldname == QLatin1String( "vocation" ) ) {
00326     a.setPrefix( value );
00327     return true;
00328   }
00329 
00330   if ( fieldname == QLatin1String( "cn" ) ) {
00331     a.setFormattedName( value );
00332     return true;
00333   }
00334 
00335   if ( fieldname == QLatin1String( "o" ) ||
00336        fieldname == QLatin1String( "organization" ) ||      // Exchange
00337        fieldname == QLatin1String( "organizationname" ) ) { // Exchange
00338     a.setOrganization( value );
00339     return true;
00340   }
00341 
00342   if ( fieldname == QLatin1String( "description" ) ) {
00343 addComment:
00344     if ( !a.note().isEmpty() ) {
00345       a.setNote( a.note() + QLatin1Char( '\n' ) );
00346     }
00347     a.setNote( a.note() + value );
00348     return true;
00349   }
00350 
00351   if ( fieldname == QLatin1String( "custom1" ) ||
00352        fieldname == QLatin1String( "custom2" ) ||
00353        fieldname == QLatin1String( "custom3" ) ||
00354        fieldname == QLatin1String( "custom4" ) ) {
00355     goto addComment;
00356   }
00357 
00358   if ( fieldname == QLatin1String( "homeurl" ) ||
00359        fieldname == QLatin1String( "workurl" ) ||
00360        fieldname == QLatin1String( "mozillahomeurl" )) {
00361     if ( a.url().isEmpty() ) {
00362       a.setUrl( KUrl( value ) );
00363       return true;
00364     }
00365     if ( a.url().prettyUrl() == KUrl( value ).prettyUrl() ) {
00366       return true;
00367     }
00368     // TODO: current version of kabc only supports one URL.
00369     // TODO: change this with KDE 4
00370   }
00371 
00372   if ( fieldname == QLatin1String( "homephone" ) ) {
00373     a.insertPhoneNumber( PhoneNumber( value, PhoneNumber::Home ) );
00374     return true;
00375   }
00376 
00377   if ( fieldname == QLatin1String( "telephonenumber" ) ) {
00378     a.insertPhoneNumber( PhoneNumber( value, PhoneNumber::Work ) );
00379     return true;
00380   }
00381 
00382   if ( fieldname == QLatin1String( "mobile" ) ) {   // mozilla/Netscape 7
00383     a.insertPhoneNumber( PhoneNumber( value, PhoneNumber::Cell ) );
00384     return true;
00385   }
00386 
00387   if ( fieldname == QLatin1String( "cellphone" ) ) {
00388     a.insertPhoneNumber( PhoneNumber( value, PhoneNumber::Cell ) );
00389     return true;
00390   }
00391 
00392   if ( fieldname == QLatin1String( "pager" )  ||       // mozilla
00393        fieldname == QLatin1String( "pagerphone" ) ) {  // mozilla
00394     a.insertPhoneNumber( PhoneNumber( value, PhoneNumber::Pager ) );
00395     return true;
00396   }
00397 
00398   if ( fieldname == QLatin1String( "facsimiletelephonenumber" ) ) {
00399     a.insertPhoneNumber( PhoneNumber( value, PhoneNumber::Fax ) );
00400     return true;
00401   }
00402 
00403   if ( fieldname == QLatin1String( "xmozillaanyphone" ) ) { // mozilla
00404     a.insertPhoneNumber( PhoneNumber( value, PhoneNumber::Work ) );
00405     return true;
00406   }
00407 
00408   if ( fieldname == QLatin1String( "street" ) ||
00409        fieldname == QLatin1String( "streethomeaddress" ) ||
00410        fieldname == QLatin1String( "mozillahomestreet" ) /*thunderbird*/ ) {
00411     homeAddr.setStreet( value );
00412     return true;
00413   }
00414 
00415   if ( fieldname == QLatin1String( "postaladdress" ) ) {  // mozilla
00416     workAddr.setStreet( value );
00417     return true;
00418   }
00419 
00420   if ( fieldname == QLatin1String( "mozillapostaladdress2" ) ) {  // mozilla
00421     workAddr.setStreet( workAddr.street() + QLatin1String( "\n" ) + value );
00422     return true;
00423   }
00424 
00425   if ( fieldname == QLatin1String( "postalcode" ) ) {
00426     workAddr.setPostalCode( value );
00427     return true;
00428   }
00429 
00430   if ( fieldname == QLatin1String( "postofficebox" ) ) {
00431     workAddr.setPostOfficeBox( value );
00432     return true;
00433   }
00434 
00435   if ( fieldname == QLatin1String( "homepostaladdress" ) ) {  // Netscape 7
00436     homeAddr.setStreet( value );
00437     return true;
00438   }
00439 
00440   if ( fieldname == QLatin1String( "mozillahomepostaladdress2" ) ) {  // mozilla
00441     homeAddr.setStreet( homeAddr.street() + QLatin1String( "\n" ) + value );
00442     return true;
00443   }
00444 
00445   if ( fieldname == QLatin1String( "mozillahomelocalityname" ) ) {  // mozilla
00446     homeAddr.setLocality( value );
00447     return true;
00448   }
00449 
00450   if ( fieldname == QLatin1String( "mozillahomestate" ) ) { // mozilla
00451     homeAddr.setRegion( value );
00452     return true;
00453   }
00454 
00455   if ( fieldname == QLatin1String( "mozillahomepostalcode" ) ) {  // mozilla
00456     homeAddr.setPostalCode( value );
00457     return true;
00458   }
00459 
00460   if ( fieldname == QLatin1String( "mozillahomecountryname" ) ) { // mozilla
00461     if ( value.length() <= 2 ) {
00462       value = Address::ISOtoCountry( value );
00463     }
00464     homeAddr.setCountry( value );
00465     return true;
00466   }
00467 
00468   if ( fieldname == QLatin1String( "locality" ) ) {
00469     workAddr.setLocality( value );
00470     return true;
00471   }
00472 
00473   if ( fieldname == QLatin1String( "streetaddress" ) ) { // Netscape 4.x
00474     workAddr.setStreet( value );
00475     return true;
00476   }
00477 
00478   if ( fieldname == QLatin1String( "countryname" ) ||
00479        fieldname == QLatin1String( "c" ) ) {  // mozilla
00480     if ( value.length() <= 2 ) {
00481       value = Address::ISOtoCountry( value );
00482     }
00483     workAddr.setCountry( value );
00484     return true;
00485   }
00486 
00487   if ( fieldname == QLatin1String( "l" ) ) {  // mozilla
00488     workAddr.setLocality( value );
00489     return true;
00490   }
00491 
00492   if ( fieldname == QLatin1String( "st" ) ) {
00493     workAddr.setRegion( value );
00494     return true;
00495   }
00496 
00497   if ( fieldname == QLatin1String( "ou" ) ) {
00498     a.setRole( value );
00499     return true;
00500   }
00501 
00502   if ( fieldname == QLatin1String( "department" ) ) {
00503     a.setDepartment( value );
00504     return true;
00505   }
00506 
00507   if ( fieldname == QLatin1String( "member" ) ) {
00508     // this is a mozilla list member (cn=xxx, mail=yyy)
00509     QStringList list = value.split( QLatin1Char( ',' ) );
00510     QString name, email;
00511 
00512     QStringList::Iterator it;
00513     for ( it = list.begin(); it != list.end(); ++it ) {
00514       if ( (*it).startsWith( QLatin1String( "cn=" ) ) ) {
00515         name = (*it).mid( 3 ).trimmed();
00516       }
00517       if ( (*it).startsWith( QLatin1String( "mail=" ) ) ) {
00518         email = (*it).mid( 5 ).trimmed();
00519       }
00520     }
00521     if ( !name.isEmpty() && !email.isEmpty() ) {
00522       email = QLatin1String( " <" ) + email + QLatin1Char( '>' );
00523     }
00524     a.insertEmail( name + email );
00525     a.insertCategory( i18n( "List of Emails" ) );
00526     return true;
00527   }
00528 
00529   if ( fieldname == QLatin1String( "modifytimestamp" ) ) {
00530     if ( value == QLatin1String( "0Z" ) ) { // ignore
00531       return true;
00532     }
00533     QDateTime dt = VCardStringToDate( value );
00534     if ( dt.isValid() ) {
00535       a.setRevision( dt );
00536       return true;
00537     }
00538   }
00539 
00540   if ( fieldname == QLatin1String( "objectclass" ) ) { // ignore
00541     return true;
00542   }
00543 
00544   if ( fieldname == QLatin1String( "birthyear" ) ) {
00545     birthyear = value.toInt();
00546     return true;
00547   }
00548   if ( fieldname == QLatin1String( "birthmonth" ) ) {
00549     birthmonth = value.toInt();
00550     return true;
00551   }
00552   if ( fieldname == QLatin1String( "birthday" ) ) {
00553     birthday = value.toInt();
00554     return true;
00555   }
00556 
00557   kWarning(5700) << QString::fromLatin1( "LDIFConverter: Unknown field for '%1': '%2=%3'\n" ).
00558     arg( a.formattedName() ).arg( fieldname ).arg( value );
00559 
00560   return true;
00561 }
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Mon Aug 27 2012 22:10:23 by doxygen 1.7.5 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kabc

Skip menu "kabc"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • Related Pages

kdepimlibs-4.8.5 API Reference

Skip menu "kdepimlibs-4.8.5 API Reference"
  • akonadi
  •   contact
  •   kmime
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  •   richtextbuilders
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal