Commit dc95755f authored by Sriram Karra's avatar Sriram Karra

Support for reading and writing back phone vectors from BBDB

There is an important change in how the phone numbers are managed,
and this impacts the other DBs as well. As BBDB supports
arbitrary labels for phone numbers, Each entry that is put
into the local represntation of vector using add_phone_home() is
now a tuple (label, number). This will have to be supported by
the other users of those routines.
parent bb30fc2f
// -*- javascript -*-
// Last Modified : Sun Apr 01 14:17:28 IST 2012
// Last Modified : Mon Apr 09 13:08:17 IST 2012
//
// Copyright (C) 2011, 2012 Sriram Karra <karra.etc@gmail.com>
//
......@@ -180,6 +180,72 @@
}, // db_config['ol']
'bb': {
// See above in 'ol'. this is the same stuff.
"email_domains" : {
"home" : ['hotmail.com', 'gmail.com',
'yahoo.com', 'yahoo.co.uk', 'yahoo.co.in',],
"work" : [],
"other" : [],
}, // db_config['email_domains']
// The "native" fields supported by BBDB are fairly
// limited, There is no standard way to represent
// websites, Instant Messaging contacts, birthdays, etc. -
// stuff that is available as native fields in Outlook as
// well as Google. However the 'notes' field is a generic
// associative list, and is used to store anything under
// the sun. In the following config parameter, you can
// specify which notes field are to be mapped to which
// 'standard' contact field in the other databases. Any
// notes field that does not appear here will be stored as
// a custom field without any mapping.
//
// The format is 'Standard Field' : 'BBDB Notes Field'
//
// Some fields, such as websites and fax numbers, can be
// present more htan once - i.e. there can be more one
// home website. In such instances, 'BBDB Notes Field' can
// be a regexp. Not that only the fields whose standard
// names end in _re are processed as regexes, and are
// matched against the note field name in BBDB.
"notes_map" : {
'fileas' : 'fileas',
'prefix' : 'prefix',
'notes' : 'notes',
'birthday' : 'birthday',
'anniv' : 'anniversary',
'itemid' : 'bbdb-id',
'web_home_re' : 'Home', // Regexp
'web_work_re' : 'Work', // Regexp
'web_other_re': 'Other', // Regexp
'ims' : 'messenger',
'dept' : 'department',
'title' : 'title',
'gender' : 'gender',
'created' : 'creation-date',
'updated' : 'timestamp',
},
// Phone numbers are stored as an array of vectors in BBDB
// Each element of the array has a label and a
// value. There is no built-in classification of the phone
// numbers into 'home', 'mobile, etc. The following map
// specifies this mapping. The label is matched against
// each of these regexes and whichever matches wins. If
// there is no match against any of the
"phones_map" : {
'phone_home' : 'Home', // Regexp
'phone_work' : 'Work', // Regexp
'phone_mob' : 'Mobile', // Regexp
'fax_home' : 'Fax.*Home', // Regexp
'fax_work' : 'Fax.*Work', // Regexp
'fax_other' : 'Fax.*Other', // Regexp
'phone_other' : '.*', // Default Regexp
},
} // db_config['bb']
}, // 'db_config'
}
......
##
## Created : Fri Apr 06 19:08:32 IST 2012
## Last Modified : Sun Apr 08 22:22:37 IST 2012
## Last Modified : Mon Apr 09 13:05:58 IST 2012
##
## Copyright (C) 2012 Sriram Karra <karra.etc@gmail.com>
##
......@@ -229,8 +229,49 @@ class BBContact(Contact):
add)
def _snarf_phones_from_parse_res (self, pr):
## FIXME: Need to fix this, for sure. LIke right now.
pass
ph_re = self.get_db().get_ph_re()
phs = re.findall(ph_re, pr['phones']) if pr['phones'] else None
if phs:
for ph in phs:
res = re.search(ph_re, '[' + ph[0] + ']')
if res:
resg = res.groupdict()
if resg['structured']:
phnum = '+1 ' + resg['structured']
else:
phnum = chompq(resg['unstructured'])
label = chompq(resg['phlabel'])
self._classify_and_add_phone(label, (label, phnum))
else:
logging.debug('Could not parse phone: %s', ph[0])
def _classify_and_add_phone (self, label, num):
nmap = self.get_phones_map()
if not nmap:
logging.error('Mapping of phone labels is not in Config. ' +
'Adding phone %s as Home phone')
self.add_phone_home(num)
return
if re.search(nmap['phone_home'], label):
self.add_phone_home(num)
elif re.search(nmap['phone_work'], label):
self.add_phone_work(num)
elif re.search(nmap['phone_mob'], label):
self.add_phone_mob(num)
elif re.search(nmap['fax_home'], label):
self.add_fax_home(num)
elif re.search(nmap['fax_work'], label):
self.add_fax_work(num)
elif re.search(nmap['fax_other'], label):
self.add_fax_other(num)
else:
self.add_phone_other(num)
def _snarf_notes_from_parse_res (self, pr):
noted = self.get_notes_map()
......@@ -356,7 +397,17 @@ class BBContact(Contact):
return '(' + ret + ')'
def _get_phones_as_string (self):
return 'nil'
## Note that any BBDB phone number that was structured in the North
## Amerial format will be munged into an equivalent string notation
## for our convenience
ph = self.get_phone_home()
ph.extend(self.get_phone_work())
ph.extend(self.get_phone_mob())
ph.extend(self.get_phone_other())
phs = ['[%s %s]' % (unchompq(l), unchompq(n)) for l,n in ph]
return ('(' + ' '.join(phs) + ')')
def _get_postal_as_string (self):
## FIXME: Need to fix this, for sure. LIke right now.
......
##
## Created : Tue Mar 13 14:26:01 IST 2012
## Last Modified : Sun Apr 08 14:34:02 IST 2012
## Last Modified : Mon Apr 09 11:25:13 IST 2012
##
## Copyright (C) 2012 Sriram Karra <karra.etc@gmail.com>
##
......@@ -206,6 +206,9 @@ class Item:
def get_notes_map (self):
return self.get_db().get_notes_map()
def get_phones_map (self):
return self.get_db().get_phones_map()
def get_sync_tags (self, destid=None):
"""Return the sync tag corresponding to specified DBID: destid. If
destid is None, the full dictionary of sync tags is returned to the
......
##
## Created : Tue Mar 13 14:26:01 IST 2012
## Last Modified : Sun Apr 08 14:24:49 IST 2012
## Last Modified : Mon Apr 09 12:38:17 IST 2012
##
## Copyright (C) 2012 Sriram Karra <karra.etc@gmail.com>
##
......@@ -56,6 +56,7 @@ class PIMDB:
self.set_db_config()
self.set_email_domains()
self.set_notes_map()
self.set_phones_map()
@abstractmethod
def get_dbid (self):
......@@ -159,6 +160,21 @@ class PIMDB:
return self._set_att('notes_map', None)
def get_phones_map (self):
return self._get_att('phones_map')
def set_phones_map (self):
dbc = self.get_db_config()
if dbc:
try:
ed = dbc['phones_map']
return self._set_att('phones_map', ed)
except KeyError, e:
logging.debug('set_phones_map(): No phones_map for PIMDB %s',
self.get_dbid())
return self._set_att('phones_map', None)
def get_folders (self, ftype=None):
"""Return all the folders of specified type. ftype should be one of
the valid folder types. If none is specifiedfor ftype, then the entire
......
##
## Created : Sat Apr 07 18:52:19 IST 2012
## Last Modified : Sun Apr 08 00:12:21 IST 2012
## Last Modified : Mon Apr 09 12:35:15 IST 2012
##
## Copyright (C) 2012 by Sriram Karra <karra.etc@gmail.com>
##
......@@ -115,11 +115,11 @@ class BBPIMDB(PIMDB):
res.update({'string_array' : re_str_ar})
## Phones
re_ph_vec = ('\[\s*(?P<phlabel>' + res['string'] +
')\s*(?P<number>(' +
re_ph_vec = ('\[\s*((?P<phlabel>' + res['string'] +
')\s*(?P<number>(?P<unstructured>' +
res['string'] + ')|'+
'(\d+\s+\d+\s+\d+\s+\d+' +
')\s*)\]')
'(?P<structured>\d+\s+\d+\s+\d+\s+\d+)' +
'\s*))\]')
re_phs = 'nil|(\(\s*(' + re_ph_vec + '\s*)+)\)'
res.update({'ph_vec' : re_phs})
......
##
## Created : Tue Jul 26 06:54:41 IST 2011
## Last Modified : Sun Apr 08 08:06:22 IST 2012
## Last Modified : Sun Apr 08 22:22:00 IST 2012
##
## Copyright (C) 2011, 2012 by Sriram Karra <karra.etc@gmail.com>
##
......@@ -19,6 +19,9 @@ def chompq (s):
else:
return s
def unchompq (s):
return '"' + str(s) + '"'
## The follow is a super cool implementation of enum equivalent in
## Python. Taken with a lot of gratitude from this post on Stackoverflow:
## http://stackoverflow.com/a/1695250/987738
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment