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

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.6)
  3.  
  4. from __future__ import with_statement
  5. from introspect import funcinfo
  6. from primitives.funcs import Delegate
  7. from functools import wraps
  8. from logging import getLogger
  9. from traceback import print_exc
  10. import sys
  11. import threading
  12. log = getLogger('callbacks')
  13. CALLBACKS = ('success', 'error', 'timeout')
  14. call_later_lock = threading.Lock()
  15. call_laters = dict()
  16.  
  17. def register_call_later(threadname, call_later):
  18.     call_later_lock.__enter__()
  19.     
  20.     try:
  21.         call_laters[threadname] = call_later
  22.     finally:
  23.         pass
  24.  
  25.  
  26.  
  27. def unregister_call_later(threadname):
  28.     call_later_lock.__enter__()
  29.     
  30.     try:
  31.         call_laters.pop(threadname)
  32.     finally:
  33.         pass
  34.  
  35.  
  36.  
  37. DO_NOTHING = lambda *a, **k: pass
  38.  
  39. class CallLater(object):
  40.     
  41.     def __init__(self, cb, threadname = None):
  42.         if not threadname:
  43.             pass
  44.         self.threadname = threading.currentThread().getName()
  45.         if self.threadname not in call_laters:
  46.             
  47.             try:
  48.                 cb_dbg_str = ', '.join((lambda .0: for s in .0:
  49. str(s))([
  50.                     funcinfo(cb),
  51.                     cb.func_code.co_filename,
  52.                     cb.func_code.co_firstlineno]))
  53.             except Exception:
  54.                 cb_dbg_str = 'Error making debug string. Repr is: {%s}' % funcinfo(cb)
  55.  
  56.             if cb is not DO_NOTHING:
  57.                 pass
  58.             
  59.         
  60.         self.cb = cb
  61.  
  62.     
  63.     def __repr__(self):
  64.         return '<%s %s>' % (type(self).__name__, funcinfo(self.cb))
  65.  
  66.     
  67.     def __call__(self, *a, **k):
  68.         if threading.currentThread().getName() != self.threadname and self.threadname in call_laters:
  69.             
  70.             try:
  71.                 return (None, None, call_laters[self.threadname])((lambda : self.cb(*a, **k)))
  72.             except Exception:
  73.                 print >>sys.stderr, 'callback is %s' % funcinfo(self.cb)
  74.                 raise 
  75.             except:
  76.                 None<EXCEPTION MATCH>Exception
  77.             
  78.  
  79.         None<EXCEPTION MATCH>Exception
  80.         
  81.         try:
  82.             return self.cb(*a, **k)
  83.         except Exception:
  84.             print >>sys.stderr, '%s in %s (%s). args/kwargs are: %r,%r' % (getattr(self.cb, '__name__', funcinfo(self.cb)), self.cb.__module__, funcinfo(self.cb), a, k)
  85.             raise 
  86.  
  87.  
  88.  
  89.  
  90. class CallLaterDelegate(Delegate):
  91.     
  92.     def __init__(self, *a):
  93.         Delegate.__init__(self, (lambda .0: for x in .0:
  94. CallLater(x))(a))
  95.  
  96.     
  97.     def __iadd__(self, f):
  98.         if isinstance(f, list):
  99.             for thing in f:
  100.                 self += thing
  101.             
  102.         else:
  103.             self.append(CallLater(f))
  104.         return self
  105.  
  106.  
  107.  
  108. class Callback(object):
  109.     _callback_names = CALLBACKS
  110.     
  111.     def __init__(self, _cbnames = None, **cbs):
  112.         if _cbnames is not None:
  113.             self._callback_names = _cbnames
  114.         
  115.         for name, callback in cbs.iteritems():
  116.             if not callable(callback):
  117.                 raise TypeError('keyword args to Callback must be callable: %s' % name)
  118.             callable(callback)
  119.             setattr(self, name, CallLaterDelegate(callback))
  120.             attr = getattr(self, name)
  121.         
  122.  
  123.     
  124.     def __getattr__(self, attr):
  125.         
  126.         try:
  127.             return object.__getattribute__(self, attr)
  128.         except AttributeError:
  129.             if attr in self._callback_names:
  130.                 return CallLaterDelegate()
  131.             raise 
  132.         except:
  133.             attr in self._callback_names
  134.  
  135.  
  136.     
  137.     def __setattr__(self, attr, val):
  138.         object.__setattr__(self, attr, val)
  139.  
  140.     
  141.     def __call__(self, *a, **k):
  142.         return self.success(*a, **k)
  143.  
  144.     
  145.     def __repr__(self):
  146.         return '<%s %s>' % (type(self).__name__, ' '.join((lambda .0: for item in .0:
  147. '%s=%s' % item)(self.__dict__.items())))
  148.  
  149.  
  150. EMPTY_CALLBACK = Callback()
  151. DefaultCallback = EMPTY_CALLBACK
  152. CALLBACK_ATTR = '_iscallback'
  153.  
  154. def callback_adapter(f, do_return = True):
  155.     
  156.     def wrapped(*a, **k):
  157.         cb = k.pop('callback')
  158.         
  159.         try:
  160.             retval = f(*a, **k)
  161.         except Exception:
  162.             e = None
  163.             cb.error(e)
  164.  
  165.         cb.success(retval)
  166.         if do_return:
  167.             return retval
  168.  
  169.     wrapped = (None, callsback)(wrapped)
  170.     return wrapped
  171.  
  172.  
  173. def callsback(func, callbacks_ = CALLBACKS):
  174.     
  175.     def wrapper(*secret_a, **secret_kws):
  176.         cb = None
  177.         if 'callback' in secret_kws:
  178.             if (any,)((lambda .0: for cbname in .0:
  179. cbname in secret_kws)(callbacks_)):
  180.                 raise AssertionError('use callback or individual callbacks')
  181.             (any,)((lambda .0: for cbname in .0:
  182. cbname in secret_kws)(callbacks_))
  183.             cb = secret_kws['callback']
  184.         else:
  185.             for cbname in callbacks_:
  186.                 if cbname in secret_kws:
  187.                     if cb is None:
  188.                         cb = Callback()
  189.                     
  190.                     if not callable(secret_kws[cbname]):
  191.                         raise TypeError('%s must be callable' % cbname)
  192.                     callable(secret_kws[cbname])
  193.                     mycb = CallLaterDelegate(secret_kws[cbname])
  194.                     setattr(cb, cbname, mycb)
  195.                     del secret_kws[cbname]
  196.                     continue
  197.             
  198.             secret_kws['callback'] = cb
  199.         if cb is None:
  200.             _cbnames = None if callbacks_ is CALLBACKS else callbacks_
  201.             secret_kws['callback'] = cb = Callback(_cbnames = _cbnames)
  202.         
  203.         
  204.         try:
  205.             val = func(*secret_a, **secret_kws)
  206.         except Exception:
  207.             e = None
  208.             print_exc()
  209.             callany = callany
  210.             import util
  211.             if not callany(cb.error, e):
  212.                 raise 
  213.             callany(cb.error, e)
  214.             val = None
  215.  
  216.         if val is True:
  217.             cb.success()
  218.         
  219.         return val
  220.  
  221.     wrapper = (None, wraps(func))(wrapper)
  222.     setattr(wrapper, CALLBACK_ATTR, True)
  223.     return wrapper
  224.  
  225.  
  226. def is_callsback(f):
  227.     return bool(getattr(f, CALLBACK_ATTR, False))
  228.  
  229.  
  230. def named_callbacks(names = ()):
  231.     
  232.     def wrapper(func):
  233.         return callsback(func, names)
  234.  
  235.     return wrapper
  236.  
  237.  
  238. def do_cb(seq, callback = None):
  239.     CallbackSequence(seq, callback = callback)()
  240.  
  241. do_cb = callsback(do_cb)
  242.  
  243. class CallbackSequence(object):
  244.     
  245.     def __init__(self, sequence, callback):
  246.         self.iter = iter(sequence)
  247.         self.callback = callback
  248.         self.n = 0
  249.  
  250.     
  251.     def __call__(self, *a):
  252.         self.n = self.n + 1
  253.         
  254.         try:
  255.             next = self.iter.next()
  256.         except StopIteration:
  257.             log.debug('stop iteration, calling success: %r', funcinfo(self.callback.success))
  258.             self.callback.success()
  259.  
  260.         log.debug('%s #%d: %r', funcinfo(self.callback), self.n, funcinfo(next))
  261.         next(*a, **dict(success = self, error = self.callback.error))
  262.  
  263.  
  264.  
  265. def do_cb_na(seq, callback = None):
  266.     CallbackSequenceNoArgs(seq, callback = callback)()
  267.  
  268. do_cb_na = callsback(do_cb_na)
  269.  
  270. class CallbackSequenceNoArgs(object):
  271.     
  272.     def __init__(self, sequence, callback):
  273.         self.iter = iter(sequence)
  274.         self.callback = callback
  275.         self.n = 0
  276.  
  277.     
  278.     def __call__(self, *a):
  279.         self.n = self.n + 1
  280.         
  281.         try:
  282.             next = self.iter.next()
  283.         except StopIteration:
  284.             log.debug('stop iteration, calling success: %r', funcinfo(self.callback.success))
  285.             self.callback.success()
  286.  
  287.         log.debug('%s #%d: %r', funcinfo(self.callback), self.n, funcinfo(next))
  288.         next(**dict(success = self, error = self.callback.error))
  289.  
  290.  
  291.  
  292. def wxcall(func):
  293.     
  294.     def wrapper(*a, **k):
  295.         CallLater(func, threadname = 'MainThread')(*a, **k)
  296.  
  297.     wrapper = (wraps(func),)(wrapper)
  298.     return wrapper
  299.  
  300.  
  301. class CallbackStream(object):
  302.     
  303.     class Cancel(Exception):
  304.         pass
  305.  
  306.     
  307.     def __init__(self, stream, progress, finished):
  308.         if not progress:
  309.             pass
  310.         self._progress = Null
  311.         if not finished:
  312.             pass
  313.         self._finished = Null
  314.         self.cancelled = False
  315.         self.stream = stream
  316.  
  317.     
  318.     def read(self, bytes = -1):
  319.         if self.cancelled:
  320.             raise CallbackStream.Cancel
  321.         self.cancelled
  322.         
  323.         try:
  324.             data = self.stream.read(bytes)
  325.             self.on_progress(self.stream.tell())
  326.         except ValueError:
  327.             data = ''
  328.  
  329.         if data == '':
  330.             self.stream.close()
  331.             if not self.cancelled:
  332.                 self.on_finished()
  333.             
  334.         
  335.         return data
  336.  
  337.     
  338.     def cancel(self):
  339.         self.stream.close()
  340.         self.cancelled = True
  341.  
  342.     
  343.     def tell(self):
  344.         return self.stream.tell()
  345.  
  346.     
  347.     def seek(self, *a, **k):
  348.         return self.stream.seek(*a, **k)
  349.  
  350.     
  351.     def on_progress(self, num_bytes):
  352.         self._progress(num_bytes)
  353.  
  354.     
  355.     def on_finished(self):
  356.         self._finished()
  357.         self._progress = self._finished = Null
  358.  
  359.     
  360.     def fileno(self):
  361.         return self.stream.fileno()
  362.  
  363.     
  364.     def name(self):
  365.         return self.stream.name
  366.  
  367.     name = property(name)
  368.  
  369. if __name__ == '__main__':
  370.     
  371.     class MyProtocol(object):
  372.         
  373.         def networkOperation(self, someArg, callback = None):
  374.             callback.success()
  375.  
  376.         networkOperation = callsback(networkOperation)
  377.  
  378.     
  379.     def good():
  380.         print 'success'
  381.  
  382.     
  383.     def bad():
  384.         print 'bad'
  385.  
  386.     c = Callback(success = good)
  387.     MyProtocol().networkOperation(5, callback = c)
  388.     MyProtocol().networkOperation(5, success = good)
  389.     MyProtocol().networkOperation(5)
  390.  
  391.