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

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.6)
  3.  
  4. from __future__ import with_statement
  5. import sys
  6. import random
  7. import logging
  8. import socket
  9. import collections
  10. import time
  11. from threading import RLock
  12. from traceback import print_exc
  13. import hub
  14. import common
  15. import oscar
  16. from oscar.Snactivator import Snactivator
  17. from util import Storage, try_this, callsback, isgeneratormethod
  18. from util.primitives.structures import unpack_named
  19. log = logging.getLogger('oscar.sock')
  20. from struct import pack
  21. from common import netcall
  22.  
  23. def _generate_flap_sequence_start():
  24.     n = random.randint(0, sys.maxint)
  25.     s = 0
  26.     i = n
  27.     while i:
  28.         i >>= 3
  29.         s = (s + i) % 0xFFFFFFFFL
  30.     return ((0 - s ^ n & 255) & 7 ^ n) + 2 & 32767
  31.  
  32.  
  33. def flap_sequence_number(start = 0):
  34.     i = start
  35.     while None:
  36.         yield i
  37.         i += 1
  38.         if i >= 32768:
  39.             i = 1
  40.             continue
  41.         continue
  42.         return None
  43.  
  44.  
  45. def default_cb(*a, **kw):
  46.     log.debug_s('Socket ignoring (%s, %s)', a, kw)
  47.  
  48.  
  49. class OscarSocket(common.socket):
  50.     flap_hdr_size = 6
  51.     snac_hdr_size = 10
  52.     id = 42
  53.     func_templ = '\n    def %(name)s (self):\n        print "%(name)s is not implemented!"\n        print self.hdr\n        print self.data\n    '
  54.     
  55.     def _repr(self):
  56.         
  57.         try:
  58.             return repr(self._OscarSocket__oserver)
  59.         except Exception:
  60.             return '??'
  61.  
  62.  
  63.     
  64.     def __init__(self):
  65.         common.socket.__init__(self)
  66.         self.on_connect = default_cb
  67.         self.on_incoming = default_cb
  68.         self.on_close = default_cb
  69.         self.cookie = None
  70.         self.bos = False
  71.         self.callbacks = collections.defaultdict(list)
  72.         self.error_callbacks = collections.defaultdict(list)
  73.         self.rate_lock = RLock()
  74.         self.hdr = None
  75.         self.buf = ''
  76.         self.data = ''
  77.         self.seq = flap_sequence_number(_generate_flap_sequence_start())
  78.         self.req = flap_sequence_number(_generate_flap_sequence_start())
  79.         self.rate_classes = []
  80.         self.rates = { }
  81.         self.rate_lvl_incr = False
  82.         self.snactivate = self._send_snac
  83.         self.snactivator = None
  84.  
  85.     
  86.     def connect(self, server, cookie = None, incoming = None, close = None, callback = None, bos = False):
  87.         if not callback:
  88.             pass
  89.         self.on_connect = default_cb
  90.         if not incoming:
  91.             pass
  92.         self.on_incoming = default_cb
  93.         if not close:
  94.             pass
  95.         self.on_close = default_cb
  96.         self.cookie = cookie
  97.         self.bos = bos
  98.         self.set_terminator(self.flap_hdr_size)
  99.         log.info('oscar socket connecting to %s', server)
  100.         self._OscarSocket__oserver = server
  101.         common.socket.connect(self, server, error = callback.error)
  102.  
  103.     connect = callsback(connect)
  104.     
  105.     def handle_error(self, e = None):
  106.         if isinstance(e, socket.error):
  107.             if self.on_close is not None:
  108.                 log.error('Socket error for %r, calling on_close (= %r): %r', self, self.on_close, e)
  109.                 self.on_close(self)
  110.             else:
  111.                 log.info('handle_error in %r but on_close is None' % self)
  112.         
  113.         common.socket.handle_error(self, e)
  114.  
  115.     
  116.     def test_connection(self):
  117.         
  118.         try:
  119.             self.send_flap(5)
  120.         except Exception:
  121.             e = None
  122.             print_exc()
  123.             if not self.on_close:
  124.                 pass
  125.             default_cb(self)
  126.  
  127.  
  128.     
  129.     def apply_rates(self, rate_classes, rate_groups):
  130.         self.rate_lock.__enter__()
  131.         
  132.         try:
  133.             self.rates.update(rate_groups)
  134.         finally:
  135.             pass
  136.  
  137.         self._lock.__enter__()
  138.         
  139.         try:
  140.             self.snactivate = self.snactivator.send_snac
  141.         finally:
  142.             pass
  143.  
  144.  
  145.     
  146.     def calc_rate_level(self, rate_class):
  147.         old_level = rate_class.current_level
  148.         window = rate_class.window
  149.         now = int(time.time())
  150.         time_diff = (now - rate_class.last_time) * 1000
  151.         new_level = min(int(((window - 1) * old_level + time_diff) / window), rate_class.max_level)
  152.         return (new_level, now)
  153.  
  154.     
  155.     def snac_rate_class(self, fam, sub, *a):
  156.         
  157.         try:
  158.             return self.rate_classes[self.rates[(fam, sub)] - 1]
  159.         except KeyError:
  160.             return None
  161.  
  162.  
  163.     
  164.     def _get_rate_lvls(self, rclass):
  165.         return (rclass.max_level, rclass.current_level, rclass.alert_level, rclass.clear_level, rclass.window)
  166.  
  167.     
  168.     def time_to_send(self, s):
  169.         fam = s[0]
  170.         sub = s[1]
  171.         rclass = self.snac_rate_class(fam, sub)
  172.         (ml, curl, al, clrl, w) = self._get_rate_lvls(rclass)
  173.         threshold = min(ml, al + (clrl - al) * 2)
  174.         self.rate_lock.__enter__()
  175.         
  176.         try:
  177.             if (curl < al or self.rate_lvl_incr) and curl < threshold:
  178.                 self.rate_lvl_incr = True
  179.             else:
  180.                 self.rate_lvl_incr = False
  181.                 return 0
  182.             k = 500
  183.             step = ml / k
  184.             wait = w * step + curl
  185.             delta = rclass.last_time - int(time.time())
  186.             to_send = delta + wait / 1000
  187.             return max(0, to_send)
  188.  
  189.  
  190.     
  191.     def handle_connect(self):
  192.         log.debug('connected')
  193.  
  194.     
  195.     def handle_close(self):
  196.         log.info('closed. calling on_close=%r', self.on_close)
  197.         if not self.on_close:
  198.             pass
  199.         default_cb(self)
  200.         self.close()
  201.  
  202.     
  203.     def handle_expt(self):
  204.         log.warning('oob data')
  205.         self.handle_close()
  206.  
  207.     
  208.     def collect_incoming_data(self, data):
  209.         pass
  210.  
  211.     
  212.     def set_terminator(self, term):
  213.         common.socket.set_terminator(self, term)
  214.  
  215.     
  216.     def found_terminator(self):
  217.         
  218.         try:
  219.             if self.hdr is None:
  220.                 self._lock.__enter__()
  221.                 
  222.                 try:
  223.                     self.hdr = unpack_named('!BBHH', 'id', 'chan', 'seq', 'size', self.buf)
  224.                     self.buf = ''
  225.                     if self.hdr.size == 0:
  226.                         self.found_terminator()
  227.                     else:
  228.                         self.set_terminator(self.hdr.size)
  229.                 finally:
  230.                     pass
  231.  
  232.             else:
  233.                 
  234.                 try:
  235.                     getattr(self, 'channel_%d' % self.hdr.chan, self.unknown_channel)()
  236.                 except oscar.errors:
  237.                     self._lock
  238.                     e = self._lock
  239.                     hub.get_instance().on_error(e)
  240.                 except Exception:
  241.                     log.critical('Error handling FLAP 0x%x (DATA: %s) ' % (self.hdr.seq, repr(self.data)))
  242.                     raise 
  243.                 except:
  244.                     self._lock
  245.                 finally:
  246.                     self._lock.__enter__()
  247.                     
  248.                     try:
  249.                         (self.hdr, self.data) = (None, '')
  250.                         self.set_terminator(self.flap_hdr_size)
  251.                     finally:
  252.                         pass
  253.  
  254.  
  255.         except socket.error:
  256.             raise 
  257.         except Exception:
  258.             e = None
  259.             log.critical('%r had a non-socket error', self)
  260.             print_exc()
  261.         finally:
  262.             if self.terminator == 0:
  263.                 log.critical('terminator was 0, closing socket!')
  264.                 self.handle_close()
  265.             
  266.  
  267.  
  268.     
  269.     def close(self):
  270.         self._cleanup()
  271.         common.socket.close(self)
  272.  
  273.     
  274.     def _cleanup(self):
  275.         self.on_incoming = None
  276.         self.on_close = None
  277.         if self.snactivator:
  278.             self.snactivator.stop()
  279.             del self.snactivator
  280.             self.snactivator = None
  281.         
  282.  
  283.     
  284.     def close_when_done(self):
  285.         self._cleanup()
  286.         
  287.         try:
  288.             self.send_flap(4)
  289.         except socket.error:
  290.             (errno, desc) = None
  291.             if errno not in (9, 10054, 10057):
  292.                 raise 
  293.             errno not in (9, 10054, 10057)
  294.         finally:
  295.             common.socket.close_when_done(self)
  296.  
  297.  
  298.     
  299.     def send_flap(self, chan, data = ''):
  300.         log.debug_s('Sending FLAP on channel %d, data is < %r >', chan, data)
  301.         (None, None, netcall)((lambda : common.socket.push(self, pack('!BBHH', self.id, chan, self.seq.next(), len(data)) + data)))
  302.  
  303.     
  304.     def send_snac(self, fam, sub, data = '', priority = 5, req = False, cb = None, *args, **kwargs):
  305.         req_id = self.req.next()
  306.         if req:
  307.             remove_empty_lists(self.callbacks)
  308.             remove_empty_lists(self.error_callbacks)
  309.             if cb:
  310.                 self.callbacks[req_id].append((cb, args, kwargs))
  311.             
  312.             err_cb = kwargs.pop('err_cb', None)
  313.             if err_cb is not None:
  314.                 self.error_callbacks[req_id].append((err_cb, args, kwargs))
  315.             
  316.         
  317.         snac = (fam, sub, req_id, data)
  318.         if self.snactivator is None:
  319.             self._send_snac(snac, priority)
  320.         else:
  321.             self.snactivator.send_snac(snac, priority)
  322.  
  323.     send_snac_first = send_snac
  324.     
  325.     def _send_snac(self, .1, priority = None):
  326.         (fam, sub, req_id, data) = .1
  327.         server_version = getattr(self, 'server_snac_versions', { }).get(fam, None)
  328.         if server_version is None:
  329.             version = None
  330.         else:
  331.             my_version = getattr(getattr(oscar.snac, 'family_x%02x' % fam, None), 'version', None)
  332.             if my_version == server_version or my_version is None:
  333.                 version = None
  334.             else:
  335.                 version = my_version
  336.         flags = None if version is None else 32768
  337.         if version:
  338.             ver_tlv = oscar.util.tlv(1, 2, version)
  339.             ver_tlv = pack('!H', len(ver_tlv)) + ver_tlv
  340.         else:
  341.             ver_tlv = ''
  342.         log.debug('sending snac: fam=0x%02x, sub=0x%02x, req=0x%04x', fam, sub, req_id)
  343.         log.debug_s('\t\tdata=%r', data)
  344.         to_send = pack('!HHHI', fam, sub, flags, req_id) + ver_tlv + data
  345.         self.send_flap(2, to_send)
  346.         if (fam, sub) in self.rates:
  347.             rclass = self.snac_rate_class(fam, sub)
  348.             (rclass.current_level, rclass.last_time) = self.calc_rate_level(rclass)
  349.             clevel = rclass.current_level
  350.             i = sorted(list(self._get_rate_lvls(rclass)) + [
  351.                 clevel]).index(clevel)
  352.             
  353.             try:
  354.                 names = ('disconnect', 'limit', 'alert', 'clear', 'max')[i:i + 2]
  355.                 hi = names[0]
  356.                 lo = names[-1]
  357.                 if not hi == 'clear' and lo == 'max':
  358.                     log.debug('current rate level is: %s < %d < %s', hi, clevel, lo)
  359.             except Exception:
  360.                 import traceback
  361.                 traceback.print_exc()
  362.             except:
  363.                 None<EXCEPTION MATCH>Exception
  364.             
  365.  
  366.         None<EXCEPTION MATCH>Exception
  367.  
  368.     
  369.     def channel_1(self):
  370.         log.info('got channel 1 (new connection) flap')
  371.         to_send = pack('!I', 1)
  372.         self.send_flap(1, to_send)
  373.         
  374.         try:
  375.             if not self.on_connect:
  376.                 pass
  377.             default_cb(self)
  378.         except StopIteration:
  379.             None if self.cookie is not None else self._lock
  380.             None if self.cookie is not None else self._lock
  381.         except:
  382.             None if self.cookie is not None else self._lock
  383.  
  384.         del self.on_connect
  385.         self.on_connect = None
  386.  
  387.     
  388.     def channel_2(self):
  389.         hdr = unpack_named('!HHHI', 'fam', 'sub', 'flags', 'req', self.data[:self.snac_hdr_size])
  390.         data = self.data[self.snac_hdr_size:]
  391.         log.debug('got channel 2 (snac data) flap. fam=0x%02x, sub=0x%02x, req=0x%04x', hdr.fam, hdr.sub, hdr.req)
  392.         log.debug_s('\t\tdata=%r', data)
  393.         snac = Storage(hdr = hdr, data = data)
  394.         if snac.hdr.flags & 32768:
  395.             log.debug('got version data for snac, trimming')
  396.             snac_ver_fmt = (('tlvs_len', 'H'), ('tlvs', 'tlv_list_len', 'tlvs_len'))
  397.             (tlvs_len, ver, snac.data) = oscar.util.apply_format(snac_ver_fmt, snac.data)
  398.         
  399.         if self.is_ignored(snac):
  400.             log.debug('Ignored snac: %r', snac)
  401.             return None
  402.         cbs = self.callbacks
  403.         req_id = snac.hdr.req
  404.         
  405.         try:
  406.             if req_id in cbs:
  407.                 call_later = []
  408.                 
  409.                 try:
  410.                     for func, args, kwargs in cbs[req_id]:
  411.                         if snac.hdr.flags & 1:
  412.                             call_later.append((func, args, kwargs))
  413.                         
  414.                         if isgeneratormethod(func):
  415.                             
  416.                             try:
  417.                                 func((self, snac) + args)
  418.                             except StopIteration:
  419.                                 pass
  420.                             except:
  421.                                 None<EXCEPTION MATCH>StopIteration
  422.                             
  423.  
  424.                         None<EXCEPTION MATCH>StopIteration
  425.                         func(self, snac, *args, **kwargs)
  426.                 finally:
  427.                     self._lock.__enter__()
  428.                     
  429.                     try:
  430.                         if not call_later:
  431.                             cbs.pop(req_id)
  432.                         else:
  433.                             cbs[req_id] = call_later
  434.                     finally:
  435.                         pass
  436.  
  437.  
  438.             elif self.on_incoming is None:
  439.                 default_cb(self, snac)
  440.             elif isgeneratormethod(self.on_incoming):
  441.                 
  442.                 try:
  443.                     self.on_incoming((self, snac))
  444.                 except StopIteration:
  445.                     pass
  446.                 except Exception:
  447.                     print repr(snac)
  448.                     raise 
  449.                 except:
  450.                     None<EXCEPTION MATCH>StopIteration
  451.                 
  452.  
  453.             None<EXCEPTION MATCH>StopIteration
  454.             self.on_incoming(self, snac)
  455.         except oscar.snac.SnacError:
  456.             self.is_ignored(snac)
  457.             e = self.is_ignored(snac)
  458.             if self.handle_error_callbacks(snac, e):
  459.                 log.info('ignoring SnacError because it was handled by a callback')
  460.                 return None
  461.             (fam, _) = ()
  462.             (sub, _) = e.args[:2]
  463.             if (fam, sub) in self.ignored_errors:
  464.                 log.error('SNAC error occured and was ignored: %r', snac)
  465.             else:
  466.                 hub.get_instance().on_error(e)
  467.         except:
  468.             self.handle_error_callbacks(snac, e)
  469.  
  470.  
  471.     
  472.     def handle_error_callbacks(self, snac, exc):
  473.         handled = False
  474.         if snac.hdr.req in self.error_callbacks:
  475.             for func, args, kwargs in self.error_callbacks[snac.hdr.req]:
  476.                 if not handled:
  477.                     pass
  478.                 handled = func(snac, exc, *args, **kwargs)
  479.             
  480.         
  481.         return handled
  482.  
  483.     
  484.     def is_ignored(self, snac):
  485.         if (snac.hdr.fam, snac.hdr.sub) in self.ignored_snacs:
  486.             return True
  487.  
  488.     ignored_snacs = [
  489.         (1, 19)]
  490.     ignored_errors = [
  491.         (1, 13),
  492.         (21, 2),
  493.         (19, 1),
  494.         (21, 5),
  495.         (19, 5),
  496.         (7, 21)]
  497.     
  498.     def channel_4(self):
  499.         log.info('got channel 4 (close connection) flap')
  500.         fmt = (('tlvs', 'tlv_dict'),)
  501.         (tlvs, data) = oscar.unpack(fmt, self.data)
  502.         if (try_this,)((lambda : ord(tlvs[9][-1])), False):
  503.             if not self.on_close:
  504.                 pass
  505.             default_cb(self, oscar.protocol.Reasons.OTHER_USER)
  506.         elif not self.on_close:
  507.             pass
  508.         default_cb(self)
  509.         del self.on_close
  510.         self.on_close = None
  511.         self.close_when_done()
  512.  
  513.     
  514.     def unknown_channel(self):
  515.         log.warning('Unknown channel for data: %r', self.data)
  516.  
  517.  
  518.  
  519. def remove_empty_lists(mapping):
  520.     for k, v in list(mapping.iteritems()):
  521.         if not v:
  522.             mapping.pop(k)
  523.             continue
  524.     
  525.  
  526.