home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2011 October / maximum-cd-2011-10.iso / DiscContents / digsby_setup.exe / lib / pyxmpp / jabber / vcard.pyo (.txt) < prev   
Encoding:
Python Compiled Bytecode  |  2011-06-22  |  34.8 KB  |  1,257 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.6)
  3.  
  4. __revision__ = '$Id: vcard.py 714 2010-04-05 10:20:10Z jajcus $'
  5. __docformat__ = 'restructuredtext en'
  6. import base64
  7. import binascii
  8. import libxml2
  9. import re
  10. import pyxmpp.jid as pyxmpp
  11. from pyxmpp.utils import to_utf8, from_utf8
  12. from pyxmpp.xmlextra import get_node_ns
  13. from pyxmpp.objects import StanzaPayloadObject
  14. from pyxmpp.exceptions import BadRequestProtocolError, JIDMalformedProtocolError, JIDError
  15. VCARD_NS = 'vcard-temp'
  16.  
  17. class Empty(Exception):
  18.     pass
  19.  
  20. valid_string_re = re.compile('^[\\w\\d \\t]*$')
  21. non_quoted_semicolon_re = re.compile('(?<!\\\\);')
  22.  
  23. def quote_semicolon(value):
  24.     return value.replace(';', '\\;')
  25.  
  26.  
  27. def unquote_semicolon(value):
  28.     return value.replace('\\;', ';')
  29.  
  30.  
  31. def rfc2425encode(name, value, parameters = None, charset = 'utf-8'):
  32.     if not parameters:
  33.         parameters = { }
  34.     
  35.     if type(value) is unicode:
  36.         value = value.replace(u'\r\n', u'\\n')
  37.         value = value.replace(u'\n', u'\\n')
  38.         value = value.replace(u'\r', u'\\n')
  39.         value = value.encode(charset, 'replace')
  40.     elif type(value) is not str:
  41.         raise TypeError, 'Bad type for rfc2425 value'
  42.     elif not valid_string_re.match(value):
  43.         parameters['encoding'] = 'b'
  44.         value = binascii.b2a_base64(value)
  45.     
  46.     ret = str(name).lower()
  47.     for k, v in parameters.items():
  48.         ret += ';%s=%s' % (str(k), str(v))
  49.     
  50.     ret += ':'
  51.     while len(value) > 70:
  52.         ret += value[:70] + '\r\n '
  53.         value = value[70:]
  54.     ret += value + '\r\n'
  55.     return ret
  56.  
  57.  
  58. class VCardField:
  59.     
  60.     def __init__(self, name):
  61.         self.name = name
  62.  
  63.     
  64.     def __repr__(self):
  65.         return '<%s %r>' % (self.__class__, self.rfc2426())
  66.  
  67.     
  68.     def rfc2426(self):
  69.         return ''
  70.  
  71.  
  72.  
  73. class VCardString(VCardField):
  74.     
  75.     def __init__(self, name, value, rfc2425parameters = None, empty_ok = False):
  76.         _unused = rfc2425parameters
  77.         VCardField.__init__(self, name)
  78.         if isinstance(value, libxml2.xmlNode):
  79.             value = value.getContent()
  80.             if value:
  81.                 self.value = unicode(value, 'utf-8', 'replace').strip()
  82.             else:
  83.                 self.value = u''
  84.         else:
  85.             self.value = value
  86.         if not (self.value) and not empty_ok:
  87.             raise Empty, 'Empty string value'
  88.         not empty_ok
  89.  
  90.     
  91.     def rfc2426(self):
  92.         return rfc2425encode(self.name, self.value)
  93.  
  94.     
  95.     def as_xml(self, parent):
  96.         return parent.newTextChild(None, to_utf8(self.name.upper()), to_utf8(self.value))
  97.  
  98.     
  99.     def __unicode__(self):
  100.         return self.value
  101.  
  102.     
  103.     def __str__(self):
  104.         return self.value.encode('utf-8')
  105.  
  106.  
  107.  
  108. class VCardXString(VCardString):
  109.     
  110.     def rfc2426(self):
  111.         return rfc2425encode('x-' + self.name, self.value)
  112.  
  113.  
  114.  
  115. class VCardJID(VCardField):
  116.     
  117.     def __init__(self, name, value, rfc2425parameters = None):
  118.         _unused = rfc2425parameters
  119.         VCardField.__init__(self, name)
  120.         if isinstance(value, libxml2.xmlNode):
  121.             
  122.             try:
  123.                 self.value = pyxmpp.jid.JID(value.getContent())
  124.             except JIDError:
  125.                 raise JIDMalformedProtocolError, 'JID malformed'
  126.             except:
  127.                 None<EXCEPTION MATCH>JIDError
  128.             
  129.  
  130.         None<EXCEPTION MATCH>JIDError
  131.         self.value = pyxmpp.jid.JID(value)
  132.         if not self.value:
  133.             raise Empty, 'Empty JID value'
  134.         self.value
  135.  
  136.     
  137.     def rfc2426(self):
  138.         return rfc2425encode('x-jabberid', self.value.as_unicode())
  139.  
  140.     
  141.     def as_xml(self, parent):
  142.         name = to_utf8(self.name.upper())
  143.         content = self.value.as_utf8()
  144.         return parent.newTextChild(None, name, content)
  145.  
  146.     
  147.     def __unicode__(self):
  148.         return self.value.as_unicode()
  149.  
  150.     
  151.     def __str__(self):
  152.         return self.value.as_string()
  153.  
  154.  
  155.  
  156. class VCardName(VCardField):
  157.     
  158.     def __init__(self, name, value, rfc2425parameters = None):
  159.         _unused = rfc2425parameters
  160.         VCardField.__init__(self, name)
  161.         if self.name.upper() != 'N':
  162.             raise RuntimeError, "VCardName handles only 'N' type"
  163.         self.name.upper() != 'N'
  164.         if isinstance(value, libxml2.xmlNode):
  165.             (self.family, self.given, self.middle, self.prefix, self.suffix) = [
  166.                 u''] * 5
  167.             empty = 1
  168.             n = value.children
  169.             vns = get_node_ns(value)
  170.             while n:
  171.                 if n.type != 'element':
  172.                     n = n.next
  173.                     continue
  174.                 
  175.                 ns = get_node_ns(n)
  176.                 if ns and vns and ns.getContent() != vns.getContent():
  177.                     n = n.next
  178.                     continue
  179.                 
  180.                 if n.name == 'FAMILY':
  181.                     self.family = unicode(n.getContent(), 'utf-8')
  182.                     empty = 0
  183.                 
  184.                 if n.name == 'GIVEN':
  185.                     self.given = unicode(n.getContent(), 'utf-8')
  186.                     empty = 0
  187.                 
  188.                 if n.name == 'MIDDLE':
  189.                     self.middle = unicode(n.getContent(), 'utf-8')
  190.                     empty = 0
  191.                 
  192.                 if n.name == 'PREFIX':
  193.                     self.prefix = unicode(n.getContent(), 'utf-8')
  194.                     empty = 0
  195.                 
  196.                 if n.name == 'SUFFIX':
  197.                     self.suffix = unicode(n.getContent(), 'utf-8')
  198.                     empty = 0
  199.                 
  200.                 n = n.next
  201.             if empty:
  202.                 raise Empty, 'Empty N value'
  203.             empty
  204.         else:
  205.             v = non_quoted_semicolon_re.split(value)
  206.             value = [
  207.                 u''] * 5
  208.             value[:len(v)] = v
  209.             (self.family, self.given, self.middle, self.prefix, self.suffix) = (lambda .0: for val in .0:
  210. unquote_semicolon(val))(value)
  211.  
  212.     
  213.     def rfc2426(self):
  214.         return rfc2425encode('n', u';'.join((lambda .0: for val in .0:
  215. quote_semicolon(val))((self.family, self.given, self.middle, self.prefix, self.suffix))))
  216.  
  217.     
  218.     def as_xml(self, parent):
  219.         n = parent.newChild(None, 'N', None)
  220.         n.newTextChild(None, 'FAMILY', to_utf8(self.family))
  221.         n.newTextChild(None, 'GIVEN', to_utf8(self.given))
  222.         n.newTextChild(None, 'MIDDLE', to_utf8(self.middle))
  223.         n.newTextChild(None, 'PREFIX', to_utf8(self.prefix))
  224.         n.newTextChild(None, 'SUFFIX', to_utf8(self.suffix))
  225.         return n
  226.  
  227.     
  228.     def __unicode__(self):
  229.         r = []
  230.         if self.prefix:
  231.             r.append(self.prefix.replace(u',', u' '))
  232.         
  233.         if self.given:
  234.             r.append(self.given.replace(u',', u' '))
  235.         
  236.         if self.middle:
  237.             r.append(self.middle.replace(u',', u' '))
  238.         
  239.         if self.family:
  240.             r.append(self.family.replace(u',', u' '))
  241.         
  242.         if self.suffix:
  243.             r.append(self.suffix.replace(u',', u' '))
  244.         
  245.         return u' '.join(r)
  246.  
  247.     
  248.     def __str__(self):
  249.         return self.__unicode__().encode('utf-8')
  250.  
  251.  
  252.  
  253. class VCardImage(VCardField):
  254.     
  255.     def __init__(self, name, value, rfc2425parameters = None):
  256.         VCardField.__init__(self, name)
  257.         if not rfc2425parameters:
  258.             rfc2425parameters = { }
  259.         
  260.         (self.uri, self.type, self.image) = [
  261.             None] * 3
  262.         if isinstance(value, libxml2.xmlNode):
  263.             n = value.children
  264.             vns = get_node_ns(value)
  265.             while n:
  266.                 if n.type != 'element':
  267.                     n = n.next
  268.                     continue
  269.                 
  270.                 ns = get_node_ns(n)
  271.                 if ns and vns and ns.getContent() != vns.getContent():
  272.                     n = n.next
  273.                     continue
  274.                 
  275.                 if n.name == 'TYPE':
  276.                     self.type = unicode(n.getContent(), 'utf-8', 'replace')
  277.                 
  278.                 if n.name == 'BINVAL':
  279.                     
  280.                     try:
  281.                         self.image = base64.decodestring(n.getContent())
  282.                     self.image = None
  283.  
  284.                 
  285.                 if n.name == 'EXTVAL':
  286.                     self.uri = unicode(n.getContent(), 'utf-8', 'replace')
  287.                 
  288.                 n = n.next
  289.             if self.uri and self.image:
  290.                 raise ValueError, 'Bad %s value in vcard' % (name,)
  291.             self.image
  292.             if not (self.uri) and not (self.image):
  293.                 raise Empty, 'Bad %s value in vcard' % (name,)
  294.             not (self.image)
  295.         elif rfc2425parameters.get('value', '').lower() == 'uri':
  296.             self.uri = value
  297.             self.type = None
  298.         else:
  299.             self.type = rfc2425parameters.get('type')
  300.             self.image = value
  301.  
  302.     
  303.     def rfc2426(self):
  304.         if self.uri:
  305.             return rfc2425encode(self.name, self.uri, {
  306.                 'value': 'uri' })
  307.         if self.image:
  308.             if self.type:
  309.                 p = {
  310.                     'type': self.type }
  311.             else:
  312.                 p = { }
  313.             return rfc2425encode(self.name, self.image, p)
  314.  
  315.     
  316.     def as_xml(self, parent):
  317.         n = parent.newChild(None, self.name.upper(), None)
  318.         if self.uri:
  319.             n.newTextChild(None, 'EXTVAL', to_utf8(self.uri))
  320.         elif self.type:
  321.             n.newTextChild(None, 'TYPE', self.type)
  322.         
  323.         n.newTextChild(None, 'BINVAL', binascii.b2a_base64(self.image))
  324.         return n
  325.  
  326.     
  327.     def __unicode__(self):
  328.         if self.uri:
  329.             return self.uri
  330.         if self.type:
  331.             return u'(%s data)' % (self.type,)
  332.         return u'(binary data)'
  333.  
  334.     
  335.     def __str__(self):
  336.         return self.__unicode__().encode('utf-8')
  337.  
  338.  
  339.  
  340. class VCardAdr(VCardField):
  341.     
  342.     def __init__(self, name, value, rfc2425parameters = None):
  343.         VCardField.__init__(self, name)
  344.         if not rfc2425parameters:
  345.             rfc2425parameters = { }
  346.         
  347.         if self.name.upper() != 'ADR':
  348.             raise RuntimeError, "VCardAdr handles only 'ADR' type"
  349.         self.name.upper() != 'ADR'
  350.         (self.pobox, self.extadr, self.street, self.locality, self.region, self.pcode, self.ctry) = [
  351.             ''] * 7
  352.         self.type = []
  353.         if isinstance(value, libxml2.xmlNode):
  354.             self._VCardAdr__from_xml(value)
  355.         else:
  356.             t = rfc2425parameters.get('type')
  357.             if t:
  358.                 self.type = t.split(',')
  359.             else:
  360.                 self.type = [
  361.                     'intl',
  362.                     'postal',
  363.                     'parcel',
  364.                     'work']
  365.             v = non_quoted_semicolon_re.split(value)
  366.             value = [
  367.                 ''] * 7
  368.             value[:len(v)] = v
  369.             (self.pobox, self.extadr, self.street, self.locality, self.region, self.pcode, self.ctry) = (lambda .0: for val in .0:
  370. unquote_semicolon(val))(value)
  371.  
  372.     
  373.     def __from_xml(self, value):
  374.         n = value.children
  375.         vns = get_node_ns(value)
  376.         while n:
  377.             if n.type != 'element':
  378.                 n = n.next
  379.                 continue
  380.             
  381.             ns = get_node_ns(n)
  382.             if ns and vns and ns.getContent() != vns.getContent():
  383.                 n = n.next
  384.                 continue
  385.             
  386.             if n.name == 'POBOX':
  387.                 self.pobox = unicode(n.getContent(), 'utf-8', 'replace')
  388.             elif n.name in ('EXTADR', 'EXTADD'):
  389.                 self.extadr = unicode(n.getContent(), 'utf-8', 'replace')
  390.             elif n.name == 'STREET':
  391.                 self.street = unicode(n.getContent(), 'utf-8', 'replace')
  392.             elif n.name == 'LOCALITY':
  393.                 self.locality = unicode(n.getContent(), 'utf-8', 'replace')
  394.             elif n.name == 'REGION':
  395.                 self.region = unicode(n.getContent(), 'utf-8', 'replace')
  396.             elif n.name == 'PCODE':
  397.                 self.pcode = unicode(n.getContent(), 'utf-8', 'replace')
  398.             elif n.name == 'CTRY':
  399.                 self.ctry = unicode(n.getContent(), 'utf-8', 'replace')
  400.             elif n.name in ('HOME', 'WORK', 'POSTAL', 'PARCEL', 'DOM', 'INTL', 'PREF'):
  401.                 self.type.append(n.name.lower())
  402.             
  403.             n = n.next
  404.         if self.type == []:
  405.             self.type = [
  406.                 'intl',
  407.                 'postal',
  408.                 'parcel',
  409.                 'work']
  410.         elif 'dom' in self.type and 'intl' in self.type:
  411.             raise ValueError, "Both 'dom' and 'intl' specified in vcard ADR"
  412.         
  413.  
  414.     
  415.     def rfc2426(self):
  416.         return rfc2425encode('adr', u';'.join((lambda .0: for val in .0:
  417. quote_semicolon(val))((self.pobox, self.extadr, self.street, self.locality, self.region, self.pcode, self.ctry))), {
  418.             'type': ','.join(self.type) })
  419.  
  420.     
  421.     def as_xml(self, parent):
  422.         n = parent.newChild(None, 'ADR', None)
  423.         for t in ('home', 'work', 'postal', 'parcel', 'dom', 'intl', 'pref'):
  424.             if t in self.type:
  425.                 n.newChild(None, t.upper(), None)
  426.                 continue
  427.         
  428.         n.newTextChild(None, 'POBOX', to_utf8(self.pobox))
  429.         n.newTextChild(None, 'EXTADD', to_utf8(self.extadr))
  430.         n.newTextChild(None, 'STREET', to_utf8(self.street))
  431.         n.newTextChild(None, 'LOCALITY', to_utf8(self.locality))
  432.         n.newTextChild(None, 'REGION', to_utf8(self.region))
  433.         n.newTextChild(None, 'PCODE', to_utf8(self.pcode))
  434.         n.newTextChild(None, 'CTRY', to_utf8(self.ctry))
  435.         return n
  436.  
  437.  
  438.  
  439. class VCardLabel(VCardField):
  440.     
  441.     def __init__(self, name, value, rfc2425parameters = None):
  442.         VCardField.__init__(self, name)
  443.         if not rfc2425parameters:
  444.             rfc2425parameters = { }
  445.         
  446.         if self.name.upper() != 'LABEL':
  447.             raise RuntimeError, "VCardAdr handles only 'LABEL' type"
  448.         self.name.upper() != 'LABEL'
  449.         if isinstance(value, libxml2.xmlNode):
  450.             self.lines = []
  451.             self.type = []
  452.             n = value.children
  453.             vns = get_node_ns(value)
  454.             while n:
  455.                 if n.type != 'element':
  456.                     n = n.next
  457.                     continue
  458.                 
  459.                 ns = get_node_ns(n)
  460.                 if ns and vns and ns.getContent() != vns.getContent():
  461.                     n = n.next
  462.                     continue
  463.                 
  464.                 if n.name == 'LINE':
  465.                     l = unicode(n.getContent(), 'utf-8', 'replace').strip()
  466.                     l = l.replace('\n', ' ').replace('\r', ' ')
  467.                     self.lines.append(l)
  468.                 elif n.name in ('HOME', 'WORK', 'POSTAL', 'PARCEL', 'DOM', 'INTL', 'PREF'):
  469.                     self.type.append(n.name.lower())
  470.                 
  471.                 n = n.next
  472.             if self.type == []:
  473.                 self.type = [
  474.                     'intl',
  475.                     'postal',
  476.                     'parcel',
  477.                     'work']
  478.             elif 'dom' in self.type and 'intl' in self.type:
  479.                 raise ValueError, "Both 'dom' and 'intl' specified in vcard LABEL"
  480.             
  481.             if not self.lines:
  482.                 self.lines = [
  483.                     '']
  484.             
  485.         else:
  486.             t = rfc2425parameters.get('type')
  487.             if t:
  488.                 self.type = t.split(',')
  489.             else:
  490.                 self.type = [
  491.                     'intl',
  492.                     'postal',
  493.                     'parcel',
  494.                     'work']
  495.             self.lines = value.split('\\n')
  496.  
  497.     
  498.     def rfc2426(self):
  499.         return rfc2425encode('label', u'\n'.join(self.lines), {
  500.             'type': ','.join(self.type) })
  501.  
  502.     
  503.     def as_xml(self, parent):
  504.         n = parent.newChild(None, 'ADR', None)
  505.         for t in ('home', 'work', 'postal', 'parcel', 'dom', 'intl', 'pref'):
  506.             if t in self.type:
  507.                 n.newChild(None, t.upper(), None)
  508.                 continue
  509.         
  510.         for l in self.lines:
  511.             n.newTextChild(None, 'LINE', l)
  512.         
  513.         return n
  514.  
  515.  
  516.  
  517. class VCardTel(VCardField):
  518.     
  519.     def __init__(self, name, value, rfc2425parameters = None):
  520.         VCardField.__init__(self, name)
  521.         if not rfc2425parameters:
  522.             rfc2425parameters = { }
  523.         
  524.         if self.name.upper() != 'TEL':
  525.             raise RuntimeError, "VCardTel handles only 'TEL' type"
  526.         self.name.upper() != 'TEL'
  527.         if isinstance(value, libxml2.xmlNode):
  528.             self.number = None
  529.             self.type = []
  530.             n = value.children
  531.             vns = get_node_ns(value)
  532.             while n:
  533.                 if n.type != 'element':
  534.                     n = n.next
  535.                     continue
  536.                 
  537.                 ns = get_node_ns(n)
  538.                 if ns and vns and ns.getContent() != vns.getContent():
  539.                     n = n.next
  540.                     continue
  541.                 
  542.                 if n.name == 'NUMBER':
  543.                     self.number = unicode(n.getContent(), 'utf-8', 'replace')
  544.                 elif n.name in ('HOME', 'WORK', 'VOICE', 'FAX', 'PAGER', 'MSG', 'CELL', 'VIDEO', 'BBS', 'MODEM', 'ISDN', 'PCS', 'PREF'):
  545.                     self.type.append(n.name.lower())
  546.                 
  547.                 n = n.next
  548.             if self.type == []:
  549.                 self.type = [
  550.                     'voice']
  551.             
  552.             if not self.number:
  553.                 raise Empty, 'No tel number'
  554.             self.number
  555.         else:
  556.             t = rfc2425parameters.get('type')
  557.             if t:
  558.                 self.type = t.split(',')
  559.             else:
  560.                 self.type = [
  561.                     'voice']
  562.             self.number = value
  563.  
  564.     
  565.     def rfc2426(self):
  566.         return rfc2425encode('tel', self.number, {
  567.             'type': ','.join(self.type) })
  568.  
  569.     
  570.     def as_xml(self, parent):
  571.         n = parent.newChild(None, 'TEL', None)
  572.         for t in ('home', 'work', 'voice', 'fax', 'pager', 'msg', 'cell', 'video', 'bbs', 'modem', 'isdn', 'pcs', 'pref'):
  573.             if t in self.type:
  574.                 n.newChild(None, t.upper(), None)
  575.                 continue
  576.         
  577.         n.newTextChild(None, 'NUMBER', to_utf8(self.number))
  578.         return n
  579.  
  580.  
  581.  
  582. class VCardEmail(VCardField):
  583.     
  584.     def __init__(self, name, value, rfc2425parameters = None):
  585.         VCardField.__init__(self, name)
  586.         if not rfc2425parameters:
  587.             rfc2425parameters = { }
  588.         
  589.         if self.name.upper() != 'EMAIL':
  590.             raise RuntimeError, "VCardEmail handles only 'EMAIL' type"
  591.         self.name.upper() != 'EMAIL'
  592.         if isinstance(value, libxml2.xmlNode):
  593.             self.address = None
  594.             self.type = []
  595.             n = value.children
  596.             vns = get_node_ns(value)
  597.             while n:
  598.                 if n.type != 'element':
  599.                     n = n.next
  600.                     continue
  601.                 
  602.                 ns = get_node_ns(n)
  603.                 if ns and vns and ns.getContent() != vns.getContent():
  604.                     n = n.next
  605.                     continue
  606.                 
  607.                 if n.name == 'USERID':
  608.                     self.address = unicode(n.getContent(), 'utf-8', 'replace')
  609.                 elif n.name in ('HOME', 'WORK', 'INTERNET', 'X400'):
  610.                     self.type.append(n.name.lower())
  611.                 
  612.                 n = n.next
  613.             if self.type == []:
  614.                 self.type = [
  615.                     'internet']
  616.             
  617.             if not self.address:
  618.                 raise Empty, 'No USERID'
  619.             self.address
  620.         else:
  621.             t = rfc2425parameters.get('type')
  622.             if t:
  623.                 self.type = t.split(',')
  624.             else:
  625.                 self.type = [
  626.                     'internet']
  627.             self.address = value
  628.  
  629.     
  630.     def rfc2426(self):
  631.         return rfc2425encode('email', self.address, {
  632.             'type': ','.join(self.type) })
  633.  
  634.     
  635.     def as_xml(self, parent):
  636.         n = parent.newChild(None, 'EMAIL', None)
  637.         for t in ('home', 'work', 'internet', 'x400'):
  638.             if t in self.type:
  639.                 n.newChild(None, t.upper(), None)
  640.                 continue
  641.         
  642.         n.newTextChild(None, 'USERID', to_utf8(self.address))
  643.         return n
  644.  
  645.  
  646.  
  647. class VCardGeo(VCardField):
  648.     
  649.     def __init__(self, name, value, rfc2425parameters = None):
  650.         _unused = rfc2425parameters
  651.         VCardField.__init__(self, name)
  652.         if self.name.upper() != 'GEO':
  653.             raise RuntimeError, "VCardName handles only 'GEO' type"
  654.         self.name.upper() != 'GEO'
  655.         if isinstance(value, libxml2.xmlNode):
  656.             (self.lat, self.lon) = [
  657.                 None] * 2
  658.             n = value.children
  659.             vns = get_node_ns(value)
  660.             while n:
  661.                 if n.type != 'element':
  662.                     n = n.next
  663.                     continue
  664.                 
  665.                 ns = get_node_ns(n)
  666.                 if ns and vns and ns.getContent() != vns.getContent():
  667.                     n = n.next
  668.                     continue
  669.                 
  670.                 if n.name == 'LAT':
  671.                     self.lat = unicode(n.getContent(), 'utf-8')
  672.                 
  673.                 if n.name == 'LON':
  674.                     self.lon = unicode(n.getContent(), 'utf-8')
  675.                 
  676.                 n = n.next
  677.             if not (self.lat) or not (self.lon):
  678.                 raise ValueError, 'Bad vcard GEO value'
  679.             not (self.lon)
  680.         else:
  681.             (self.lat, self.lon) = (lambda .0: for val in .0:
  682. unquote_semicolon(val))(non_quoted_semicolon_re.split(value))
  683.  
  684.     
  685.     def rfc2426(self):
  686.         return rfc2425encode('geo', u';'.join((lambda .0: for val in .0:
  687. quote_semicolon(val))((self.lat, self.lon))))
  688.  
  689.     
  690.     def as_xml(self, parent):
  691.         n = parent.newChild(None, 'GEO', None)
  692.         n.newTextChild(None, 'LAT', to_utf8(self.lat))
  693.         n.newTextChild(None, 'LON', to_utf8(self.lon))
  694.         return n
  695.  
  696.  
  697.  
  698. class VCardOrg(VCardField):
  699.     
  700.     def __init__(self, name, value, rfc2425parameters = None):
  701.         _unused = rfc2425parameters
  702.         VCardField.__init__(self, name)
  703.         if self.name.upper() != 'ORG':
  704.             raise RuntimeError, "VCardName handles only 'ORG' type"
  705.         self.name.upper() != 'ORG'
  706.         if isinstance(value, libxml2.xmlNode):
  707.             (self.name, self.unit) = (None, '')
  708.             n = value.children
  709.             vns = get_node_ns(value)
  710.             while n:
  711.                 if n.type != 'element':
  712.                     n = n.next
  713.                     continue
  714.                 
  715.                 ns = get_node_ns(n)
  716.                 if ns and vns and ns.getContent() != vns.getContent():
  717.                     n = n.next
  718.                     continue
  719.                 
  720.                 if n.name == 'ORGNAME':
  721.                     self.name = unicode(n.getContent(), 'utf-8')
  722.                 
  723.                 if n.name == 'ORGUNIT':
  724.                     self.unit = unicode(n.getContent(), 'utf-8')
  725.                 
  726.                 n = n.next
  727.             if not self.name:
  728.                 raise Empty, 'Bad vcard ORG value'
  729.             self.name
  730.         else:
  731.             sp = non_quoted_semicolon_re.split(value, 1)
  732.             if len(sp) > 1:
  733.                 (self.name, self.unit) = (lambda .0: for val in .0:
  734. unquote_semicolon(val))(sp)
  735.             else:
  736.                 self.name = unquote_semicolon(sp[0])
  737.                 self.unit = None
  738.  
  739.     
  740.     def rfc2426(self):
  741.         if self.unit:
  742.             return rfc2425encode('org', u';'.join((lambda .0: for val in .0:
  743. quote_semicolon(val))((self.name, self.unit))))
  744.         return rfc2425encode('org', unicode(quote_semicolon(self.name)))
  745.  
  746.     
  747.     def as_xml(self, parent):
  748.         n = parent.newChild(None, 'ORG', None)
  749.         n.newTextChild(None, 'ORGNAME', to_utf8(self.name))
  750.         n.newTextChild(None, 'ORGUNIT', to_utf8(self.unit))
  751.         return n
  752.  
  753.  
  754.  
  755. class VCardCategories(VCardField):
  756.     
  757.     def __init__(self, name, value, rfc2425parameters = None):
  758.         _unused = rfc2425parameters
  759.         VCardField.__init__(self, name)
  760.         self.name = name
  761.         if self.name.upper() != 'CATEGORIES':
  762.             raise RuntimeError, "VCardName handles only 'CATEGORIES' type"
  763.         self.name.upper() != 'CATEGORIES'
  764.         if isinstance(value, libxml2.xmlNode):
  765.             self.keywords = []
  766.             n = value.children
  767.             vns = get_node_ns(value)
  768.             while n:
  769.                 if n.type != 'element':
  770.                     n = n.next
  771.                     continue
  772.                 
  773.                 ns = get_node_ns(n)
  774.                 if ns and vns and ns.getContent() != vns.getContent():
  775.                     n = n.next
  776.                     continue
  777.                 
  778.                 if n.name == 'KEYWORD':
  779.                     self.keywords.append(unicode(n.getContent(), 'utf-8'))
  780.                 
  781.                 n = n.next
  782.             if not self.keywords:
  783.                 raise Empty, 'Bad vcard CATEGORIES value'
  784.             self.keywords
  785.         else:
  786.             self.keywords = value.split(',')
  787.  
  788.     
  789.     def rfc2426(self):
  790.         return rfc2425encode('keywords', u','.join(self.keywords))
  791.  
  792.     
  793.     def as_xml(self, parent):
  794.         n = parent.newChild(None, 'CATEGORIES', None)
  795.         for k in self.keywords:
  796.             n.newTextChild(None, 'KEYWORD', to_utf8(k))
  797.         
  798.         return n
  799.  
  800.  
  801.  
  802. class VCardSound(VCardField):
  803.     
  804.     def __init__(self, name, value, rfc2425parameters = None):
  805.         VCardField.__init__(self, name)
  806.         if not rfc2425parameters:
  807.             rfc2425parameters = { }
  808.         
  809.         (self.uri, self.sound, self.phonetic) = [
  810.             None] * 3
  811.         if isinstance(value, libxml2.xmlNode):
  812.             n = value.children
  813.             vns = get_node_ns(value)
  814.             while n:
  815.                 if n.type != 'element':
  816.                     n = n.next
  817.                     continue
  818.                 
  819.                 ns = get_node_ns(n)
  820.                 if ns and vns and ns.getContent() != vns.getContent():
  821.                     n = n.next
  822.                     continue
  823.                 
  824.                 if n.name == 'BINVAL':
  825.                     if self.phonetic or self.uri:
  826.                         raise ValueError, 'Bad SOUND value in vcard'
  827.                     self.uri
  828.                     self.sound = base64.decodestring(n.getContent())
  829.                 
  830.                 if n.name == 'PHONETIC':
  831.                     if self.sound or self.uri:
  832.                         raise ValueError, 'Bad SOUND value in vcard'
  833.                     self.uri
  834.                     self.phonetic = unicode(n.getContent(), 'utf-8', 'replace')
  835.                 
  836.                 if n.name == 'EXTVAL':
  837.                     if self.phonetic or self.sound:
  838.                         raise ValueError, 'Bad SOUND value in vcard'
  839.                     self.sound
  840.                     self.uri = unicode(n.getContent(), 'utf-8', 'replace')
  841.                 
  842.                 n = n.next
  843.             if not (self.phonetic) and not (self.uri) and not (self.sound):
  844.                 raise Empty, 'Bad SOUND value in vcard'
  845.             not (self.sound)
  846.         elif rfc2425parameters.get('value', '').lower() == 'uri':
  847.             self.uri = value
  848.             self.sound = None
  849.             self.phonetic = None
  850.         else:
  851.             self.sound = value
  852.             self.uri = None
  853.             self.phonetic = None
  854.  
  855.     
  856.     def rfc2426(self):
  857.         if self.uri:
  858.             return rfc2425encode(self.name, self.uri, {
  859.                 'value': 'uri' })
  860.         if self.sound:
  861.             return rfc2425encode(self.name, self.sound)
  862.  
  863.     
  864.     def as_xml(self, parent):
  865.         n = parent.newChild(None, self.name.upper(), None)
  866.         if self.uri:
  867.             n.newTextChild(None, 'EXTVAL', to_utf8(self.uri))
  868.         elif self.phonetic:
  869.             n.newTextChild(None, 'PHONETIC', to_utf8(self.phonetic))
  870.         else:
  871.             n.newTextChild(None, 'BINVAL', binascii.b2a_base64(self.sound))
  872.         return n
  873.  
  874.  
  875.  
  876. class VCardPrivacy(VCardField):
  877.     
  878.     def __init__(self, name, value, rfc2425parameters = None):
  879.         _unused = rfc2425parameters
  880.         VCardField.__init__(self, name)
  881.         if isinstance(value, libxml2.xmlNode):
  882.             self.value = None
  883.             n = value.children
  884.             vns = get_node_ns(value)
  885.             while n:
  886.                 if n.type != 'element':
  887.                     n = n.next
  888.                     continue
  889.                 
  890.                 ns = get_node_ns(n)
  891.                 if ns and vns and ns.getContent() != vns.getContent():
  892.                     n = n.next
  893.                     continue
  894.                 
  895.                 if n.name == 'PUBLIC':
  896.                     self.value = 'public'
  897.                 elif n.name == 'PRIVATE':
  898.                     self.value = 'private'
  899.                 elif n.name == 'CONFIDENTAL':
  900.                     self.value = 'confidental'
  901.                 
  902.                 n = n.next
  903.             if not self.value:
  904.                 raise Empty
  905.             self.value
  906.         else:
  907.             self.value = value
  908.  
  909.     
  910.     def rfc2426(self):
  911.         return rfc2425encode(self.name, self.value)
  912.  
  913.     
  914.     def as_xml(self, parent):
  915.         if self.value in ('public', 'private', 'confidental'):
  916.             n = parent.newChild(None, self.name.upper(), None)
  917.             n.newChild(None, self.value.upper(), None)
  918.             return n
  919.  
  920.  
  921.  
  922. class VCardKey(VCardField):
  923.     
  924.     def __init__(self, name, value, rfc2425parameters = None):
  925.         VCardField.__init__(self, name)
  926.         if not rfc2425parameters:
  927.             rfc2425parameters = { }
  928.         
  929.         if isinstance(value, libxml2.xmlNode):
  930.             (self.type, self.cred) = (None, None)
  931.             n = value.children
  932.             vns = get_node_ns(value)
  933.             while n:
  934.                 if n.type != 'element':
  935.                     n = n.next
  936.                     continue
  937.                 
  938.                 ns = get_node_ns(n)
  939.                 if ns and vns and ns.getContent() != vns.getContent():
  940.                     n = n.next
  941.                     continue
  942.                 
  943.                 if n.name == 'TYPE':
  944.                     self.type = unicode(n.getContent(), 'utf-8', 'replace')
  945.                 
  946.                 if n.name == 'CRED':
  947.                     self.cred = base64.decodestring(n.getContent())
  948.                 
  949.                 n = n.next
  950.             if not self.cred:
  951.                 raise Empty, 'Bad %s value in vcard' % (name,)
  952.             self.cred
  953.         else:
  954.             self.type = rfc2425parameters.get('type')
  955.             self.cred = value
  956.  
  957.     
  958.     def rfc2426(self):
  959.         if self.type:
  960.             p = {
  961.                 'type': self.type }
  962.         else:
  963.             p = { }
  964.         return rfc2425encode(self.name, self.cred, p)
  965.  
  966.     
  967.     def as_xml(self, parent):
  968.         n = parent.newChild(None, self.name.upper(), None)
  969.         if self.type:
  970.             n.newTextChild(None, 'TYPE', self.type)
  971.         
  972.         n.newTextChild(None, 'CRED', binascii.b2a_base64(self.cred))
  973.         return n
  974.  
  975.  
  976.  
  977. class VCard(StanzaPayloadObject):
  978.     xml_element_name = 'vCard'
  979.     xml_element_namespace = VCARD_NS
  980.     components = {
  981.         'FN': (VCardString, 'required'),
  982.         'N': (VCardName, 'required'),
  983.         'NICKNAME': (VCardString, 'multi'),
  984.         'PHOTO': (VCardImage, 'multi'),
  985.         'BDAY': (VCardString, 'multi'),
  986.         'ADR': (VCardAdr, 'multi'),
  987.         'LABEL': (VCardLabel, 'multi'),
  988.         'TEL': (VCardTel, 'multi'),
  989.         'EMAIL': (VCardEmail, 'multi'),
  990.         'JABBERID': (VCardJID, 'multi'),
  991.         'MAILER': (VCardString, 'multi'),
  992.         'TZ': (VCardString, 'multi'),
  993.         'GEO': (VCardGeo, 'multi'),
  994.         'TITLE': (VCardString, 'multi'),
  995.         'ROLE': (VCardString, 'multi'),
  996.         'LOGO': (VCardImage, 'multi'),
  997.         'AGENT': ('VCardAgent', 'ignore'),
  998.         'ORG': (VCardOrg, 'multi'),
  999.         'CATEGORIES': (VCardCategories, 'multi'),
  1000.         'NOTE': (VCardString, 'multi'),
  1001.         'PRODID': (VCardString, 'multi'),
  1002.         'REV': (VCardString, 'multi'),
  1003.         'SORT-STRING': (VCardString, 'multi'),
  1004.         'SOUND': (VCardSound, 'multi'),
  1005.         'UID': (VCardString, 'multi'),
  1006.         'URL': (VCardString, 'multi'),
  1007.         'CLASS': (VCardString, 'multi'),
  1008.         'KEY': (VCardKey, 'multi'),
  1009.         'DESC': (VCardXString, 'multi') }
  1010.     
  1011.     def __init__(self, data):
  1012.         self.n = None
  1013.         del self.n
  1014.         self.content = { }
  1015.         if isinstance(data, libxml2.xmlNode):
  1016.             self._VCard__from_xml(data)
  1017.         else:
  1018.             self._VCard__from_rfc2426(data)
  1019.         if not self.content.get('N') and self.content.get('FN'):
  1020.             s = self.content['FN'].value.replace(';', ',')
  1021.             s = s.split(None, 2)
  1022.             if len(s) == 2:
  1023.                 s = u'%s;%s;;;' % (s[1], s[0])
  1024.             elif len(s) == 3:
  1025.                 s = u'%s;%s;%s' % (s[2], s[0], s[1])
  1026.             else:
  1027.                 s = u'%s;;;;' % (s[0],)
  1028.             self.content['N'] = VCardName('N', s)
  1029.         elif not self.content.get('FN') and self.content.get('N'):
  1030.             self._VCard__make_fn()
  1031.         
  1032.         for _unused, tp in self.components.items():
  1033.             if self.content.has_key(c):
  1034.                 continue
  1035.             
  1036.             if tp == 'required':
  1037.                 raise ValueError, '%s is missing' % (c,)
  1038.             tp == 'required'
  1039.             if tp == 'multi':
  1040.                 self.content[c] = []
  1041.                 continue
  1042.             if tp == 'optional':
  1043.                 self.content[c] = None
  1044.                 continue
  1045.         
  1046.  
  1047.     
  1048.     def __make_fn(self):
  1049.         s = []
  1050.         if self.n.prefix:
  1051.             s.append(self.n.prefix)
  1052.         
  1053.         if self.n.given:
  1054.             s.append(self.n.given)
  1055.         
  1056.         if self.n.middle:
  1057.             s.append(self.n.middle)
  1058.         
  1059.         if self.n.family:
  1060.             s.append(self.n.family)
  1061.         
  1062.         if self.n.suffix:
  1063.             s.append(self.n.suffix)
  1064.         
  1065.         s = u' '.join(s)
  1066.         self.content['FN'] = VCardString('FN', s, empty_ok = True)
  1067.  
  1068.     
  1069.     def __from_xml(self, data):
  1070.         ns = get_node_ns(data)
  1071.         if ns and ns.getContent() != VCARD_NS:
  1072.             raise ValueError, 'Not in the %r namespace' % (VCARD_NS,)
  1073.         ns.getContent() != VCARD_NS
  1074.         if data.name.lower() != 'vCard'.lower():
  1075.             raise ValueError, 'Bad root element name: %r' % (data.name,)
  1076.         data.name.lower() != 'vCard'.lower()
  1077.         n = data.children
  1078.         dns = get_node_ns(data)
  1079.         while n:
  1080.             if n.type != 'element':
  1081.                 n = n.next
  1082.                 continue
  1083.             
  1084.             ns = get_node_ns(n)
  1085.             if ns and dns and ns.getContent() != dns.getContent():
  1086.                 n = n.next
  1087.                 continue
  1088.             
  1089.             if not self.components.has_key(n.name):
  1090.                 n = n.next
  1091.                 continue
  1092.             
  1093.             (cl, tp) = self.components[n.name]
  1094.             if tp in ('required', 'optional'):
  1095.                 if self.content.has_key(n.name):
  1096.                     raise ValueError, 'Duplicate %s' % (n.name,)
  1097.                 self.content.has_key(n.name)
  1098.                 
  1099.                 try:
  1100.                     self.content[n.name] = cl(n.name, n)
  1101.                 except Empty:
  1102.                     pass
  1103.                 except:
  1104.                     None<EXCEPTION MATCH>Empty
  1105.                 
  1106.  
  1107.             None<EXCEPTION MATCH>Empty
  1108.             if tp == 'multi':
  1109.                 if not self.content.has_key(n.name):
  1110.                     self.content[n.name] = []
  1111.                 
  1112.                 
  1113.                 try:
  1114.                     self.content[n.name].append(cl(n.name, n))
  1115.                 except Empty:
  1116.                     pass
  1117.                 except:
  1118.                     None<EXCEPTION MATCH>Empty
  1119.                 
  1120.  
  1121.             None<EXCEPTION MATCH>Empty
  1122.             n = n.next
  1123.  
  1124.     
  1125.     def __from_rfc2426(self, data):
  1126.         data = from_utf8(data)
  1127.         lines = data.split('\n')
  1128.         started = 0
  1129.         current = None
  1130.         for l in lines:
  1131.             if not l:
  1132.                 continue
  1133.             
  1134.             if l[-1] == '\r':
  1135.                 l = l[:-1]
  1136.             
  1137.             if not l:
  1138.                 continue
  1139.             
  1140.             if l[0] in ' \t':
  1141.                 if current is None:
  1142.                     continue
  1143.                 
  1144.                 current += l[1:]
  1145.                 continue
  1146.             
  1147.             if not started and current and current.upper().strip() == 'BEGIN:VCARD':
  1148.                 started = 1
  1149.             elif started and current.upper().strip() == 'END:VCARD':
  1150.                 current = None
  1151.                 break
  1152.             elif current and started:
  1153.                 self._process_rfc2425_record(current)
  1154.             
  1155.             current = l
  1156.         
  1157.         if started and current:
  1158.             self._process_rfc2425_record(current)
  1159.         
  1160.  
  1161.     
  1162.     def _process_rfc2425_record(self, data):
  1163.         (label, value) = data.split(':', 1)
  1164.         value = value.replace('\\n', '\n').replace('\\N', '\n')
  1165.         psplit = label.lower().split(';')
  1166.         name = psplit[0]
  1167.         params = psplit[1:]
  1168.         if u'.' in name:
  1169.             name = name.split('.', 1)[1]
  1170.         
  1171.         name = name.upper()
  1172.         if name in (u'X-DESC', u'X-JABBERID'):
  1173.             name = name[2:]
  1174.         
  1175.         if not self.components.has_key(name):
  1176.             return None
  1177.         (cl, tp) = self.components[name]
  1178.         if tp in ('required', 'optional'):
  1179.             if self.content.has_key(name):
  1180.                 raise ValueError, 'Duplicate %s' % (name,)
  1181.             self.content.has_key(name)
  1182.             
  1183.             try:
  1184.                 self.content[name] = cl(name, value, params)
  1185.             except Empty:
  1186.                 self.components.has_key(name) if params else dict
  1187.                 self.components.has_key(name) if params else dict
  1188.             except:
  1189.                 self.components.has_key(name) if params else dict<EXCEPTION MATCH>Empty
  1190.             
  1191.  
  1192.         self.components.has_key(name) if params else dict
  1193.         if tp == 'multi':
  1194.             if not self.content.has_key(name):
  1195.                 self.content[name] = []
  1196.             
  1197.             
  1198.             try:
  1199.                 self.content[name].append(cl(name, value, params))
  1200.             except Empty:
  1201.                 pass
  1202.             except:
  1203.                 None<EXCEPTION MATCH>Empty
  1204.             
  1205.  
  1206.         None<EXCEPTION MATCH>Empty
  1207.         return None
  1208.  
  1209.     
  1210.     def __repr__(self):
  1211.         return '<vCard of %r>' % (self.content['FN'].value,)
  1212.  
  1213.     
  1214.     def rfc2426(self):
  1215.         ret = 'begin:VCARD\r\n'
  1216.         ret += 'version:3.0\r\n'
  1217.         for _unused, value in self.content.items():
  1218.             if value is None:
  1219.                 continue
  1220.             
  1221.             if type(value) is list:
  1222.                 for v in value:
  1223.                     ret += v.rfc2426()
  1224.                 
  1225.             v = value.rfc2426()
  1226.             ret += v
  1227.         
  1228.         return ret + 'end:VCARD\r\n'
  1229.  
  1230.     
  1231.     def complete_xml_element(self, xmlnode, _unused):
  1232.         for _unused1, value in self.content.items():
  1233.             if value is None:
  1234.                 continue
  1235.             
  1236.             if type(value) is list:
  1237.                 for v in value:
  1238.                     v.as_xml(xmlnode)
  1239.                 
  1240.             value.as_xml(xmlnode)
  1241.         
  1242.  
  1243.     
  1244.     def __getattr__(self, name):
  1245.         
  1246.         try:
  1247.             return self.content[name.upper().replace('_', '-')]
  1248.         except KeyError:
  1249.             raise AttributeError, 'Attribute %r not found' % (name,)
  1250.  
  1251.  
  1252.     
  1253.     def __getitem__(self, name):
  1254.         return self.content[name.upper()]
  1255.  
  1256.  
  1257.