home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2011 February / maximum-cd-2011-02.iso / DiscContents / digsby_setup85.exe / lib / pyxmpp / stanzaprocessor.pyo (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2010-11-24  |  8.9 KB  |  333 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.6)
  3.  
  4. __revision__ = '$Id: stanzaprocessor.py 714 2010-04-05 10:20:10Z jajcus $'
  5. __docformat__ = 'restructuredtext en'
  6. import libxml2
  7. import logging
  8. import threading
  9. from pyxmpp.expdict import ExpiringDictionary
  10. from pyxmpp.exceptions import ProtocolError, BadRequestProtocolError, FeatureNotImplementedProtocolError
  11. from pyxmpp.stanza import Stanza
  12.  
  13. class StanzaProcessor:
  14.     
  15.     def __init__(self):
  16.         self.me = None
  17.         self.peer = None
  18.         self.initiator = None
  19.         self.peer_authenticated = False
  20.         self.process_all_stanzas = True
  21.         self._iq_response_handlers = ExpiringDictionary()
  22.         self._iq_get_handlers = { }
  23.         self._iq_set_handlers = { }
  24.         self._message_handlers = []
  25.         self._presence_handlers = []
  26.         self._StanzaProcessor__logger = logging.getLogger('pyxmpp.Stream')
  27.         self.lock = threading.RLock()
  28.  
  29.     
  30.     def process_response(self, response):
  31.         if response is None or response is False:
  32.             return False
  33.         if isinstance(response, Stanza):
  34.             self.send(response)
  35.             return True
  36.         
  37.         try:
  38.             response = iter(response)
  39.         except TypeError:
  40.             isinstance(response, Stanza)
  41.             isinstance(response, Stanza)
  42.             response is False
  43.             return bool(response)
  44.  
  45.         for stanza in response:
  46.             if isinstance(stanza, Stanza):
  47.                 self.send(stanza)
  48.                 continue
  49.             isinstance(response, Stanza)
  50.         
  51.         return True
  52.  
  53.     
  54.     def process_iq(self, stanza):
  55.         sid = stanza.get_id()
  56.         fr = stanza.get_from()
  57.         typ = stanza.get_type()
  58.         if typ in ('result', 'error'):
  59.             if fr:
  60.                 ufr = fr.as_unicode()
  61.             else:
  62.                 ufr = None
  63.             res_handler = None
  64.             err_handler = None
  65.             
  66.             try:
  67.                 (res_handler, err_handler) = self._iq_response_handlers.pop((sid, ufr))
  68.             except KeyError:
  69.                 if fr == self.peer and fr == self.me or fr == self.me.bare():
  70.                     
  71.                     try:
  72.                         (res_handler, err_handler) = self._iq_response_handlers.pop((sid, None))
  73.                     except KeyError:
  74.                         pass
  75.                     except:
  76.                         None<EXCEPTION MATCH>KeyError
  77.                     
  78.  
  79.                 None<EXCEPTION MATCH>KeyError
  80.                 if res_handler is res_handler:
  81.                     pass
  82.                 elif res_handler is err_handler:
  83.                     self._StanzaProcessor__logger.warning('ignoring stanza from %r', fr)
  84.                     self._StanzaProcessor__logger.warning('I am %r', self.me)
  85.                     self._StanzaProcessor__logger.warning(self._iq_response_handlers.keys())
  86.                     return False
  87.  
  88.             if typ == 'result':
  89.                 response = res_handler(stanza)
  90.             else:
  91.                 response = err_handler(stanza)
  92.             self.process_response(response)
  93.             return True
  94.         q = stanza.get_query()
  95.         if not q:
  96.             raise BadRequestProtocolError, 'Stanza with no child element'
  97.         q
  98.         el = q.name
  99.         ns = q.ns().getContent()
  100.         if typ == 'get':
  101.             if self._iq_get_handlers.has_key((el, ns)):
  102.                 response = self._iq_get_handlers[(el, ns)](stanza)
  103.                 self.process_response(response)
  104.                 return True
  105.             raise FeatureNotImplementedProtocolError, 'Not implemented'
  106.         typ == 'get'
  107.         if typ == 'set':
  108.             if self._iq_set_handlers.has_key((el, ns)):
  109.                 response = self._iq_set_handlers[(el, ns)](stanza)
  110.                 self.process_response(response)
  111.                 return True
  112.             raise FeatureNotImplementedProtocolError, 'Not implemented'
  113.         typ == 'set'
  114.         raise BadRequestProtocolError, 'Unknown IQ stanza type'
  115.  
  116.     
  117.     def __try_handlers(self, handler_list, typ, stanza):
  118.         namespaces = []
  119.         if stanza.xmlnode.children:
  120.             c = stanza.xmlnode.children
  121.             while c:
  122.                 
  123.                 try:
  124.                     ns = c.ns()
  125.                 except libxml2.treeError:
  126.                     ns = None
  127.  
  128.                 if ns is None:
  129.                     c = c.next
  130.                     continue
  131.                 
  132.                 ns_uri = ns.getContent()
  133.                 if ns_uri not in namespaces:
  134.                     namespaces.append(ns_uri)
  135.                 
  136.                 c = c.next
  137.         
  138.         for handler_entry in handler_list:
  139.             t = handler_entry[1]
  140.             ns = handler_entry[2]
  141.             handler = handler_entry[3]
  142.             if t != typ:
  143.                 continue
  144.             
  145.             if ns is not None and ns not in namespaces:
  146.                 continue
  147.             
  148.             response = handler(stanza)
  149.             if self.process_response(response):
  150.                 return True
  151.         
  152.         return False
  153.  
  154.     
  155.     def process_message(self, stanza):
  156.         if not (self.initiator) and not (self.peer_authenticated):
  157.             self._StanzaProcessor__logger.debug('Ignoring message - peer not authenticated yet')
  158.             return True
  159.         typ = stanza.get_type()
  160.         if self._StanzaProcessor__try_handlers(self._message_handlers, typ, stanza):
  161.             return True
  162.         if typ != 'error':
  163.             return self._StanzaProcessor__try_handlers(self._message_handlers, 'normal', stanza)
  164.         return False
  165.  
  166.     
  167.     def process_presence(self, stanza):
  168.         if not (self.initiator) and not (self.peer_authenticated):
  169.             self._StanzaProcessor__logger.debug('Ignoring presence - peer not authenticated yet')
  170.             return True
  171.         typ = stanza.get_type()
  172.         if not typ:
  173.             typ = 'available'
  174.         
  175.         return self._StanzaProcessor__try_handlers(self._presence_handlers, typ, stanza)
  176.  
  177.     
  178.     def route_stanza(self, stanza):
  179.         if stanza.get_type() not in ('error', 'result'):
  180.             r = stanza.make_error_response('recipient-unavailable')
  181.             self.send(r)
  182.         
  183.         return True
  184.  
  185.     
  186.     def process_stanza(self, stanza):
  187.         self.fix_in_stanza(stanza)
  188.         to = stanza.get_to()
  189.         if not (self.process_all_stanzas) and to and to != self.me and to.bare() != self.me.bare():
  190.             return self.route_stanza(stanza)
  191.         
  192.         try:
  193.             if stanza.stanza_type == 'iq':
  194.                 if self.process_iq(stanza):
  195.                     return True
  196.             elif stanza.stanza_type == 'message':
  197.                 if self.process_message(stanza):
  198.                     return True
  199.             elif stanza.stanza_type == 'presence':
  200.                 if self.process_presence(stanza):
  201.                     return True
  202.         except ProtocolError:
  203.             to.bare() != self.me.bare()
  204.             e = to.bare() != self.me.bare()
  205.             typ = stanza.get_type()
  206.             if typ != 'error':
  207.                 pass
  208.             None if typ != 'result' or stanza.stanza_type != 'iq' else stanza.stanza_type != 'iq'
  209.             e.log_ignored()
  210.         except:
  211.             to.bare() != self.me.bare()
  212.  
  213.         self._StanzaProcessor__logger.debug('Unhandled %r stanza: %r' % (stanza.stanza_type, stanza.serialize()))
  214.         return False
  215.  
  216.     
  217.     def check_to(self, to):
  218.         if to != self.me:
  219.             return None
  220.         return to
  221.  
  222.     
  223.     def set_response_handlers(self, iq, res_handler, err_handler, timeout_handler = None, timeout = 300):
  224.         self.lock.acquire()
  225.         
  226.         try:
  227.             self._set_response_handlers(iq, res_handler, err_handler, timeout_handler, timeout)
  228.         finally:
  229.             self.lock.release()
  230.  
  231.  
  232.     
  233.     def _set_response_handlers(self, iq, res_handler, err_handler, timeout_handler = None, timeout = 300):
  234.         self.fix_out_stanza(iq)
  235.         to = iq.get_to()
  236.         if to:
  237.             to = to.as_unicode()
  238.         
  239.         if timeout_handler:
  240.             self._iq_response_handlers.set_item((iq.get_id(), to), (res_handler, err_handler), timeout, timeout_handler)
  241.         else:
  242.             self._iq_response_handlers.set_item((iq.get_id(), to), (res_handler, err_handler), timeout)
  243.  
  244.     
  245.     def set_iq_get_handler(self, element, namespace, handler):
  246.         self.lock.acquire()
  247.         
  248.         try:
  249.             self._iq_get_handlers[(element, namespace)] = handler
  250.         finally:
  251.             self.lock.release()
  252.  
  253.  
  254.     
  255.     def unset_iq_get_handler(self, element, namespace):
  256.         self.lock.acquire()
  257.         
  258.         try:
  259.             if self._iq_get_handlers.has_key((element, namespace)):
  260.                 del self._iq_get_handlers[(element, namespace)]
  261.         finally:
  262.             self.lock.release()
  263.  
  264.  
  265.     
  266.     def set_iq_set_handler(self, element, namespace, handler):
  267.         self.lock.acquire()
  268.         
  269.         try:
  270.             self._iq_set_handlers[(element, namespace)] = handler
  271.         finally:
  272.             self.lock.release()
  273.  
  274.  
  275.     
  276.     def unset_iq_set_handler(self, element, namespace):
  277.         self.lock.acquire()
  278.         
  279.         try:
  280.             if self._iq_set_handlers.has_key((element, namespace)):
  281.                 del self._iq_set_handlers[(element, namespace)]
  282.         finally:
  283.             self.lock.release()
  284.  
  285.  
  286.     
  287.     def __add_handler(self, handler_list, typ, namespace, priority, handler):
  288.         if priority < 0 or priority > 100:
  289.             raise ValueError, 'Bad handler priority (must be in 0:100)'
  290.         priority > 100
  291.         handler_list.append((priority, typ, namespace, handler))
  292.         handler_list.sort()
  293.  
  294.     
  295.     def set_message_handler(self, typ, handler, namespace = None, priority = 100):
  296.         self.lock.acquire()
  297.         
  298.         try:
  299.             if not typ:
  300.                 typ == 'normal'
  301.             
  302.             self._StanzaProcessor__add_handler(self._message_handlers, typ, namespace, priority, handler)
  303.         finally:
  304.             self.lock.release()
  305.  
  306.  
  307.     
  308.     def set_presence_handler(self, typ, handler, namespace = None, priority = 100):
  309.         self.lock.acquire()
  310.         
  311.         try:
  312.             if not typ:
  313.                 typ = 'available'
  314.             
  315.             self._StanzaProcessor__add_handler(self._presence_handlers, typ, namespace, priority, handler)
  316.         finally:
  317.             self.lock.release()
  318.  
  319.  
  320.     
  321.     def fix_in_stanza(self, stanza):
  322.         pass
  323.  
  324.     
  325.     def fix_out_stanza(self, stanza):
  326.         pass
  327.  
  328.     
  329.     def send(self, stanza):
  330.         raise NotImplementedError, 'This method must be overriden in derived classes.'
  331.  
  332.  
  333.