home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2009 June / maximum-cd-2009-06.iso / DiscContents / digsby_setup.exe / lib / jabber / JabberBuddy.pyo (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2009-02-26  |  18.4 KB  |  527 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.5)
  3.  
  4. import common
  5. import hashlib
  6. import jabber
  7. from jabber import JID, Presence
  8. from util import callsback, Storage as S, odict, threaded
  9. from util.cacheable import urlcacheopen, cproperty
  10. from common.actions import action
  11. from jabber.objects.nick import NICK_NS, Nick
  12. from common import pref
  13. from gui import skin
  14. from urllib import quote
  15. from pyxmpp.jabber.vcard import VCardString
  16.  
  17. VCardString.decode = lambda s, *a: s.value.decode(*a)
  18. from jabber import VCard
  19. from util.observe import ObservableProperty as oproperty
  20. import logging
  21. log = logging.getLogger('jabber.buddy')
  22. GTALK = 'gtalk'
  23. GTALK_DOMAINS = ('gmail.com', 'googlemail.com')
  24. JABBER = 'jabber'
  25.  
  26. def isGTalk(resource):
  27.     if not isinstance(resource, basestring):
  28.         return False
  29.     
  30.     reslower = resource.lower()
  31.     return (any,)((lambda .0: for x in .0:
  32. reslower.startswith(x))(('talk.', 'gmail.', 'talkgadget', 'ics')))
  33.  
  34.  
  35. no_widget = lambda self: None if getattr(self, 'iswidget', False) else True
  36. ADDRESS_KEYS = 'street,extadr,locality,region,pcode,ctry'.split(',')
  37. WORK_KEYS = 'company department postition role'.split()
  38. SUBSCRIPTION_TO = ('to', 'both')
  39. SUBSCRIPTION_FROM = ('from', 'both')
  40.  
  41. class JabberBuddy(common.buddy):
  42.     
  43.     def __init__(self, jabber_, jid, rosteritem = None):
  44.         uname = JID(jid).bare().as_unicode()
  45.         self.jid = JID(jid).bare()
  46.         self.username = uname
  47.         self.resources = { }
  48.         self.subscription = None if rosteritem else None
  49.         self.rostername = None if rosteritem else None
  50.         self.ask = None if rosteritem else None
  51.         self.groups = None if rosteritem else []
  52.         self.profile = False
  53.         common.buddy.__init__(self, uname, jabber_)
  54.         self._gen_pretty_profile()
  55.         self.pending_adds = set()
  56.  
  57.     
  58.     def __call__(self, item):
  59.         self.subscription = item.subscription
  60.         self.ask = item.ask
  61.         self.rostername = item.name
  62.         self.groups = item.groups
  63.         self.check_subscription()
  64.         return self
  65.  
  66.     
  67.     def sort(self, cmp = cmp, key = (lambda x: x), reverse = False):
  68.         pass
  69.  
  70.     
  71.     def check_subscription(self):
  72.         if self.subscription not in SUBSCRIPTION_TO and self.resources and self is not getattr(self.protocol, 'self_buddy', sentinel):
  73.             self.resources.clear()
  74.             self.notify()
  75.         
  76.  
  77.     
  78.     def service(self):
  79.         if self.jid.domain in GTALK_DOMAINS:
  80.             return GTALK
  81.         else:
  82.             return JABBER
  83.  
  84.     service = property(service)
  85.     
  86.     def serviceicon(self):
  87.         if self.jid.domain in GTALK_DOMAINS or any((lambda .0: for j in .0:
  88. isGTalk(j.resource))(self.resources)):
  89.             service = GTALK
  90.         else:
  91.             service = JABBER
  92.         return skin.get('serviceicons.' + service)
  93.  
  94.     serviceicon = property(serviceicon)
  95.     
  96.     def id(self):
  97.         return self.jid
  98.  
  99.     id = property(id)
  100.     
  101.     def away(self):
  102.         if self.service == GTALK:
  103.             if self.resources and not (self.idle):
  104.                 pass
  105.             return not any((lambda .0: for r in .0:
  106. r.available)(self.resources.itervalues()))
  107.         elif self.resources:
  108.             pass
  109.         return all((lambda .0: for r in .0:
  110. r.away)(self.resources.itervalues()))
  111.  
  112.     away = property(away)
  113.     
  114.     def mobile(self):
  115.         return False
  116.  
  117.     mobile = property(mobile)
  118.     
  119.     def blocked(self):
  120.         return False
  121.  
  122.     blocked = property(blocked)
  123.     
  124.     def online(self):
  125.         return bool(self.resources)
  126.  
  127.     online = property(online)
  128.     
  129.     def idle(self):
  130.         if self.service == GTALK:
  131.             if self.resources:
  132.                 pass
  133.             return all((lambda .0: for r in .0:
  134. r.idle)(self.resources.itervalues()))
  135.         else:
  136.             return False
  137.  
  138.     idle = property(idle)
  139.     
  140.     def get_caps(self):
  141.         caps = common.buddy.get_caps(self)
  142.         for r in self.resources.values():
  143.             res = r.jid.resource
  144.             if res and not isGTalk(res):
  145.                 break
  146.                 continue
  147.         
  148.         return caps
  149.  
  150.     caps = property(get_caps)
  151.     
  152.     def _gen_pretty_profile(self):
  153.         profile = odict()
  154.         ok = False
  155.         fullname = self.vcard_get('fn')
  156.         if fullname:
  157.             profile['Full Name:'] = fullname
  158.             ok = True
  159.         
  160.         mapping = {
  161.             'birthday': ('bday',),
  162.             'email_address': ('email', 'address'),
  163.             'phone': ('tel', 'number'),
  164.             'company': ('org', 'name'),
  165.             'department': ('org', 'unit'),
  166.             'postition': ('title',),
  167.             'role': ('role',) }
  168.         for key in ('birthday', 'email_address', 'phone'):
  169.             val = self.vcard_get(*mapping[key])
  170.             if val is not None:
  171.                 profile[key.replace('_', ' ').title() + ':'] = val
  172.                 ok = True
  173.                 continue
  174.         
  175.         homepage = self.vcard_get('url')
  176.         if homepage:
  177.             profile['Website'] = (homepage, homepage)
  178.             ok = True
  179.         
  180.         about = self.vcard_get('desc')
  181.         if about:
  182.             if ok:
  183.                 profile['sep1'] = 4
  184.             
  185.             profile['Additional Information:'] = ''.join([
  186.                 '\n',
  187.                 about])
  188.         
  189.         
  190.         def prettyaddy(addict):
  191.             addy = []
  192.             
  193.             add = lambda s: addy.insert(0, s)
  194.             mstr = '%(street)s %(extadr)s %(locality)s %(region)s %(pcode)s %(ctry)s' % addict
  195.             if isinstance(mstr, unicode):
  196.                 mstr = mstr.encode('utf-8')
  197.             
  198.             murl = 'http://maps.google.com/maps?q=' + quote(mstr)
  199.             if addict.ctry:
  200.                 add('\n' + addict.ctry)
  201.             
  202.             if addict.pcode:
  203.                 add(addict.pcode)
  204.             
  205.             if addict.region:
  206.                 if addict.pcode:
  207.                     add(' ')
  208.                 
  209.                 add(addict.region)
  210.             
  211.             if addict.locality:
  212.                 if addict.region or addict.pcode:
  213.                     add(', ')
  214.                 
  215.                 add(addict.locality)
  216.             
  217.             if addict.extadr:
  218.                 if any((addict.locality, addict.region, addict.pcode)):
  219.                     add('\n')
  220.                 
  221.                 add(addict.extadr)
  222.             
  223.             if addict.street:
  224.                 if any((addict.locality, addict.region, addict.pcode, addict.extadr)):
  225.                     add('\n')
  226.                 
  227.                 add(addict.street)
  228.             
  229.             if addy:
  230.                 add([
  231.                     '(',
  232.                     (murl, 'map'),
  233.                     ')\n'])
  234.             
  235.             return addy
  236.  
  237.         address = self.vcard_get('adr')
  238.         if ok:
  239.             profile['sep3'] = 4
  240.         
  241.         for key in WORK_KEYS:
  242.             val = self.vcard_get(*mapping[key])
  243.             profile[key.title() + ':'] = val
  244.         
  245.         self.last_pretty_profile = profile
  246.         return profile
  247.  
  248.     
  249.     def pretty_profile(self):
  250.         return getattr(self, ('last_pretty_profile',), (lambda : self._gen_pretty_profile()))
  251.  
  252.     pretty_profile = property(pretty_profile)
  253.     
  254.     def get_status_message(self):
  255.         
  256.         try:
  257.             res = self.get_highest_priority_resource()
  258.             if res:
  259.                 if not res.status_message:
  260.                     pass
  261.                 return ''
  262.             else:
  263.                 return ''
  264.         except Exception:
  265.             e = None
  266.             log.warning('status_message(self) on %r: %r', self, e)
  267.             raise 
  268.  
  269.  
  270.     
  271.     def set_status_message(self, value):
  272.         r = self.get_highest_priority_resource()
  273.         if r:
  274.             old = r.status_message
  275.             r.status_message = value
  276.             self.notify('status_message', old, value)
  277.         
  278.  
  279.     status_message = property(get_status_message, set_status_message)
  280.     
  281.     def stripped_msg(self):
  282.         return self.status_message
  283.  
  284.     stripped_msg = property(stripped_msg)
  285.     
  286.     def status(self):
  287.         if self.subscription not in SUBSCRIPTION_TO and self is not getattr(self.protocol, 'self_buddy', sentinel):
  288.             return 'unknown'
  289.         elif not getattr(self, 'resources', []):
  290.             return 'offline'
  291.         elif not self.away:
  292.             return 'available'
  293.         else:
  294.             return 'away'
  295.  
  296.     status = property(status)
  297.     
  298.     def update_presence(self, presence, notify = True, buddy = None):
  299.         if not presence.get_from():
  300.             pass
  301.         buddy = buddy
  302.         presence_type = presence.get_type()
  303.         if not presence_type or presence_type == 'available':
  304.             old_length = len(self.resources)
  305.             self.resources[buddy] = jabber.resource(self.protocol, buddy, presence)
  306.             children = presence.xmlnode.get_children()
  307.             nicks = jabber.jabber_util.xpath_eval(presence.xmlnode, 'n:nick', {
  308.                 'n': NICK_NS })
  309.             if nicks:
  310.                 self.nick = Nick(nicks[0]).nick
  311.             
  312.             if self.jid.domain not in pref('digsby.guest.domains', []):
  313.                 self.protocol.get_buddy_icon(self.name)
  314.             
  315.         elif presence_type == 'unavailable':
  316.             if buddy in self.resources:
  317.                 del self.resources[buddy]
  318.             
  319.         
  320.         if notify:
  321.             self.notify('status')
  322.         
  323.  
  324.     
  325.     def get_highest_priority_resource(self):
  326.         return None if getattr(self, 'resources', []) else None
  327.  
  328.     
  329.     def set_vcard(self, stanza):
  330.         log.info('incoming vcard for %s', self)
  331.         self._vcard_incoming = False
  332.         q = stanza.get_query()
  333.         if not q:
  334.             return None
  335.         
  336.         
  337.         try:
  338.             vc = self.vcard = jabber.VCard(q)
  339.         except ValueError:
  340.             pass
  341.  
  342.         self._incoming_icon(vc.photo)
  343.         self._gen_pretty_profile()
  344.  
  345.     
  346.     def set_vc(self, vcard):
  347.         self._vcard = vcard
  348.  
  349.     
  350.     def get_vc(self):
  351.         return self._vcard
  352.  
  353.     vcard = property(get_vc, set_vc)
  354.     _vcard = cproperty(None, (lambda o: None if o is not None else None), (lambda o: None if o is not None else None))
  355.     
  356.     def vcard_get(self, *stuffs):
  357.         if self.vcard:
  358.             stuff = stuffs[0]
  359.             stuffs = stuffs[1:]
  360.             thing = getattr(self.vcard, stuff, None)
  361.             if isinstance(thing, list) and thing:
  362.                 thing = thing[0]
  363.                 while stuffs:
  364.                     thing = getattr(thing, stuffs[0])
  365.                     stuffs = stuffs[1:]
  366.             elif thing:
  367.                 if stuffs:
  368.                     log.warning_s('%r', stuffs)
  369.                     log.warning_s(self.vcard.as_xml())
  370.                 
  371.             
  372.             return None if thing else thing
  373.         
  374.  
  375.     nick = cproperty(None)
  376.     
  377.     def _incoming_icon(self, photos):
  378.         if photos and photos[0].image:
  379.             img = photos[0].image
  380.             self._update_photo_image(img)
  381.         elif photos and photos[0].uri:
  382.             
  383.             def success(result):
  384.                 (_response, content) = result
  385.                 self._update_photo_image(content)
  386.  
  387.             meth = threaded(urlcacheopen)
  388.             meth.verbose = False
  389.             meth(photos[0].uri, success = success)
  390.         
  391.  
  392.     
  393.     def _update_photo_image(self, data):
  394.         hash = hashlib.sha1(data).hexdigest()
  395.         self.cache_icon(data, hash)
  396.         self.icon_hash = hash
  397.  
  398.     
  399.     def get_remote_alias(self):
  400.         for attr in ('rostername', 'nick'):
  401.             nick = getattr(self, attr, None)
  402.             if nick:
  403.                 return unicode(nick)
  404.                 continue
  405.         
  406.         for attr in ('nickname', 'fn'):
  407.             nick = self.vcard_get(attr)
  408.             if nick:
  409.                 return unicode(nick)
  410.                 continue
  411.         
  412.  
  413.     remote_alias = oproperty(get_remote_alias, observe = [
  414.         'vcard'])
  415.     
  416.     def add_to_group(self, groupname, callback = None):
  417.         log.info('%s add_to_group %s', self, groupname)
  418.         pending = self.pending_adds
  419.         if groupname in pending:
  420.             log.info('ignoring request.')
  421.         else:
  422.             pending.add(groupname)
  423.         item = self.protocol.roster.get_item_by_jid(self.id).clone()
  424.         if groupname not in item.groups:
  425.             item.groups.append(groupname)
  426.             query = item.make_roster_push()
  427.             
  428.             def onsuccess(_s):
  429.                 pending.discard(groupname)
  430.                 callback.success()
  431.  
  432.             
  433.             def onerror(_s = (None, (None, None, None), None)):
  434.                 pending.discard(groupname)
  435.                 log.warning('error adding %r to %s', self.id, groupname)
  436.  
  437.             self.protocol.send_cb(query, success = onsuccess, error = onerror, timeout = onerror)
  438.         
  439.  
  440.     add_to_group = action(needs = ((unicode, 'Group name'),))(callsback(add_to_group))
  441.     
  442.     def remove(self, callback = None):
  443.         
  444.         try:
  445.             item = self.protocol.roster.get_item_by_jid(self.id).clone()
  446.         except KeyError:
  447.             return None
  448.  
  449.         item.subscription = 'remove'
  450.         self.protocol.send_cb(item.make_roster_push(), callback = callback)
  451.  
  452.     remove = action()(callsback(remove))
  453.     
  454.     def subscribed(self):
  455.         self.protocol.send_presence(Presence(to_jid = self.id, stanza_type = 'subscribed'))
  456.  
  457.     subscribed = action((lambda self: if no_widget(self) is None:
  458. passelif self.subscription in SUBSCRIPTION_FROM:
  459. passTrue))(subscribed)
  460.     
  461.     def unsubscribed(self):
  462.         self.protocol.send_presence(Presence(to_jid = self.id, stanza_type = 'unsubscribed'))
  463.  
  464.     unsubscribed = action((lambda self: if no_widget(self) is None:
  465. passelif self.subscription not in SUBSCRIPTION_FROM:
  466. passTrue))(unsubscribed)
  467.     
  468.     def subscribe(self):
  469.         self.protocol.send_presence(Presence(to_jid = self.id, stanza_type = 'subscribe'))
  470.  
  471.     subscribe = action((lambda self: if no_widget(self) is None:
  472. passelif self.subscription in SUBSCRIPTION_TO:
  473. passTrue))(subscribe)
  474.     
  475.     def unsubscribe(self):
  476.         self.protocol.send_presence(Presence(to_jid = self.id, stanza_type = 'unsubscribe'))
  477.  
  478.     unsubscribe = action((lambda self: if no_widget(self) is None:
  479. passelif self.subscription not in SUBSCRIPTION_TO:
  480. passTrue))(unsubscribe)
  481.     
  482.     def appear_offline_to(self):
  483.         self.protocol.send_presence(Presence(stanza_type = 'unavailable', status = 'Logged Out', to_jid = self.id))
  484.  
  485.     
  486.     def expand(self):
  487.         print 'expand %r' % self
  488.  
  489.     expand = action()(expand)
  490.     
  491.     def sorted_resources(self):
  492.         return sorted(self.resources.itervalues(), key = (lambda r: (r.priority, r.jid)), reverse = True)
  493.  
  494.     
  495.     def __iter__(self):
  496.         return iter(self.sorted_resources())
  497.  
  498.     
  499.     def __len__(self):
  500.         return len(self.resources)
  501.  
  502.     
  503.     def __getitem__(self, index):
  504.         return self.sorted_resources()[index]
  505.  
  506.     
  507.     def __repr__(self):
  508.         
  509.         try:
  510.             res = len(self.resources)
  511.         except:
  512.             res = 0
  513.  
  514.         
  515.         try:
  516.             n = self.name
  517.         except:
  518.             n = ''
  519.  
  520.         return '<JabberBuddy %s %d>' % (n, res)
  521.  
  522.  
  523.  
  524. def dupe_presence(p):
  525.     return Presence(p.get_node())
  526.  
  527.