Package Gnumed :: Package business :: Module gmVCard |
[frames] | no frames]

# Source Code for Module Gnumed.business.gmVCard

      1  # -*- coding: utf-8 -*-
      2  """Import vCard data."""
      3  #============================================================
      4  __author__ = "K.Hilbert <Karsten.Hilbert@gmx.net>"
      5  __license__ = "GPL v2"
      6
      7  # std lib
      8  import sys
      9  import io
     10  import datetime as pyDT
     11  import logging
     12
     13
     14  # GNUmed
     15  if __name__ == '__main__':
     16          sys.path.insert(0, '../../')
     17          from Gnumed.pycommon import gmI18N
     18          gmI18N.activate_locale()
     19          gmI18N.install_domain()
     20  from Gnumed.pycommon import gmDateTime
     21  from Gnumed.business import gmPerson
     22  from Gnumed.business import gmDemographicRecord
     23
     24
     25  _log = logging.getLogger('gm-vcf')
     26
     27  #============================================================
     28 -def parse_vcard2dto(vc_text=None, filename=None):
     29
     30          import vobject
     31
     32          if vc_text is None:
     33                  _log.info('trying to parse vCard from [%s]', filename)
     34                  for encoding in ['utf8', 'Windows-1252']:
     35                          try:
     36                                  vcf = io.open(filename, mode = 'rt', encoding = encoding)
     37                                  vc_text = vcf.read()
     38                                  vcf.close()
     39                                  break
     40                          except UnicodeDecodeError:
     41                                  _log.exception('vCard not encoded as [%s]', encoding)
     42                  if vc_text is None:
     43                          return None
     44                  vcf_lines = []
     45                  found_first = False
     46                  for line in vc_text.split('\n'):
     47                          if not found_first:
     48                                  if line.strip() == 'BEGIN:VCARD':
     49                                          found_first = True
     50                                          vcf_lines.append(line)
     51                                  continue
     52                          vcf_lines.append(line)
     53                          if line.strip() == 'END:VCARD':
     54                                  break
     55                  vc_text = '\n'.join(vcf_lines)
     56
     57          dob_format = '%Y%m%d'
     58
     59          try:
     60                  vc = vobject.readOne(vc_text)
     61          except vobject.base.ParseError:
     62                  _log.exception('cannot parse, really a vcf ?')
     63                  return None
     64
     65          try:
     66                  if vc.kind.value.strip() != 'individual':
     67                          _log.warning('not a vCard for a single person (vCard.KIND=%s)', vc.kind.value)
     68                          return None
     69          except AttributeError:
     70                  _log.debug('vCard.KIND attribute not available')
     71
     72          dto = gmPerson.cDTO_person()
     73          dto.firstnames = vc.n.value.given.strip()
     74          dto.lastnames = vc.n.value.family.strip()
     75          try:
     76                  dto.title = vc.title.value.strip()
     77          except AttributeError:
     78                  _log.debug('vCard.TITLE attribute not available')
     79          try:
     80                  gender = vc.gender.value.strip().lower()
     81                  if gender != '':
     82                          dto.gender = gender
     83          except AttributeError:
     84                  _log.debug('vCard.GENDER attribute not available')
     85          try:
     86                  dob = pyDT.datetime.strptime(vc.bday.value.strip(), dob_format)
     87                  dto.dob = dob.replace(tzinfo = gmDateTime.pydt_now_here().tzinfo)
     88                  dto.dob_is_estimated = False
     89          except AttributeError:
     90                  _log.debug('vCard.BDAY attribute not available')
     91          dto.source = 'vCard %s' % vc.version.value.strip()
     92
     93          adr = None
     94          try:
     95                  adr = vc.adr.value
     96          except AttributeError:
     97                  _log.debug('vCard.ADR attribute not available')
     98          if adr is not None:
     99                  region_code = None
    100                  region = adr.region.strip()
    101                  if region == '':
    102                          region = None
    103                  # deduce country
    104                  country_code = None
    105                  country = adr.country.strip()
    106                  if country == '':
    107                          country = None
    108                  if country is None:
    109                          country_row = gmDemographicRecord.map_urb_zip_region2country(urb = adr.city, zip = adr.code, region = region)
    110                          if country_row is not None:
    111                                  country = country_row['country']
    112                                  country_code = country_row['code_country']
    113                  else:
    114                          country_code = gmDemographicRecord.map_country2code(country = country)
    115                  if None in [country, country_code]:
    116                          _log.error('unknown vCard.ADR.country (%s), skipping address', adr.country)
    117                  else:
    118                          # deduce region
    119                          if region is None:
    120                                  region_row = gmDemographicRecord.map_urb_zip_country2region(urb = adr.city, zip = adr.code, country_code = country_code)
    121                                  if region_row is not None:
    122                                          region = region_row['region']
    123                                          region_code = region_row['code_region']
    124                          else:
    125                                  region_code = gmDemographicRecord.map_region2code(region = region, country_code = country_code)
    126                          if region_code is None:
    127                                  _log.warning('unknown vCard.ADR.region (%s), using default region', adr.region)
    128                          dto.remember_address (
    129                                  number = '?',
    130                                  street = adr.street,
    131                                  urb = adr.city,
    132                                  region_code = region_code,
    133                                  zip = adr.code,
    134                                  country_code = country_code,
    135                                  adr_type = 'home',
    136                                  subunit = None
    137                          )
    138
    139          tel = None
    140          try:
    141                  tel = vc.tel.value
    142          except AttributeError:
    143                  _log.debug('vCard.TEL attribute not available')
    144          if tel is not None:
    145                  if 'TYPE' in vc.tel.params:
    146                          channel = (vc.tel.params['TYPE'][0]).lower()
    147                          if not channel.endswith('phone'):
    148                                  channel += 'phone'
    149                  else:
    150                          channel = 'homephone'
    151                  dto.remember_comm_channel(channel = channel, url = tel)
    152
    153          email = None
    154          try:
    155                  email = vc.email.value
    156          except AttributeError:
    157                  _log.debug('vCard.EMAIL attribute not available')
    158          if email is not None:
    159                  dto.remember_comm_channel(channel = 'email', url = email)
    160
    161          url = None
    162          try:
    163                  url = vc.url.value
    164          except AttributeError:
    165                  _log.debug('vCard.URL attribute not available')
    166          if url is not None:
    167                  dto.remember_comm_channel(channel = 'web', url = url)
    168
    169          return dto
    170
    171  #============================================================
    172  # main/testing
    173  #============================================================
    174  if __name__ == '__main__':
    175
    176          if len(sys.argv) == 1:
    177                  sys.exit()
    178
    179          if sys.argv[1] != 'test':
    180                  sys.exit()
    181
    182          from Gnumed.pycommon import gmLog2
    183
    184          gmDateTime.init()
    185
    186 -        def test():
    187                  try:
    188                          dto = parse_vcard2dto(filename = sys.argv[2])
    189                          print dto
    190                          print dto.addresses
    191                          print dto.comm_channels
    192                  except:
    193                          _log.exception('cannot parse vCard')
    194                          gmLog2.log_stack_trace()
    195                          raise
    196
    197          test()
    198