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

kabc

  • kabc
ldifconverter.cpp
1 /*
2  This file is part of libkabc.
3  Copyright (c) 2003 Helge Deller <deller@kde.org>
4 
5  This library is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Library General Public
7  License as published by the Free Software Foundation; either
8  version 2 of the License, or (at your option) any later version.
9 
10  This library is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Library General Public License for more details.
14 
15  You should have received a copy of the GNU Library General Public License
16  along with this library; see the file COPYING.LIB. If not, write to
17  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  Boston, MA 02110-1301, USA.
19 */
20 
21 /*
22  Useful links:
23  - http://tldp.org/HOWTO/LDAP-Implementation-HOWTO/schemas.html
24  - http://www.faqs.org/rfcs/rfc2849.html
25 
26  Not yet handled items:
27  - objectclass microsoftaddressbook
28  - info,
29  - initials,
30  - otherfacsimiletelephonenumber,
31  - otherpager,
32  - physicaldeliveryofficename,
33 */
34 
35 #include "ldifconverter.h"
36 #include "vcardconverter.h"
37 #include "address.h"
38 #include "addressee.h"
39 
40 #include "ldif_p.h"
41 
42 #include <kdebug.h>
43 #include <klocale.h>
44 
45 #include <QtCore/QRegExp>
46 #include <QtCore/QStringList>
47 #include <QtCore/QTextCodec>
48 #include <QtCore/QTextStream>
49 
50 using namespace KABC;
51 
52 /* generate LDIF stream */
53 
54 bool LDIFConverter::addresseeToLDIF( const AddresseeList &addrList, QString &str )
55 {
56  AddresseeList::ConstIterator it;
57  AddresseeList::ConstIterator end( addrList.constEnd() );
58  for ( it = addrList.constBegin(); it != end; ++it ) {
59  addresseeToLDIF( *it, str );
60  }
61  return true;
62 }
63 
64 static void ldif_out( QTextStream &t, const QString &formatStr,
65  const QString &value )
66 {
67  if ( value.isEmpty() ) {
68  return;
69  }
70 
71  const QByteArray txt = Ldif::assembleLine( formatStr, value, 72 );
72 
73  // write the string
74  t << QString::fromUtf8( txt ) << "\n";
75 }
76 
77 bool LDIFConverter::addresseeToLDIF( const Addressee &addr, QString &str )
78 {
79  if ( addr.isEmpty() ) {
80  return false;
81  }
82 
83  QTextStream t( &str, QIODevice::WriteOnly|QIODevice::Append );
84  t.setCodec( QTextCodec::codecForName( "UTF-8" ) );
85 
86  const Address homeAddr = addr.address( Address::Home );
87  const Address workAddr = addr.address( Address::Work );
88 
89  ldif_out( t, QLatin1String( "dn" ), QString::fromLatin1( "cn=%1,mail=%2" ).
90  arg( addr.formattedName().simplified() ).
91  arg( addr.preferredEmail() ) );
92  ldif_out( t, QLatin1String( "givenname" ), addr.givenName() );
93  ldif_out( t, QLatin1String( "sn" ), addr.familyName() );
94  ldif_out( t, QLatin1String( "cn" ), addr.formattedName().simplified() );
95  ldif_out( t, QLatin1String( "uid" ), addr.uid() );
96  ldif_out( t, QLatin1String( "nickname" ), addr.nickName() );
97  ldif_out( t, QLatin1String( "xmozillanickname" ), addr.nickName() );
98  ldif_out( t, QLatin1String( "mozillanickname" ), addr.nickName() );
99 
100  ldif_out( t, QLatin1String( "mail" ), addr.preferredEmail() );
101  if ( addr.emails().count() > 1 ) {
102  ldif_out( t, QLatin1String( "mozillasecondemail" ), addr.emails()[ 1 ] );
103  }
104 //ldif_out( t, "mozilla_AIMScreenName: %1\n", "screen_name" );
105 
106  ldif_out( t, QLatin1String( "telephonenumber" ),
107  addr.phoneNumber( PhoneNumber::Work ).number() );
108  ldif_out( t, QLatin1String( "facsimiletelephonenumber" ),
109  addr.phoneNumber( PhoneNumber::Fax ).number() );
110  ldif_out( t, QLatin1String( "homephone" ),
111  addr.phoneNumber( PhoneNumber::Home ).number() );
112  ldif_out( t, QLatin1String( "mobile" ),
113  addr.phoneNumber( PhoneNumber::Cell ).number() ); // Netscape 7
114  ldif_out( t, QLatin1String( "cellphone" ),
115  addr.phoneNumber( PhoneNumber::Cell ).number() ); // Netscape 4.x
116  ldif_out( t, QLatin1String( "pager" ),
117  addr.phoneNumber( PhoneNumber::Pager ).number() );
118  ldif_out( t, QLatin1String( "pagerphone" ),
119  addr.phoneNumber( PhoneNumber::Pager ).number() );
120 
121  ldif_out( t, QLatin1String( "streethomeaddress" ), homeAddr.street() );
122  ldif_out( t, QLatin1String( "postalcode" ), workAddr.postalCode() );
123  ldif_out( t, QLatin1String( "postofficebox" ), workAddr.postOfficeBox() );
124 
125  QStringList streets = homeAddr.street().split( QLatin1Char( '\n' ) );
126  const int numberOfStreets(streets.count());
127  if ( numberOfStreets > 0 ) {
128  ldif_out( t, QLatin1String( "homepostaladdress" ), streets[ 0 ] ); // Netscape 7
129  }
130  if ( numberOfStreets > 1 ) {
131  ldif_out( t, QLatin1String( "mozillahomepostaladdress2" ), streets[ 1 ] ); // Netscape 7
132  }
133  ldif_out( t, QLatin1String( "mozillahomelocalityname" ), homeAddr.locality() ); // Netscape 7
134  ldif_out( t, QLatin1String( "mozillahomestate" ), homeAddr.region() );
135  ldif_out( t, QLatin1String( "mozillahomepostalcode" ), homeAddr.postalCode() );
136  ldif_out( t, QLatin1String( "mozillahomecountryname" ),
137  Address::ISOtoCountry( homeAddr.country() ) );
138  ldif_out( t, QLatin1String( "locality" ), workAddr.locality() );
139  ldif_out( t, QLatin1String( "streetaddress" ), workAddr.street() ); // Netscape 4.x
140 
141  streets = workAddr.street().split( QLatin1Char( '\n' ) );
142  if ( streets.count() > 0 ) {
143  ldif_out( t, QLatin1String( "postaladdress" ), streets[ 0 ] );
144  }
145  if ( streets.count() > 1 ) {
146  ldif_out( t, QLatin1String( "mozillapostaladdress2" ), streets[ 1 ] );
147  }
148  ldif_out( t, QLatin1String( "countryname" ), Address::ISOtoCountry( workAddr.country() ) );
149  ldif_out( t, QLatin1String( "l" ), workAddr.locality() );
150  ldif_out( t, QLatin1String( "c" ), Address::ISOtoCountry( workAddr.country() ) );
151  ldif_out( t, QLatin1String( "st" ), workAddr.region() );
152 
153  ldif_out( t, QLatin1String( "title" ), addr.title() );
154  ldif_out( t, QLatin1String( "vocation" ), addr.prefix() );
155  ldif_out( t, QLatin1String( "ou" ), addr.role() );
156  ldif_out( t, QLatin1String( "o" ), addr.organization() );
157  ldif_out( t, QLatin1String( "organization" ), addr.organization() );
158  ldif_out( t, QLatin1String( "organizationname" ), addr.organization() );
159 
160  // Compatibility with older kabc versions.
161  if ( !addr.department().isEmpty() ) {
162  ldif_out( t, QLatin1String( "department" ), addr.department() );
163  } else {
164  ldif_out( t, QLatin1String( "department" ), addr.custom( QLatin1String( "KADDRESSBOOK" ),
165  QLatin1String( "X-Department" ) ) );
166  }
167 
168  ldif_out( t, QLatin1String( "workurl" ), addr.url().prettyUrl() );
169  ldif_out( t, QLatin1String( "homeurl" ), addr.url().prettyUrl() );
170  ldif_out( t, QLatin1String( "mozillahomeurl" ), addr.url().prettyUrl() );
171 
172  ldif_out( t, QLatin1String( "description" ), addr.note() );
173  if ( addr.revision().isValid() ) {
174  ldif_out( t, QLatin1String( "modifytimestamp" ), dateToVCardString( addr.revision() ) );
175  }
176 
177  const QDateTime birthday = addr.birthday();
178  if ( birthday.isValid() ) {
179  const QDate date = birthday.date();
180  ldif_out( t, QLatin1String( "birthyear" ), QString::number( date.year() ) );
181  ldif_out( t, QLatin1String( "birthmonth" ), QString::number( date.month() ) );
182  ldif_out( t, QLatin1String( "birthday" ), QString::number( date.day() ) );
183  }
184 
185  t << "objectclass: top\n";
186  t << "objectclass: person\n";
187  t << "objectclass: organizationalPerson\n";
188 
189  t << "\n";
190 
191  return true;
192 }
193 
194 /* convert from LDIF stream */
195 
196 bool LDIFConverter::LDIFToAddressee( const QString &str, AddresseeList &addrList,
197  const QDateTime &dt )
198 {
199  if ( str.isEmpty() ) {
200  return true;
201  }
202 
203  bool endldif = false, end = false;
204  Ldif ldif;
205  Ldif::ParseValue ret;
206  Addressee a;
207  Address homeAddr, workAddr;
208  int birthday = -1;
209  int birthmonth = -1;
210  int birthyear = -1;
211 
212  ldif.setLdif( str.toLatin1() );
213  QDateTime qdt = dt;
214  if ( !qdt.isValid() ) {
215  qdt = QDateTime::currentDateTime();
216  }
217  a.setRevision( qdt );
218  homeAddr = Address( Address::Home );
219  workAddr = Address( Address::Work );
220 
221  do {
222  ret = ldif.nextItem();
223  switch ( ret ) {
224  case Ldif::Item:
225  {
226  QString fieldname = ldif.attr().toLower();
227  QString value = QString::fromUtf8( ldif.value(), ldif.value().size() );
228  evaluatePair( a, homeAddr, workAddr, fieldname, value, birthday, birthmonth, birthyear );
229  break;
230  }
231  case Ldif::EndEntry:
232  {
233  // if the new address is not empty, append it
234  QDateTime birthDate( QDate( birthyear, birthmonth, birthday ) );
235  if ( birthDate.isValid() ) {
236  a.setBirthday( birthDate );
237  }
238 
239  if ( !a.formattedName().isEmpty() || !a.name().isEmpty() ||
240  !a.familyName().isEmpty() ) {
241  if ( !homeAddr.isEmpty() ) {
242  a.insertAddress( homeAddr );
243  }
244  if ( !workAddr.isEmpty() ) {
245  a.insertAddress( workAddr );
246  }
247  addrList.append( a );
248  }
249  a = Addressee();
250  a.setRevision( qdt );
251  homeAddr = Address( Address::Home );
252  workAddr = Address( Address::Work );
253  }
254  break;
255  case Ldif::MoreData:
256  {
257  if ( endldif ) {
258  end = true;
259  } else {
260  ldif.endLdif();
261  endldif = true;
262  break;
263  }
264  }
265  default:
266  break;
267  }
268  } while ( !end );
269 
270  return true;
271 }
272 
273 bool LDIFConverter::evaluatePair( Addressee &a, Address &homeAddr,
274  Address &workAddr,
275  QString &fieldname, QString &value,
276  int &birthday, int &birthmonth, int &birthyear )
277 {
278  if ( fieldname == QLatin1String( "dn" ) ) { // ignore & return false!
279  return false;
280  }
281 
282  if ( fieldname.startsWith( QLatin1Char( '#' ) ) ) {
283  return true;
284  }
285 
286  if ( fieldname.isEmpty() && !a.note().isEmpty() ) {
287  // some LDIF export filters are borken and add additional
288  // comments on stand-alone lines. Just add them to the notes for now.
289  a.setNote( a.note() + QLatin1Char( '\n' ) + value );
290  return true;
291  }
292 
293  if ( fieldname == QLatin1String( "givenname" ) ) {
294  a.setGivenName( value );
295  return true;
296  }
297 
298  if ( fieldname == QLatin1String( "xmozillanickname" ) ||
299  fieldname == QLatin1String( "nickname" ) ||
300  fieldname == QLatin1String( "mozillanickname" ) ) {
301  a.setNickName( value );
302  return true;
303  }
304 
305  if ( fieldname == QLatin1String( "sn" ) ) {
306  a.setFamilyName( value );
307  return true;
308  }
309 
310  if ( fieldname == QLatin1String( "uid" ) ) {
311  a.setUid( value );
312  return true;
313  }
314  if ( fieldname == QLatin1String( "mail" ) ||
315  fieldname == QLatin1String( "mozillasecondemail" ) ) { // mozilla
316  if ( a.emails().indexOf( value ) == -1 ) {
317  a.insertEmail( value );
318  }
319  return true;
320  }
321 
322  if ( fieldname == QLatin1String( "title" ) ) {
323  a.setTitle( value );
324  return true;
325  }
326 
327  if ( fieldname == QLatin1String( "vocation" ) ) {
328  a.setPrefix( value );
329  return true;
330  }
331 
332  if ( fieldname == QLatin1String( "cn" ) ) {
333  a.setFormattedName( value );
334  return true;
335  }
336 
337  if ( fieldname == QLatin1String( "o" ) ||
338  fieldname == QLatin1String( "organization" ) || // Exchange
339  fieldname == QLatin1String( "organizationname" ) ) { // Exchange
340  a.setOrganization( value );
341  return true;
342  }
343 
344  if ( fieldname == QLatin1String( "description" ) ) {
345 addComment:
346  if ( !a.note().isEmpty() ) {
347  a.setNote( a.note() + QLatin1Char( '\n' ) );
348  }
349  a.setNote( a.note() + value );
350  return true;
351  }
352 
353  if ( fieldname == QLatin1String( "custom1" ) ||
354  fieldname == QLatin1String( "custom2" ) ||
355  fieldname == QLatin1String( "custom3" ) ||
356  fieldname == QLatin1String( "custom4" ) ) {
357  goto addComment;
358  }
359 
360  if ( fieldname == QLatin1String( "homeurl" ) ||
361  fieldname == QLatin1String( "workurl" ) ||
362  fieldname == QLatin1String( "mozillahomeurl" ) ) {
363  if ( a.url().isEmpty() ) {
364  a.setUrl( KUrl( value ) );
365  return true;
366  }
367  if ( a.url().prettyUrl() == KUrl( value ).prettyUrl() ) {
368  return true;
369  }
370  // TODO: current version of kabc only supports one URL.
371  // TODO: change this with KDE 4
372  }
373 
374  if ( fieldname == QLatin1String( "homephone" ) ) {
375  a.insertPhoneNumber( PhoneNumber( value, PhoneNumber::Home ) );
376  return true;
377  }
378 
379  if ( fieldname == QLatin1String( "telephonenumber" ) ) {
380  a.insertPhoneNumber( PhoneNumber( value, PhoneNumber::Work ) );
381  return true;
382  }
383 
384  if ( fieldname == QLatin1String( "mobile" ) ) { // mozilla/Netscape 7
385  a.insertPhoneNumber( PhoneNumber( value, PhoneNumber::Cell ) );
386  return true;
387  }
388 
389  if ( fieldname == QLatin1String( "cellphone" ) ) {
390  a.insertPhoneNumber( PhoneNumber( value, PhoneNumber::Cell ) );
391  return true;
392  }
393 
394  if ( fieldname == QLatin1String( "pager" ) || // mozilla
395  fieldname == QLatin1String( "pagerphone" ) ) { // mozilla
396  a.insertPhoneNumber( PhoneNumber( value, PhoneNumber::Pager ) );
397  return true;
398  }
399 
400  if ( fieldname == QLatin1String( "facsimiletelephonenumber" ) ) {
401  a.insertPhoneNumber( PhoneNumber( value, PhoneNumber::Fax ) );
402  return true;
403  }
404 
405  if ( fieldname == QLatin1String( "xmozillaanyphone" ) ) { // mozilla
406  a.insertPhoneNumber( PhoneNumber( value, PhoneNumber::Work ) );
407  return true;
408  }
409 
410  if ( fieldname == QLatin1String( "streethomeaddress" ) ||
411  fieldname == QLatin1String( "mozillahomestreet" ) /*thunderbird*/ ) {
412  homeAddr.setStreet( value );
413  return true;
414  }
415 
416  if ( fieldname == QLatin1String( "street" ) || fieldname == QLatin1String( "postaladdress" ) ) { // mozilla
417  workAddr.setStreet( value );
418  return true;
419  }
420 
421  if ( fieldname == QLatin1String( "mozillapostaladdress2" ) ) { // mozilla
422  workAddr.setStreet( workAddr.street() + QLatin1String( "\n" ) + value );
423  return true;
424  }
425 
426  if ( fieldname == QLatin1String( "postalcode" ) ) {
427  workAddr.setPostalCode( value );
428  return true;
429  }
430 
431  if ( fieldname == QLatin1String( "postofficebox" ) ) {
432  workAddr.setPostOfficeBox( value );
433  return true;
434  }
435 
436  if ( fieldname == QLatin1String( "homepostaladdress" ) ) { // Netscape 7
437  homeAddr.setStreet( value );
438  return true;
439  }
440 
441  if ( fieldname == QLatin1String( "mozillahomepostaladdress2" ) ) { // mozilla
442  homeAddr.setStreet( homeAddr.street() + QLatin1String( "\n" ) + value );
443  return true;
444  }
445 
446  if ( fieldname == QLatin1String( "mozillahomelocalityname" ) ) { // mozilla
447  homeAddr.setLocality( value );
448  return true;
449  }
450 
451  if ( fieldname == QLatin1String( "mozillahomestate" ) ) { // mozilla
452  homeAddr.setRegion( value );
453  return true;
454  }
455 
456  if ( fieldname == QLatin1String( "mozillahomepostalcode" ) ) { // mozilla
457  homeAddr.setPostalCode( value );
458  return true;
459  }
460 
461  if ( fieldname == QLatin1String( "mozillahomecountryname" ) ) { // mozilla
462  if ( value.length() <= 2 ) {
463  value = Address::ISOtoCountry( value );
464  }
465  homeAddr.setCountry( value );
466  return true;
467  }
468 
469  if ( fieldname == QLatin1String( "locality" ) ) {
470  workAddr.setLocality( value );
471  return true;
472  }
473 
474  if ( fieldname == QLatin1String( "streetaddress" ) ) { // Netscape 4.x
475  workAddr.setStreet( value );
476  return true;
477  }
478 
479  if ( fieldname == QLatin1String( "countryname" ) ||
480  fieldname == QLatin1String( "c" ) ) { // mozilla
481  if ( value.length() <= 2 ) {
482  value = Address::ISOtoCountry( value );
483  }
484  workAddr.setCountry( value );
485  return true;
486  }
487 
488  if ( fieldname == QLatin1String( "l" ) ) { // mozilla
489  workAddr.setLocality( value );
490  return true;
491  }
492 
493  if ( fieldname == QLatin1String( "st" ) ) {
494  workAddr.setRegion( value );
495  return true;
496  }
497 
498  if ( fieldname == QLatin1String( "ou" ) ) {
499  a.setRole( value );
500  return true;
501  }
502 
503  if ( fieldname == QLatin1String( "department" ) ) {
504  a.setDepartment( value );
505  return true;
506  }
507 
508  if ( fieldname == QLatin1String( "member" ) ) {
509  // this is a mozilla list member (cn=xxx, mail=yyy)
510  QStringList list = value.split( QLatin1Char( ',' ) );
511  QString name, email;
512 
513  QStringList::Iterator it;
514  for ( it = list.begin(); it != list.end(); ++it ) {
515  if ( (*it).startsWith( QLatin1String( "cn=" ) ) ) {
516  name = (*it).mid( 3 ).trimmed();
517  }
518  if ( (*it).startsWith( QLatin1String( "mail=" ) ) ) {
519  email = (*it).mid( 5 ).trimmed();
520  }
521  }
522  if ( !name.isEmpty() && !email.isEmpty() ) {
523  email = QLatin1String( " <" ) + email + QLatin1Char( '>' );
524  }
525  a.insertEmail( name + email );
526  a.insertCategory( i18n( "List of Emails" ) );
527  return true;
528  }
529 
530  if ( fieldname == QLatin1String( "modifytimestamp" ) ) {
531  if ( value == QLatin1String( "0Z" ) ) { // ignore
532  return true;
533  }
534  QDateTime dt = VCardStringToDate( value );
535  if ( dt.isValid() ) {
536  a.setRevision( dt );
537  return true;
538  }
539  }
540 
541  if ( fieldname == QLatin1String( "objectclass" ) ) { // ignore
542  return true;
543  }
544 
545  if ( fieldname == QLatin1String( "birthyear" ) ) {
546  birthyear = value.toInt();
547  return true;
548  }
549  if ( fieldname == QLatin1String( "birthmonth" ) ) {
550  birthmonth = value.toInt();
551  return true;
552  }
553  if ( fieldname == QLatin1String( "birthday" ) ) {
554  birthday = value.toInt();
555  return true;
556  }
557 
558  kWarning(5700) << QString::fromLatin1( "LDIFConverter: Unknown field for '%1': '%2=%3'\n" ).
559  arg( a.formattedName() ).arg( fieldname ).arg( value );
560 
561  return true;
562 }
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Wed Nov 28 2012 21:59:34 by doxygen 1.8.1.2 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.9.3 API Reference

Skip menu "kdepimlibs-4.9.3 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