1 | /* |
2 | This file is part of the KContacts framework. |
3 | SPDX-FileCopyrightText: 2003 Helge Deller <deller@kde.org> |
4 | |
5 | SPDX-License-Identifier: LGPL-2.0-or-later |
6 | */ |
7 | |
8 | /* |
9 | Useful links: |
10 | - http://tldp.org/HOWTO/LDAP-Implementation-HOWTO/schemas.html |
11 | - http://www.faqs.org/rfcs/rfc2849.html |
12 | |
13 | Not yet handled items: |
14 | - objectclass microsoftaddressbook |
15 | - info, |
16 | - initials, |
17 | - otherfacsimiletelephonenumber, |
18 | - otherpager, |
19 | - physicaldeliveryofficename, |
20 | */ |
21 | |
22 | #include "ldifconverter.h" |
23 | #include "address.h" |
24 | #include "kcontacts_debug.h" |
25 | #include "vcardconverter.h" |
26 | |
27 | #include "ldif_p.h" |
28 | |
29 | #include <KCountry> |
30 | #include <KLocalizedString> |
31 | |
32 | #include <QIODevice> |
33 | #include <QStringList> |
34 | #include <QTextStream> |
35 | |
36 | using namespace KContacts; |
37 | |
38 | /* internal functions - do not use !! */ |
39 | |
40 | namespace KContacts |
41 | { |
42 | /*! |
43 | \internal |
44 | |
45 | Evaluates \a fieldname and sets the \a value at the addressee or the address |
46 | objects when appropriate. |
47 | |
48 | \a a The addressee to store information into |
49 | |
50 | \a homeAddr The home address to store respective information into |
51 | |
52 | \a workAddr The work address to store respective information into |
53 | |
54 | \a fieldname LDIF field name to evaluate |
55 | |
56 | \a value The value of the field addressed by \a fieldname |
57 | */ |
58 | void evaluatePair(Addressee &a, |
59 | Address &homeAddr, |
60 | Address &workAddr, |
61 | QString &fieldname, |
62 | QString &value, |
63 | int &birthday, |
64 | int &birthmonth, |
65 | int &birthyear, |
66 | ContactGroup &contactGroup); |
67 | } |
68 | |
69 | /* generate LDIF stream */ |
70 | |
71 | static void ldif_out(QTextStream &t, const QString &formatStr, const QString &value) |
72 | { |
73 | if (value.isEmpty()) { |
74 | return; |
75 | } |
76 | |
77 | const QByteArray txt = Ldif::assembleLine(fieldname: formatStr, value, linelen: 72); |
78 | |
79 | // write the string |
80 | t << QString::fromUtf8(ba: txt) << "\n" ; |
81 | } |
82 | |
83 | bool LDIFConverter::addresseeAndContactGroupToLDIF(const AddresseeList &addrList, const ContactGroup::List &contactGroupList, QString &str) |
84 | { |
85 | bool result = addresseeToLDIF(addrList, str); |
86 | if (!contactGroupList.isEmpty()) { |
87 | result = (contactGroupToLDIF(contactGroupList, str) || result); // order matters |
88 | } |
89 | return result; |
90 | } |
91 | |
92 | bool LDIFConverter::contactGroupToLDIF(const ContactGroup &contactGroup, QString &str) |
93 | { |
94 | if (contactGroup.dataCount() <= 0) { |
95 | return false; |
96 | } |
97 | QTextStream t(&str, QIODevice::WriteOnly | QIODevice::Append); |
98 | |
99 | t << "objectclass: top\n" ; |
100 | t << "objectclass: groupOfNames\n" ; |
101 | |
102 | for (int i = 0; i < contactGroup.dataCount(); ++i) { |
103 | const ContactGroup::Data &data = contactGroup.data(index: i); |
104 | const QString value = QStringLiteral("cn=%1,mail=%2" ).arg(args: data.name(), args: data.email()); |
105 | ldif_out(t, QStringLiteral("member" ), value); |
106 | } |
107 | |
108 | t << "\n" ; |
109 | return true; |
110 | } |
111 | |
112 | bool LDIFConverter::contactGroupToLDIF(const ContactGroup::List &contactGroupList, QString &str) |
113 | { |
114 | if (contactGroupList.isEmpty()) { |
115 | return false; |
116 | } |
117 | |
118 | bool result = true; |
119 | for (const ContactGroup &group : contactGroupList) { |
120 | result = (contactGroupToLDIF(contactGroup: group, str) || result); // order matters |
121 | } |
122 | return result; |
123 | } |
124 | |
125 | bool LDIFConverter::addresseeToLDIF(const AddresseeList &addrList, QString &str) |
126 | { |
127 | if (addrList.isEmpty()) { |
128 | return false; |
129 | } |
130 | |
131 | bool result = true; |
132 | for (const Addressee &addr : addrList) { |
133 | result = (addresseeToLDIF(addr, str) || result); // order matters |
134 | } |
135 | return result; |
136 | } |
137 | |
138 | static QString countryName(const QString &isoCodeOrName) |
139 | { |
140 | const auto c = KCountry::fromAlpha2(alpha2Code: isoCodeOrName); |
141 | return c.isValid() ? c.name() : isoCodeOrName; |
142 | } |
143 | |
144 | bool LDIFConverter::addresseeToLDIF(const Addressee &addr, QString &str) |
145 | { |
146 | if (addr.isEmpty()) { |
147 | return false; |
148 | } |
149 | |
150 | QTextStream t(&str, QIODevice::WriteOnly | QIODevice::Append); |
151 | |
152 | const Address homeAddr = addr.address(type: Address::Home); |
153 | const Address workAddr = addr.address(type: Address::Work); |
154 | |
155 | ldif_out(t, QStringLiteral("dn" ), QStringLiteral("cn=%1,mail=%2" ).arg(args: addr.formattedName().simplified(), args: addr.preferredEmail())); |
156 | t << "objectclass: top\n" ; |
157 | t << "objectclass: person\n" ; |
158 | t << "objectclass: organizationalPerson\n" ; |
159 | |
160 | ldif_out(t, QStringLiteral("givenname" ), value: addr.givenName()); |
161 | ldif_out(t, QStringLiteral("sn" ), value: addr.familyName()); |
162 | ldif_out(t, QStringLiteral("cn" ), value: addr.formattedName().simplified()); |
163 | ldif_out(t, QStringLiteral("uid" ), value: addr.uid()); |
164 | ldif_out(t, QStringLiteral("nickname" ), value: addr.nickName()); |
165 | ldif_out(t, QStringLiteral("xmozillanickname" ), value: addr.nickName()); |
166 | ldif_out(t, QStringLiteral("mozillanickname" ), value: addr.nickName()); |
167 | |
168 | ldif_out(t, QStringLiteral("mail" ), value: addr.preferredEmail()); |
169 | const QStringList emails = addr.emails(); |
170 | const int numEmails = emails.count(); |
171 | for (int i = 1; i < numEmails; ++i) { |
172 | if (i == 0) { |
173 | // nothing |
174 | } else if (i == 1) { |
175 | ldif_out(t, QStringLiteral("mozillasecondemail" ), value: emails[1]); |
176 | } else { |
177 | ldif_out(t, QStringLiteral("othermailbox" ), value: emails[i]); |
178 | } |
179 | } |
180 | // ldif_out( t, "mozilla_AIMScreenName: %1\n", "screen_name" ); |
181 | |
182 | ldif_out(t, QStringLiteral("telephonenumber" ), value: addr.phoneNumber(type: PhoneNumber::Work).number()); |
183 | ldif_out(t, QStringLiteral("facsimiletelephonenumber" ), value: addr.phoneNumber(type: PhoneNumber::Fax).number()); |
184 | ldif_out(t, QStringLiteral("homephone" ), value: addr.phoneNumber(type: PhoneNumber::Home).number()); |
185 | ldif_out(t, QStringLiteral("mobile" ), |
186 | value: addr.phoneNumber(type: PhoneNumber::Cell).number()); // Netscape 7 |
187 | ldif_out(t, QStringLiteral("cellphone" ), |
188 | value: addr.phoneNumber(type: PhoneNumber::Cell).number()); // Netscape 4.x |
189 | ldif_out(t, QStringLiteral("pager" ), value: addr.phoneNumber(type: PhoneNumber::Pager).number()); |
190 | ldif_out(t, QStringLiteral("pagerphone" ), value: addr.phoneNumber(type: PhoneNumber::Pager).number()); |
191 | |
192 | ldif_out(t, QStringLiteral("streethomeaddress" ), value: homeAddr.street()); |
193 | ldif_out(t, QStringLiteral("postalcode" ), value: workAddr.postalCode()); |
194 | ldif_out(t, QStringLiteral("postofficebox" ), value: workAddr.postOfficeBox()); |
195 | |
196 | QStringList streets = homeAddr.street().split(sep: QLatin1Char('\n')); |
197 | const int numberOfStreets(streets.count()); |
198 | if (numberOfStreets > 0) { |
199 | ldif_out(t, QStringLiteral("homepostaladdress" ), value: streets.at(i: 0)); // Netscape 7 |
200 | } |
201 | if (numberOfStreets > 1) { |
202 | ldif_out(t, QStringLiteral("mozillahomepostaladdress2" ), value: streets.at(i: 1)); // Netscape 7 |
203 | } |
204 | ldif_out(t, QStringLiteral("mozillahomelocalityname" ), value: homeAddr.locality()); // Netscape 7 |
205 | ldif_out(t, QStringLiteral("mozillahomestate" ), value: homeAddr.region()); |
206 | ldif_out(t, QStringLiteral("mozillahomepostalcode" ), value: homeAddr.postalCode()); |
207 | ldif_out(t, QStringLiteral("mozillahomecountryname" ), value: countryName(isoCodeOrName: homeAddr.country())); |
208 | ldif_out(t, QStringLiteral("locality" ), value: workAddr.locality()); |
209 | ldif_out(t, QStringLiteral("streetaddress" ), value: workAddr.street()); // Netscape 4.x |
210 | |
211 | streets = workAddr.street().split(sep: QLatin1Char('\n')); |
212 | const int streetsCount = streets.count(); |
213 | if (streetsCount > 0) { |
214 | ldif_out(t, QStringLiteral("street" ), value: streets.at(i: 0)); |
215 | } |
216 | if (streetsCount > 1) { |
217 | ldif_out(t, QStringLiteral("mozillaworkstreet2" ), value: streets.at(i: 1)); |
218 | } |
219 | ldif_out(t, QStringLiteral("countryname" ), value: countryName(isoCodeOrName: workAddr.country())); |
220 | ldif_out(t, QStringLiteral("l" ), value: workAddr.locality()); |
221 | ldif_out(t, QStringLiteral("c" ), value: countryName(isoCodeOrName: workAddr.country())); |
222 | ldif_out(t, QStringLiteral("st" ), value: workAddr.region()); |
223 | |
224 | ldif_out(t, QStringLiteral("title" ), value: addr.title()); |
225 | ldif_out(t, QStringLiteral("vocation" ), value: addr.prefix()); |
226 | ldif_out(t, QStringLiteral("ou" ), value: addr.role()); |
227 | ldif_out(t, QStringLiteral("o" ), value: addr.organization()); |
228 | ldif_out(t, QStringLiteral("organization" ), value: addr.organization()); |
229 | ldif_out(t, QStringLiteral("organizationname" ), value: addr.organization()); |
230 | |
231 | // Compatibility with older kabc versions. |
232 | if (!addr.department().isEmpty()) { |
233 | ldif_out(t, QStringLiteral("department" ), value: addr.department()); |
234 | } else { |
235 | ldif_out(t, QStringLiteral("department" ), value: addr.custom(QStringLiteral("KADDRESSBOOK" ), QStringLiteral("X-Department" ))); |
236 | } |
237 | |
238 | ldif_out(t, QStringLiteral("workurl" ), value: addr.url().url().toDisplayString()); |
239 | ldif_out(t, QStringLiteral("homeurl" ), value: addr.url().url().toDisplayString()); |
240 | ldif_out(t, QStringLiteral("mozillahomeurl" ), value: addr.url().url().toDisplayString()); |
241 | |
242 | ldif_out(t, QStringLiteral("description" ), value: addr.note()); |
243 | if (addr.revision().isValid()) { |
244 | ldif_out(t, QStringLiteral("modifytimestamp" ), value: dateToVCardString(dateTime: addr.revision())); |
245 | } |
246 | |
247 | const QDate birthday = addr.birthday().date(); |
248 | if (birthday.isValid()) { |
249 | const int year = birthday.year(); |
250 | if (year > 0) { |
251 | ldif_out(t, QStringLiteral("birthyear" ), value: QString::number(year)); |
252 | } |
253 | ldif_out(t, QStringLiteral("birthmonth" ), value: QString::number(birthday.month())); |
254 | ldif_out(t, QStringLiteral("birthday" ), value: QString::number(birthday.day())); |
255 | } |
256 | |
257 | t << "\n" ; |
258 | |
259 | return true; |
260 | } |
261 | |
262 | /* convert from LDIF stream */ |
263 | bool LDIFConverter::LDIFToAddressee(const QString &str, AddresseeList &addrList, ContactGroup::List &contactGroupList, const QDateTime &dt) |
264 | { |
265 | if (str.isEmpty()) { |
266 | return true; |
267 | } |
268 | |
269 | bool endldif = false; |
270 | bool end = false; |
271 | Ldif ldif; |
272 | Ldif::ParseValue ret; |
273 | Addressee a; |
274 | Address homeAddr; |
275 | Address workAddr; |
276 | int birthday = -1; |
277 | int birthmonth = -1; |
278 | int birthyear = -1; |
279 | ContactGroup contactGroup; |
280 | ldif.setLdif(str.toLatin1()); |
281 | QDateTime qdt = dt; |
282 | if (!qdt.isValid()) { |
283 | qdt = QDateTime::currentDateTime(); |
284 | } |
285 | a.setRevision(qdt); |
286 | homeAddr = Address(Address::Home); |
287 | workAddr = Address(Address::Work); |
288 | |
289 | do { |
290 | ret = ldif.nextItem(); |
291 | switch (ret) { |
292 | case Ldif::Item: { |
293 | QString fieldname = ldif.attr().toLower(); |
294 | QString value = QString::fromUtf8(ba: ldif.value()); |
295 | evaluatePair(a, homeAddr, workAddr, fieldname, value, birthday, birthmonth, birthyear, contactGroup); |
296 | break; |
297 | } |
298 | case Ldif::EndEntry: |
299 | if (contactGroup.count() == 0) { |
300 | // if the new address is not empty, append it |
301 | QDate birthDate(birthyear, birthmonth, birthday); |
302 | if (birthDate.isValid()) { |
303 | a.setBirthday(birthDate); |
304 | } |
305 | |
306 | if (!a.formattedName().isEmpty() || !a.name().isEmpty() || !a.familyName().isEmpty()) { |
307 | if (!homeAddr.isEmpty()) { |
308 | a.insertAddress(address: homeAddr); |
309 | } |
310 | if (!workAddr.isEmpty()) { |
311 | a.insertAddress(address: workAddr); |
312 | } |
313 | addrList.append(t: a); |
314 | } |
315 | } else { |
316 | contactGroupList.append(t: contactGroup); |
317 | } |
318 | a = Addressee(); |
319 | contactGroup = ContactGroup(); |
320 | a.setRevision(qdt); |
321 | homeAddr = Address(Address::Home); |
322 | workAddr = Address(Address::Work); |
323 | break; |
324 | case Ldif::MoreData: |
325 | if (endldif) { |
326 | end = true; |
327 | } else { |
328 | ldif.endLdif(); |
329 | endldif = true; |
330 | break; |
331 | } |
332 | default: |
333 | break; |
334 | } |
335 | } while (!end); |
336 | |
337 | return true; |
338 | } |
339 | |
340 | void KContacts::evaluatePair(Addressee &a, |
341 | Address &homeAddr, |
342 | Address &workAddr, |
343 | QString &fieldname, |
344 | QString &value, |
345 | int &birthday, |
346 | int &birthmonth, |
347 | int &birthyear, |
348 | ContactGroup &contactGroup) |
349 | { |
350 | if (fieldname == QLatin1String("dn" )) { // ignore |
351 | return; |
352 | } |
353 | |
354 | if (fieldname.startsWith(c: QLatin1Char('#'))) { |
355 | return; |
356 | } |
357 | |
358 | if (fieldname.isEmpty() && !a.note().isEmpty()) { |
359 | // some LDIF export filters are broken and add additional |
360 | // comments on stand-alone lines. Just add them to the notes for now. |
361 | a.setNote(a.note() + QLatin1Char('\n') + value); |
362 | return; |
363 | } |
364 | |
365 | if (fieldname == QLatin1String("givenname" )) { |
366 | a.setGivenName(value); |
367 | return; |
368 | } |
369 | |
370 | if (fieldname == QLatin1String("xmozillanickname" ) // |
371 | || fieldname == QLatin1String("nickname" ) // |
372 | || fieldname == QLatin1String("mozillanickname" )) { |
373 | a.setNickName(value); |
374 | return; |
375 | } |
376 | |
377 | if (fieldname == QLatin1String("sn" )) { |
378 | a.setFamilyName(value); |
379 | return; |
380 | } |
381 | |
382 | if (fieldname == QLatin1String("uid" )) { |
383 | a.setUid(value); |
384 | return; |
385 | } |
386 | if (fieldname == QLatin1String("mail" ) // |
387 | || fieldname == QLatin1String("mozillasecondemail" ) /* mozilla */ |
388 | || fieldname == QLatin1String("othermailbox" ) /*TheBat!*/) { |
389 | if (a.emails().indexOf(str: value) == -1) { |
390 | a.addEmail(email: value); |
391 | } |
392 | return; |
393 | } |
394 | |
395 | if (fieldname == QLatin1String("title" )) { |
396 | a.setTitle(value); |
397 | return; |
398 | } |
399 | |
400 | if (fieldname == QLatin1String("vocation" )) { |
401 | a.setPrefix(value); |
402 | return; |
403 | } |
404 | |
405 | if (fieldname == QLatin1String("cn" )) { |
406 | a.setFormattedName(value); |
407 | return; |
408 | } |
409 | |
410 | if (fieldname == QLatin1Char('o') || fieldname == QLatin1String("organization" ) // Exchange |
411 | || fieldname == QLatin1String("organizationname" )) { // Exchange |
412 | a.setOrganization(value); |
413 | return; |
414 | } |
415 | |
416 | // clang-format off |
417 | if (fieldname == QLatin1String("description" ) |
418 | || fieldname == QLatin1String("mozillacustom1" ) |
419 | || fieldname == QLatin1String("mozillacustom2" ) |
420 | || fieldname == QLatin1String("mozillacustom3" ) |
421 | || fieldname == QLatin1String("mozillacustom4" ) |
422 | || fieldname == QLatin1String("custom1" ) |
423 | || fieldname == QLatin1String("custom2" ) |
424 | || fieldname == QLatin1String("custom3" ) |
425 | || fieldname == QLatin1String("custom4" )) { |
426 | if (!a.note().isEmpty()) { |
427 | a.setNote(a.note() + QLatin1Char('\n')); |
428 | } |
429 | a.setNote(a.note() + value); |
430 | return; |
431 | } |
432 | // clang-format on |
433 | |
434 | if (fieldname == QLatin1String("homeurl" ) // |
435 | || fieldname == QLatin1String("workurl" ) // |
436 | || fieldname == QLatin1String("mozillahomeurl" )) { |
437 | if (a.url().url().isEmpty()) { |
438 | ResourceLocatorUrl url; |
439 | url.setUrl(QUrl(value)); |
440 | a.setUrl(url); |
441 | return; |
442 | } |
443 | if (a.url().url().toDisplayString() == QUrl(value).toDisplayString()) { |
444 | return; |
445 | } |
446 | // TODO: current version of kabc only supports one URL. |
447 | // TODO: change this with KDE 4 |
448 | } |
449 | |
450 | if (fieldname == QLatin1String("homephone" )) { |
451 | a.insertPhoneNumber(phoneNumber: PhoneNumber(value, PhoneNumber::Home)); |
452 | return; |
453 | } |
454 | |
455 | if (fieldname == QLatin1String("telephonenumber" )) { |
456 | a.insertPhoneNumber(phoneNumber: PhoneNumber(value, PhoneNumber::Work)); |
457 | return; |
458 | } |
459 | if (fieldname == QLatin1String("mobile" ) /* mozilla/Netscape 7 */ |
460 | || fieldname == QLatin1String("cellphone" )) { |
461 | a.insertPhoneNumber(phoneNumber: PhoneNumber(value, PhoneNumber::Cell)); |
462 | return; |
463 | } |
464 | |
465 | if (fieldname == QLatin1String("pager" ) // mozilla |
466 | || fieldname == QLatin1String("pagerphone" )) { // mozilla |
467 | a.insertPhoneNumber(phoneNumber: PhoneNumber(value, PhoneNumber::Pager)); |
468 | return; |
469 | } |
470 | |
471 | if (fieldname == QLatin1String("facsimiletelephonenumber" )) { |
472 | a.insertPhoneNumber(phoneNumber: PhoneNumber(value, PhoneNumber::Fax)); |
473 | return; |
474 | } |
475 | |
476 | if (fieldname == QLatin1String("xmozillaanyphone" )) { // mozilla |
477 | a.insertPhoneNumber(phoneNumber: PhoneNumber(value, PhoneNumber::Work)); |
478 | return; |
479 | } |
480 | |
481 | if (fieldname == QLatin1String("streethomeaddress" ) // |
482 | || fieldname == QLatin1String("mozillahomestreet" )) { // thunderbird |
483 | homeAddr.setStreet(value); |
484 | return; |
485 | } |
486 | |
487 | if (fieldname == QLatin1String("street" ) // |
488 | || fieldname == QLatin1String("postaladdress" )) { // mozilla |
489 | workAddr.setStreet(value); |
490 | return; |
491 | } |
492 | if (fieldname == QLatin1String("mozillapostaladdress2" ) // |
493 | || fieldname == QLatin1String("mozillaworkstreet2" )) { // mozilla |
494 | workAddr.setStreet(workAddr.street() + QLatin1Char('\n') + value); |
495 | return; |
496 | } |
497 | |
498 | if (fieldname == QLatin1String("postalcode" )) { |
499 | workAddr.setPostalCode(value); |
500 | return; |
501 | } |
502 | |
503 | if (fieldname == QLatin1String("postofficebox" )) { |
504 | workAddr.setPostOfficeBox(value); |
505 | return; |
506 | } |
507 | |
508 | if (fieldname == QLatin1String("homepostaladdress" )) { // Netscape 7 |
509 | homeAddr.setStreet(value); |
510 | return; |
511 | } |
512 | |
513 | if (fieldname == QLatin1String("mozillahomepostaladdress2" )) { // mozilla |
514 | homeAddr.setStreet(homeAddr.street() + QLatin1Char('\n') + value); |
515 | return; |
516 | } |
517 | |
518 | if (fieldname == QLatin1String("mozillahomelocalityname" )) { // mozilla |
519 | homeAddr.setLocality(value); |
520 | return; |
521 | } |
522 | |
523 | if (fieldname == QLatin1String("mozillahomestate" )) { // mozilla |
524 | homeAddr.setRegion(value); |
525 | return; |
526 | } |
527 | |
528 | if (fieldname == QLatin1String("mozillahomepostalcode" )) { // mozilla |
529 | homeAddr.setPostalCode(value); |
530 | return; |
531 | } |
532 | |
533 | if (fieldname == QLatin1String("mozillahomecountryname" )) { // mozilla |
534 | if (value.length() <= 2) { |
535 | value = countryName(isoCodeOrName: value); |
536 | } |
537 | homeAddr.setCountry(value); |
538 | return; |
539 | } |
540 | |
541 | if (fieldname == QLatin1String("locality" )) { |
542 | workAddr.setLocality(value); |
543 | return; |
544 | } |
545 | |
546 | if (fieldname == QLatin1String("streetaddress" )) { // Netscape 4.x |
547 | workAddr.setStreet(value); |
548 | return; |
549 | } |
550 | |
551 | if (fieldname == QLatin1String("countryname" ) // |
552 | || fieldname == QLatin1Char('c')) { // mozilla |
553 | if (value.length() <= 2) { |
554 | value = countryName(isoCodeOrName: value); |
555 | } |
556 | workAddr.setCountry(value); |
557 | return; |
558 | } |
559 | |
560 | if (fieldname == QLatin1Char('l')) { // mozilla |
561 | workAddr.setLocality(value); |
562 | return; |
563 | } |
564 | |
565 | if (fieldname == QLatin1String("st" )) { |
566 | workAddr.setRegion(value); |
567 | return; |
568 | } |
569 | |
570 | if (fieldname == QLatin1String("ou" )) { |
571 | a.setRole(value); |
572 | return; |
573 | } |
574 | |
575 | if (fieldname == QLatin1String("department" )) { |
576 | a.setDepartment(value); |
577 | return; |
578 | } |
579 | |
580 | if (fieldname == QLatin1String("member" )) { |
581 | // this is a mozilla list member (cn=xxx, mail=yyy) |
582 | const QStringList list = value.split(sep: QLatin1Char(',')); |
583 | QString name; |
584 | QString email; |
585 | |
586 | const QLatin1String cnTag("cn=" ); |
587 | const QLatin1String mailTag("mail=" ); |
588 | for (const auto &str : list) { |
589 | if (str.startsWith(s: cnTag)) { |
590 | name = QStringView(str).mid(pos: cnTag.size()).trimmed().toString(); |
591 | } else if (str.startsWith(s: mailTag)) { |
592 | email = QStringView(str).mid(pos: mailTag.size()).trimmed().toString(); |
593 | } |
594 | } |
595 | |
596 | if (!name.isEmpty() && !email.isEmpty()) { |
597 | email = QLatin1String(" <" ) + email + QLatin1Char('>'); |
598 | } |
599 | ContactGroup::Data data; |
600 | data.setEmail(email); |
601 | data.setName(name); |
602 | contactGroup.append(data); |
603 | return; |
604 | } |
605 | |
606 | if (fieldname == QLatin1String("modifytimestamp" )) { |
607 | if (value == QLatin1String("0Z" )) { // ignore |
608 | return; |
609 | } |
610 | QDateTime dt = VCardStringToDate(dateString: value); |
611 | if (dt.isValid()) { |
612 | a.setRevision(dt); |
613 | return; |
614 | } |
615 | } |
616 | |
617 | if (fieldname == QLatin1String("display-name" )) { |
618 | contactGroup.setName(value); |
619 | return; |
620 | } |
621 | |
622 | if (fieldname == QLatin1String("objectclass" )) { // ignore |
623 | return; |
624 | } |
625 | |
626 | if (fieldname == QLatin1String("birthyear" )) { |
627 | bool ok; |
628 | birthyear = value.toInt(ok: &ok); |
629 | if (!ok) { |
630 | birthyear = -1; |
631 | } |
632 | return; |
633 | } |
634 | if (fieldname == QLatin1String("birthmonth" )) { |
635 | birthmonth = value.toInt(); |
636 | return; |
637 | } |
638 | if (fieldname == QLatin1String("birthday" )) { |
639 | birthday = value.toInt(); |
640 | return; |
641 | } |
642 | if (fieldname == QLatin1String("xbatbirthday" )) { |
643 | const QStringView str{value}; |
644 | QDate dt(str.mid(pos: 0, n: 4).toInt(), str.mid(pos: 4, n: 2).toInt(), str.mid(pos: 6, n: 2).toInt()); |
645 | if (dt.isValid()) { |
646 | a.setBirthday(dt); |
647 | } |
648 | return; |
649 | } |
650 | qCWarning(KCONTACTS_LOG) << QStringLiteral("LDIFConverter: Unknown field for '%1': '%2=%3'\n" ).arg(args: a.formattedName(), args&: fieldname, args&: value); |
651 | } |
652 | |