@interface OCSContactFieldExtractor : GCSFieldExtractor
@end
+#include <NGiCal/NGVCard.h>
#include "common.h"
@implementation OCSContactFieldExtractor
+static NSString *fieldNames[] = {
+ /* quickfield, vCard KVC path */
+ @"givenName", @"n.given",
+ @"cn", @"fn.stringValue",
+ @"sn", @"n.family",
+ @"l", @"preferredAdr.locality",
+ @"mail", @"preferredEMail.stringValue",
+ @"o", @"org.orgnam",
+ @"ou", @"org.orgunit",
+ @"telephoneNumber", @"preferredTel.stringValue",
+ nil, nil
+};
+
+- (NSMutableDictionary *)extractQuickFieldsFromVCard:(NGVCard *)_vCard {
+ NSMutableDictionary *fields;
+ unsigned i;
+
+ if (_vCard == nil)
+ return nil;
+
+ fields = [NSMutableDictionary dictionaryWithCapacity:16];
+
+ for (i = 0; fieldNames[i] != nil; i += 2) {
+ id value;
+
+ value = ([fieldNames[i + 1] length] > 0)
+ ? [_vCard valueForKeyPath:fieldNames[i + 1]]
+ : nil;
+ if (![value isNotNull]) value = [NSNull null];
+
+ [fields setObject:value forKey:[fieldNames[i] lowercaseString]];
+ }
+ return fields;
+}
+
+- (NSMutableDictionary *)extractQuickFieldsFromVCardString:(NSString *)_str {
+ NSArray *vCards;
+
+ if ((vCards = [NGVCard parseVCardsFromSource:_str]) == nil) {
+ [self errorWithFormat:@"Could not parse content as a vCard."];
+ return nil;
+ }
+ if ([vCards count] == 0) {
+ [self errorWithFormat:@"Could not parse content as a vCard."];
+ return nil;
+ }
+
+ if ([vCards count] > 1)
+ [self warnWithFormat:@"More than one vCard in content, using first."];
+
+ return [self extractQuickFieldsFromVCard:[vCards objectAtIndex:0]];
+}
+
- (NSMutableDictionary *)extractQuickFieldsFromContent:(NSString *)_content {
- static NSString *fieldNames[] = {
- @"givenName",
- @"cn",
- @"sn",
- @"l",
- @"mail",
- @"o",
- @"ou",
- @"telephoneNumber",
- nil
- };
NSMutableDictionary *fields;
NSDictionary *plist;
unsigned i;
if ([_content length] == 0)
return nil;
+ if ([_content hasPrefix:@"BEGIN:VCARD"])
+ return [self extractQuickFieldsFromVCardString:_content];
+
// TODO: we want to support vcard storage in the future?!
if ((plist = [_content propertyList]) == nil) {
return nil;
}
+ if (![plist isKindOfClass:[NSDictionary class]]) {
+ [self logWithFormat:@"ERROR: parsed property list is not a dictionary!"];
+ return nil;
+ }
+
fields = [NSMutableDictionary dictionaryWithCapacity:16];
/* copy field values to quick record */
- for (i = 0; fieldNames[i] != nil; i++) {
+ for (i = 0; fieldNames[i] != nil; i += 2) {
NSString *fieldName, *sqlName;
id value;
-
+
fieldName = fieldNames[i];
sqlName = [fieldName lowercaseString]; /* actually pgsql doesn't care */