home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2012 January / maximum-cd-2012-01.iso / DiscContents / digsby_setup.exe / lib / msn / MSNSocket.pyo (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2011-10-05  |  14.4 KB  |  523 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.6)
  3.  
  4. from __future__ import with_statement
  5. import socket
  6. import threading
  7. import logging
  8. import collections
  9. import common
  10. import util
  11. import util.Events as Events
  12. log = logging.getLogger('msn.sock')
  13. import msn
  14. import msn.Msnifier as msn
  15.  
  16. dummy = lambda *a, **k: pass
  17.  
  18. def trid(max = 2147483647, i = 0):
  19.     while True:
  20.         i += 1
  21.         yield i
  22.         if i == max:
  23.             i = 0
  24.             continue
  25.  
  26.  
  27. class MSNSocketBase(Events.EventMixin):
  28.     events = Events.EventMixin.events | set(('on_connect', 'on_send', 'on_conn_error', 'on_close', 'on_message'))
  29.     delim = '\r\n'
  30.     payload_commands = 'MSG UUX UBX PAG IPG NOT GCF ADL UUN UBN RML FQY 241 508 UBM UUM'.split()
  31.     
  32.     def __init__(self):
  33.         Events.EventMixin.__init__(self)
  34.         self.trid = trid()
  35.         self.callbacks = collections.defaultdict(list)
  36.         if not hasattr(self, '_lock'):
  37.             self._lock = threading.RLock()
  38.         
  39.         self.timeouts = { }
  40.  
  41.     
  42.     def set_trid(self, msgobj, trid):
  43.         if trid is True:
  44.             msgobj.trid = self.trid.next()
  45.         
  46.  
  47.     
  48.     def set_callbacks(self, msgobj, callback):
  49.         if callback is sentinel:
  50.             callback = None
  51.         
  52.         if msgobj.is_trid:
  53.             self.set_timeout(msgobj)
  54.             self.callbacks[msgobj.trid].append(callback)
  55.         else:
  56.             self.callbacks[msgobj.cmd].append(callback)
  57.  
  58.     
  59.     def set_timeout(self, msgobj):
  60.         timeout = getattr(msgobj, 'timeout', None)
  61.         if timeout is not None and common.pref('msn.socket.use_timeout', type = bool, default = False):
  62.             log.info('Starting timeout for %r', msgobj)
  63.             timer = util.Timer(timeout, self.timeout_handler(msgobj))
  64.             self.timeouts[msgobj.trid] = timer
  65.             timer.start()
  66.         
  67.  
  68.     
  69.     def timeout_handler(self, msgobj):
  70.         
  71.         def handler():
  72.             log.debug('This message has timed out: %r', msgobj)
  73.             msgcopy = msgobj.copy()
  74.             msgcopy.timeout = msgobj.timeout
  75.             msgcopy.retries = msgobj.retries - 1
  76.             msgcopy.trid = 0
  77.             if msgcopy.retries == 0:
  78.                 return None
  79.             log.debug('Retrying this message that timed out: %r', msgcopy)
  80.             self._lock.__enter__()
  81.             
  82.             try:
  83.                 callback = self.callbacks.pop(msgobj.trid, None)
  84.             finally:
  85.                 pass
  86.  
  87.             self.send(msgcopy, trid = True, callback = callback)
  88.  
  89.         return handler
  90.  
  91.     
  92.     def unset_timeout(self, msgobj, include_previous = True):
  93.         if not msgobj.is_trid:
  94.             return None
  95.         if include_previous:
  96.             for i in range(msgobj.trid):
  97.                 self.unset_timeout_single(i)
  98.             
  99.         
  100.         self.unset_timeout_single(msgobj.trid)
  101.  
  102.     
  103.     def unset_timeout_single(self, key):
  104.         
  105.         try:
  106.             timer = self.timeouts.pop(key, None)
  107.             if timer is not None:
  108.                 timer.stop()
  109.         except (IndexError, KeyError):
  110.             pass
  111.  
  112.  
  113.     
  114.     def pause(self):
  115.         pass
  116.  
  117.     
  118.     def unpause(self):
  119.         pass
  120.  
  121.     
  122.     def on_connect(self):
  123.         return self
  124.  
  125.     on_connect = Events.event(on_connect)
  126.     
  127.     def on_send(self, data):
  128.         pass
  129.  
  130.     on_send = Events.event(on_send)
  131.     
  132.     def on_conn_error(self, e = None):
  133.         log.info('%r had a connection error: %r', self, e)
  134.         return (self, e)
  135.  
  136.     on_conn_error = Events.event(on_conn_error)
  137.     
  138.     def on_close(self):
  139.         return self
  140.  
  141.     on_close = Events.event(on_close)
  142.     
  143.     def unset_callbacks(self, msg):
  144.         callback = None
  145.         
  146.         try:
  147.             if not msg.trid:
  148.                 pass
  149.             callback = self.callbacks[msg.cmd][0]
  150.         except (KeyError, IndexError):
  151.             e = None
  152.             pop = False
  153.  
  154.         pop = True
  155.         if pop:
  156.             if msg.is_trid:
  157.                 self.unset_timeout(msg, include_previous = True)
  158.                 for i in range(msg.trid):
  159.                     
  160.                     try:
  161.                         self.callbacks.pop(i, None)
  162.                     continue
  163.                     except (IndexError, KeyError):
  164.                         continue
  165.                     
  166.  
  167.                 
  168.             elif not msg.trid:
  169.                 self.callbacks[msg.cmd].pop(0)
  170.             
  171.         
  172.         return callback
  173.  
  174.     unset_callbacks = util.lock(unset_callbacks)
  175.     
  176.     def adjust_message(self, msg):
  177.         if msg.cmd == 'QNG':
  178.             msg.cmd = 'PNG'
  179.             msg.trid = 0
  180.         
  181.         return msg
  182.  
  183.     
  184.     def on_message(self, msg):
  185.         self.event('on_message', msg)
  186.         msg = self.adjust_message(msg)
  187.         callback = self.unset_callbacks(msg)
  188.         if callback is None:
  189.             return None
  190.         
  191.         try:
  192.             if msg.is_error:
  193.                 f = callback.error
  194.             else:
  195.                 f = callback.success
  196.         except AttributeError:
  197.             callback is None
  198.             e = callback is None
  199.             log.error('AttributeError in msnsocket.on_message: %r\ncallback was: %r', e, callback)
  200.         except:
  201.             callback is None
  202.  
  203.         log.debug('MSNSocket calling %r', f)
  204.         
  205.         try:
  206.             f(self, msg)
  207.         except Exception:
  208.             callback is None
  209.             e = callback is None
  210.             log.error('Error in callback')
  211.             import traceback
  212.             traceback.print_exc()
  213.         except:
  214.             callback is None
  215.  
  216.  
  217.     
  218.     def close(self):
  219.         while self.timeouts:
  220.             
  221.             try:
  222.                 (k, v) = self.timeouts.popitem()
  223.             except KeyError:
  224.                 break
  225.                 continue
  226.  
  227.             if v is not None:
  228.                 v.stop()
  229.                 continue
  230.  
  231.  
  232.  
  233. class MSNSocket(MSNSocketBase, common.socket):
  234.     speed_limit = 2000
  235.     speed_window = 0.25
  236.     
  237.     def __init__(self):
  238.         common.socket.__init__(self)
  239.         MSNSocketBase.__init__(self)
  240.         self.set_terminator(self.delim)
  241.         self.data = ''
  242.         self.expecting = 'command'
  243.         self._server = None
  244.         self.rater = msn.Msnifier.Msnifier(self)
  245.         self.rater.start()
  246.         self._bc_lock = threading.RLock()
  247.         self.bytecount = [
  248.             (0, util.default_timer())]
  249.         log.debug('%r created', self)
  250.  
  251.     
  252.     def get_local_sockname(self):
  253.         return self.socket.getsockname()
  254.  
  255.     
  256.     def connect_args_for(self, type, addr):
  257.         return (type, addr)
  258.  
  259.     
  260.     def connect(self, type, host_port):
  261.         self._scktype = type
  262.         
  263.         try:
  264.             (host, port) = host_port
  265.         except (ValueError, TypeError):
  266.             raise TypeError("%r address must be <type 'tuple'> (host, port) not %r (%r)", type(self).__name__, type(host_port), host_port)
  267.  
  268.         if self._server is not None:
  269.             raise ValueError("Don't know which server to use! self._server = %r, host_port = %r.", self._server, host_port)
  270.         self._server is not None
  271.         self._server = host_port
  272.         log.info('connecting socket to %r', self._server)
  273.         
  274.         try:
  275.             common.socket.connect(self, self._server, error = self.on_conn_error)
  276.         except Exception:
  277.             e = None
  278.             self.on_conn_error(e)
  279.             return None
  280.  
  281.         self.bind_event('on_message', (lambda msg: log.debug('Received %r', msg)))
  282.  
  283.     _connect = connect
  284.     
  285.     def _disconnect(self):
  286.         self.close_when_done()
  287.  
  288.     
  289.     def _closed(self):
  290.         return not getattr(self.socket, 'connected', False)
  291.  
  292.     _closed = property(_closed)
  293.     
  294.     def __repr__(self):
  295.         
  296.         try:
  297.             s = 'connected to %r' % (self.socket.getpeername(),)
  298.         except socket.error:
  299.             s = 'not connected'
  300.  
  301.         return '<%s %s>' % (type(self).__name__, s)
  302.  
  303.     
  304.     def test_connection(self, callback = None):
  305.         if self._scktype == 'NS':
  306.             self.send(msn.Message('PNG'), callback = callback)
  307.         else:
  308.             log.info('Not testing connection because this is not an NS socket.')
  309.             callback.success()
  310.  
  311.     test_connection = util.callsback(test_connection)
  312.     
  313.     def handle_connect(self):
  314.         log.debug('connection established')
  315.         self.on_connect()
  316.  
  317.     
  318.     def handle_expt(self):
  319.         log.warning('OOB data. self.data = %r', self.data)
  320.         self.close()
  321.  
  322.     
  323.     def collect_incoming_data(self, data):
  324.         self.data += data
  325.  
  326.     collect_incoming_data = util.lock(collect_incoming_data)
  327.     
  328.     def set_terminator(self, term):
  329.         common.socket.set_terminator(self, term)
  330.  
  331.     
  332.     def found_terminator(self):
  333.         self.data += self.delim
  334.         
  335.         try:
  336.             self._lock.__enter__()
  337.             
  338.             try:
  339.                 self.data = ''
  340.                 data = self.data
  341.                 dlist = data.split(' ')
  342.                 cmd = dlist[0]
  343.                 if self.expecting == 'command' and dlist[0] in self.payload_commands:
  344.                     self.expecting = 'payload'
  345.                     self.data = data
  346.                     
  347.                     try:
  348.                         new_term = int(dlist[-1])
  349.                     except ValueError:
  350.                         self._lock.__exit__
  351.                         self._lock.__exit__
  352.                         self._lock
  353.                         new_term = 0
  354.                     except:
  355.                         self
  356.  
  357.                     if not new_term:
  358.                         self.found_terminator()
  359.                         new_term = self.delim
  360.                     
  361.                     return self.set_terminator(new_term)
  362.                 self.set_terminator(self.delim)
  363.                 log.debug_s('IN  : %r', data)
  364.                 msg = msn.Message.from_net(data, payload)
  365.             finally:
  366.                 pass
  367.  
  368.         except Exception:
  369.             self
  370.             e = self
  371.             log.info('error parsing message, testing connection\nError was %r', e)
  372.             self.test_connection(success = self.conn_ok, error = self.conn_error)
  373.             import traceback
  374.             traceback.print_exc()
  375.         except:
  376.             self
  377.  
  378.         self.on_message(msg)
  379.  
  380.     
  381.     def handle_close(self):
  382.         log.warning('socket closed, self.data = %r', self.data)
  383.         if self.rater is not None:
  384.             self.rater.stop()
  385.             self.rater = None
  386.         
  387.         self.close()
  388.  
  389.     
  390.     def close(self):
  391.         log.warning('socket closing, self.data = %r', self.data)
  392.         MSNSocketBase.close(self)
  393.         common.socket.close(self)
  394.         self.on_close()
  395.  
  396.     
  397.     def send_gen(self, gen, priority = 5):
  398.         if self.rater is not None:
  399.             self.rater.send_pkt(gen, priority)
  400.         else:
  401.             log.error("Can't send generator after rater has been stopped")
  402.  
  403.     
  404.     def send(self, msgobj, trid = sentinel, callback = None, **kw):
  405.         self.set_trid(msgobj, trid)
  406.         self.set_callbacks(msgobj, callback)
  407.         log.debug('Sending %r', msgobj)
  408.         if self.rater is not None:
  409.             self.rater.send_pkt(str(msgobj), **kw)
  410.         else:
  411.             self._send(str(msgobj))
  412.  
  413.     send = util.callsback(send)
  414.     
  415.     def conn_ok(self):
  416.         log.info('connection test passed')
  417.  
  418.     
  419.     def conn_error(self):
  420.         log.warning('connection test failed')
  421.         self.close_when_done()
  422.         self.on_conn_error()
  423.  
  424.     
  425.     def _send(self, data, *a, **k):
  426.         log.log_s(0, 'sent: %s' % data)
  427.         self._lock.__enter__()
  428.         
  429.         try:
  430.             log.debug_s('OUT : %r' % (data,))
  431.             
  432.             try:
  433.                 if not common.socket.send(self, data, *a, **k):
  434.                     log.critical('Message dropped in %r, data = %r', self, data)
  435.             except Exception:
  436.                 self._lock.__exit__
  437.                 e = self._lock.__exit__
  438.                 self._lock
  439.                 log.critical('Error sending message in %r. error was %r, data = %r', self, e, data)
  440.                 
  441.                 try:
  442.                     if data == 'OUT\r\n':
  443.                         e.verbose = False
  444.                 except Exception:
  445.                     pass
  446.  
  447.                 self.handle_error(e)
  448.                 if self.connected:
  449.                     self.close()
  450.                 
  451.                 return None
  452.  
  453.         finally:
  454.             pass
  455.  
  456.         self.on_send(data)
  457.         now = util.default_timer()
  458.         self._bc_lock.__enter__()
  459.         
  460.         try:
  461.             self.bytecount.append((len(data), now))
  462.         finally:
  463.             pass
  464.  
  465.  
  466.     
  467.     def time_to_send(self, data):
  468.         now = util.default_timer()
  469.         self._bc_lock.__enter__()
  470.         
  471.         try:
  472.             self.bytecount = (self._bc_lock.__exit__, filter)((lambda t: now - t[1] < self.speed_window), self.bytecount)
  473.         finally:
  474.             pass
  475.  
  476.         send_rate = sum((lambda .0: for b in .0:
  477. b[0])(self.bytecount))
  478.         if send_rate < self.speed_limit:
  479.             return 0
  480.         log.debug('sending too fast')
  481.         for size, tstamp in reversed(self.bytecount):
  482.             bytes += size
  483.             interval = now - tstamp
  484.             if (bytes / interval) * self.speed_window > self.speed_limit:
  485.                 break
  486.                 continue
  487.             bytes = dlen = len(data)
  488.         
  489.         tts = (bytes / self.speed_limit) * self.speed_window + interval
  490.         log.log(5, 'currently sending at %d bytes/sec', send_rate)
  491.         log.debug('sleeping for %r seconds' % tts)
  492.         return tts
  493.  
  494.     
  495.     def close_when_done(self):
  496.         if self.rater is not None:
  497.             self.rater.stop()
  498.             self.rater = None
  499.         
  500.         if getattr(self, 'closed', False):
  501.             return None
  502.         self.closed = True
  503.         
  504.         try:
  505.             self.send(msn.Message('OUT'))
  506.         except socket.error:
  507.             getattr(self, 'closed', False)
  508.             getattr(self, 'closed', False)
  509.         except:
  510.             getattr(self, 'closed', False)
  511.  
  512.         
  513.         try:
  514.             self.close()
  515.         except socket.error:
  516.             getattr(self, 'closed', False)
  517.             getattr(self, 'closed', False)
  518.         except:
  519.             getattr(self, 'closed', False)
  520.  
  521.  
  522.  
  523.