<s> import logging <EOL> import re <EOL> import string <EOL> import subprocess <EOL> import sys <EOL> import threading <EOL> import time <EOL> from . . import atexit <EOL> from . . import context <EOL> from . . import term <EOL> from . . log import getLogger <EOL> from . . log import getPerformanceLogger <EOL> from . . timeout import Timeout <EOL> from . . util import fiddling <EOL> from . . util import misc <EOL> from . . util import packing <EOL> from . buffer import Buffer <EOL> log = getLogger ( __name__ ) <EOL> dumplog = getPerformanceLogger ( __name__ + '<STR_LIT>' ) <EOL> class tube ( Timeout ) : <EOL> """<STR_LIT>""" <EOL> default = Timeout . default <EOL> forever = Timeout . forever <EOL> newline = '<STR_LIT:\n>' <EOL> def __init__ ( self , timeout = default ) : <EOL> super ( tube , self ) . __init__ ( timeout ) <EOL> self . buffer = Buffer ( ) <EOL> atexit . register ( self . close ) <EOL> def recv ( self , numb = <NUM_LIT> , timeout = default ) : <EOL> r"""<STR_LIT>""" <EOL> return self . _recv ( numb , timeout ) or '<STR_LIT>' <EOL> def unrecv ( self , data ) : <EOL> """<STR_LIT>""" <EOL> self . buffer . unget ( data ) <EOL> def _fillbuffer ( self , timeout = default ) : <EOL> """<STR_LIT>""" <EOL> data = '<STR_LIT>' <EOL> with self . local ( timeout ) : <EOL> data = self . recv_raw ( <NUM_LIT> ) <EOL> if data and dumplog . isEnabledFor ( logging . DEBUG ) : <EOL> dumplog . debug ( '<STR_LIT>' % len ( data ) ) <EOL> if len ( set ( data ) ) == <NUM_LIT:1> : <EOL> dumplog . indented ( '<STR_LIT>' % ( data [ <NUM_LIT:0> ] , len ( data ) ) , level = logging . DEBUG ) <EOL> elif all ( c in string . printable for c in data ) : <EOL> for line in data . splitlines ( True ) : <EOL> dumplog . indented ( repr ( line ) , level = logging . DEBUG ) <EOL> else : <EOL> dumplog . indented ( fiddling . hexdump ( data ) , level = logging . DEBUG ) <EOL> if data : <EOL> self . buffer . add ( data ) <EOL> return data <EOL> def _recv ( self , numb = <NUM_LIT> , timeout = default ) : <EOL> """<STR_LIT>""" <EOL> data = '<STR_LIT>' <EOL> if not self . buffer and not self . _fillbuffer ( timeout ) : <EOL> return '<STR_LIT>' <EOL> return self . buffer . get ( numb ) <EOL> def recvpred ( self , pred , timeout = default ) : <EOL> """<STR_LIT>""" <EOL> data = '<STR_LIT>' <EOL> with self . countdown ( timeout ) : <EOL> while not pred ( data ) : <EOL> try : <EOL> res = self . recv ( <NUM_LIT:1> ) <EOL> except : <EOL> self . unrecv ( data ) <EOL> return '<STR_LIT>' <EOL> if res : <EOL> data += res <EOL> else : <EOL> self . unrecv ( data ) <EOL> return '<STR_LIT>' <EOL> return data <EOL> def recvn ( self , numb , timeout = default ) : <EOL> """<STR_LIT>""" <EOL> with self . countdown ( timeout ) : <EOL> while self . countdown_active ( ) and len ( self . buffer ) < numb and self . _fillbuffer ( self . timeout ) : <EOL> pass <EOL> if len ( self . buffer ) < numb : <EOL> return '<STR_LIT>' <EOL> return self . buffer . get ( numb ) <EOL> def recvuntil ( self , delims , drop = False , timeout = default ) : <EOL> """<STR_LIT>""" <EOL> if isinstance ( delims , ( str , unicode ) ) : <EOL> delims = ( delims , ) <EOL> longest = max ( map ( len , delims ) ) <EOL> data = [ ] <EOL> top = '<STR_LIT>' <EOL> with self . countdown ( timeout ) : <EOL> while self . countdown_active ( ) : <EOL> try : <EOL> res = self . recv ( timeout = self . timeout ) <EOL> except : <EOL> self . unrecv ( '<STR_LIT>' . join ( data ) + top ) <EOL> raise <EOL> if not res : <EOL> self . unrecv ( '<STR_LIT>' . join ( data ) + top ) <EOL> return '<STR_LIT>' <EOL> top += res <EOL> start = len ( top ) <EOL> for d in delims : <EOL> j = top . find ( d ) <EOL> if start > j > - <NUM_LIT:1> : <EOL> start = j <EOL> end = j + len ( d ) <EOL> if start < len ( top ) : <EOL> self . unrecv ( top [ end : ] ) <EOL> if drop : <EOL> top = top [ : start ] <EOL> else : <EOL> top = top [ : end ] <EOL> return '<STR_LIT>' . join ( data ) + top <EOL> if len ( top ) > longest : <EOL> i = - longest - <NUM_LIT:1> <EOL> data . append ( top [ : i ] ) <EOL> top = top [ i : ] <EOL> return '<STR_LIT>' <EOL> def recvlines ( self , numlines , keepends = False , timeout = default ) : <EOL> r"""<STR_LIT>""" <EOL> lines = [ ] <EOL> with self . countdown ( timeout ) : <EOL> for _ in xrange ( numlines ) : <EOL> try : <EOL> res = self . recvline ( keepends = True , timeout = timeout ) <EOL> except : <EOL> self . unrecv ( '<STR_LIT>' . join ( lines ) ) <EOL> raise <EOL> if res : <EOL> lines . append ( res ) <EOL> else : <EOL> break <EOL> if not keepends : <EOL> lines = [ line . rstrip ( self . newline ) for line in lines ] <EOL> return lines <EOL> def recvline ( self , keepends = True , timeout = default ) : <EOL> r"""<STR_LIT>""" <EOL> return self . recvuntil ( self . newline , drop = not keepends , timeout = timeout ) <EOL> def recvline_pred ( self , pred , keepends = False , timeout = default ) : <EOL> r"""<STR_LIT>""" <EOL> tmpbuf = Buffer ( ) <EOL> line = '<STR_LIT>' <EOL> with self . countdown ( timeout ) : <EOL> while self . countdown_active ( ) : <EOL> try : <EOL> line = self . recvline ( keepends = True ) <EOL> except : <EOL> self . buffer . add ( tmpbuf ) <EOL> raise <EOL> if not line : <EOL> self . buffer . add ( tmpbuf ) <EOL> return '<STR_LIT>' <EOL> if pred ( line ) : <EOL> if not keepends : <EOL> line = line [ : - len ( self . newline ) ] <EOL> return line <EOL> else : <EOL> tmpbuf . add ( line ) <EOL> return '<STR_LIT>' <EOL> def recvline_contains ( self , items , keepends = False , timeout = default ) : <EOL> r"""<STR_LIT>""" <EOL> if isinstance ( items , ( str , unicode ) ) : <EOL> items = ( items , ) <EOL> def pred ( line ) : <EOL> return any ( d in line for d in items ) <EOL> return self . recvline_pred ( pred , keepends , timeout ) <EOL> def recvline_startswith ( self , delims , keepends = False , timeout = default ) : <EOL> r"""<STR_LIT>""" <EOL> if isinstance ( delims , ( str , unicode ) ) : <EOL> delims = ( delims , ) <EOL> return self . recvline_pred ( lambda line : any ( map ( line . startswith , delims ) ) , <EOL> keepends = keepends , <EOL> timeout = timeout ) <EOL> def recvline_endswith ( self , delims , keepends = False , timeout = default ) : <EOL> r"""<STR_LIT>""" <EOL> if isinstance ( delims , ( str , unicode ) ) : <EOL> delims = ( delims , ) <EOL> delims = tuple ( delim + self . newline for delim in delims ) <EOL> return self . recvline_pred ( lambda line : any ( map ( line . endswith , delims ) ) , <EOL> keepends = keepends , <EOL> timeout = timeout ) <EOL> def recvregex ( self , regex , exact = False , timeout = default ) : <EOL> """<STR_LIT>""" <EOL> if isinstance ( regex , ( str , unicode ) ) : <EOL> regex = re . compile ( regex ) <EOL> if exact : <EOL> pred = regex . match <EOL> else : <EOL> pred = regex . search <EOL> return self . recvpred ( pred , timeout = timeout ) <EOL> def recvline_regex ( self , regex , exact = False , keepends = False , timeout = default ) : <EOL> """<STR_LIT>""" <EOL> if isinstance ( regex , ( str , unicode ) ) : <EOL> regex = re . compile ( regex ) <EOL> if exact : <EOL> pred = regex . match <EOL> else : <EOL> pred = regex . search <EOL> return self . recvline_pred ( pred , keepends = keepends , timeout = timeout ) <EOL> def recvrepeat ( self , timeout = default ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> while self . _fillbuffer ( timeout = timeout ) : <EOL> pass <EOL> except EOFError : <EOL> pass <EOL> return self . buffer . get ( ) <EOL> def recvall ( self , timeout = Timeout . forever ) : <EOL> """<STR_LIT>""" <EOL> with log . waitfor ( '<STR_LIT>' ) as h : <EOL> l = len ( self . buffer ) <EOL> with self . local ( timeout ) : <EOL> try : <EOL> while True : <EOL> l = misc . size ( len ( self . buffer ) ) <EOL> h . status ( l ) <EOL> if not self . _fillbuffer ( ) : <EOL> break <EOL> except EOFError : <EOL> pass <EOL> h . success ( "<STR_LIT>" % l ) <EOL> self . close ( ) <EOL> return self . buffer . get ( ) <EOL> def send ( self , data ) : <EOL> """<STR_LIT>""" <EOL> if dumplog . isEnabledFor ( logging . DEBUG ) : <EOL> log . debug ( '<STR_LIT>' % len ( data ) ) <EOL> if len ( set ( data ) ) == <NUM_LIT:1> : <EOL> dumplog . indented ( '<STR_LIT>' % ( data [ <NUM_LIT:0> ] , len ( data ) ) ) <EOL> elif all ( c in string . printable for c in data ) : <EOL> for line in data . splitlines ( True ) : <EOL> log . indented ( repr ( line ) , level = logging . DEBUG ) <EOL> else : <EOL> log . indented ( fiddling . hexdump ( data ) , level = logging . DEBUG ) <EOL> self . send_raw ( data ) <EOL> def sendline ( self , line ) : <EOL> r"""<STR_LIT>""" <EOL> self . send ( line + self . newline ) <EOL> def sendafter ( self , delim , data , timeout = default ) : <EOL> """<STR_LIT>""" <EOL> res = self . recvuntil ( delim , timeout ) <EOL> self . send ( data ) <EOL> return res <EOL> def sendlineafter ( self , delim , data , timeout = default ) : <EOL> """<STR_LIT>""" <EOL> res = self . recvuntil ( delim , timeout ) <EOL> self . sendline ( data ) <EOL> return res <EOL> def sendthen ( self , delim , data , timeout = default ) : <EOL> """<STR_LIT>""" <EOL> self . send ( data ) <EOL> return self . recvuntil ( delim , timeout ) <EOL> def sendlinethen ( self , delim , data , timeout = default ) : <EOL> """<STR_LIT>""" <EOL> self . send ( data + self . newline ) <EOL> return self . recvuntil ( delim , timeout ) <EOL> def interactive ( self , prompt = term . text . bold_red ( '<STR_LIT:$>' ) + '<STR_LIT:U+0020>' ) : <EOL> """<STR_LIT>""" <EOL> log . info ( '<STR_LIT>' ) <EOL> go = threading . Event ( ) <EOL> def recv_thread ( ) : <EOL> while not go . isSet ( ) : <EOL> try : <EOL> cur = self . recv ( timeout = <NUM_LIT> ) <EOL> if cur : <EOL> sys . stderr . write ( cur ) <EOL> sys . stderr . flush ( ) <EOL> except EOFError : <EOL> log . info ( '<STR_LIT>' ) <EOL> break <EOL> t = context . Thread ( target = recv_thread ) <EOL> t . daemon = True <EOL> t . start ( ) <EOL> try : <EOL> while not go . isSet ( ) : <EOL> if term . term_mode : <EOL> data = term . readline . readline ( prompt = prompt , float = True ) <EOL> else : <EOL> data = sys . stdin . read ( <NUM_LIT:1> ) <EOL> if data : <EOL> try : <EOL> self . send ( data ) <EOL> except EOFError : <EOL> go . set ( ) <EOL> log . info ( '<STR_LIT>' ) <EOL> else : <EOL> go . set ( ) <EOL> except KeyboardInterrupt : <EOL> log . info ( '<STR_LIT>' ) <EOL> go . set ( ) <EOL> while t . is_alive ( ) : <EOL> t . join ( timeout = <NUM_LIT:0.1> ) <EOL> def clean ( self , timeout = <NUM_LIT> ) : <EOL> """<STR_LIT>""" <EOL> if timeout == <NUM_LIT:0> : <EOL> return self . buffer . get ( ) <EOL> return self . recvrepeat ( timeout ) <EOL> def clean_and_log ( self , timeout = <NUM_LIT> ) : <EOL> r"""<STR_LIT>""" <EOL> with context . context . local ( log_level = '<STR_LIT>' ) : <EOL> return self . clean ( timeout ) <EOL> def connect_input ( self , other ) : <EOL> """<STR_LIT>""" <EOL> def pump ( ) : <EOL> import sys as _sys <EOL> while self . countdown_active ( ) : <EOL> if not ( self . connected ( '<STR_LIT>' ) and other . connected ( '<STR_LIT>' ) ) : <EOL> break <EOL> try : <EOL> data = other . recv ( timeout = <NUM_LIT> ) <EOL> except EOFError : <EOL> break <EOL> if not _sys : <EOL> return <EOL> if not data : <EOL> continue <EOL> try : <EOL> self . send ( data ) <EOL> except EOFError : <EOL> break <EOL> if not _sys : <EOL> return <EOL> self . shutdown ( '<STR_LIT>' ) <EOL> other . shutdown ( '<STR_LIT>' ) <EOL> t = context . Thread ( target = pump ) <EOL> t . daemon = True <EOL> t . start ( ) <EOL> def connect_output ( self , other ) : <EOL> """<STR_LIT>""" <EOL> other . connect_input ( self ) <EOL> def connect_both ( self , other ) : <EOL> """<STR_LIT>""" <EOL> self . connect_input ( other ) <EOL> self . connect_output ( other ) <EOL> def spawn_process ( self , * args , ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> return subprocess . Popen ( <EOL> * args , <EOL> stdin = self . fileno ( ) , <EOL> stdout = self . fileno ( ) , <EOL> stderr = self . fileno ( ) , <EOL> ** kwargs <EOL> ) <EOL> def __lshift__ ( self , other ) : <EOL> """<STR_LIT>""" <EOL> self . connect_input ( other ) <EOL> return other <EOL> def __rshift__ ( self , other ) : <EOL> """<STR_LIT>""" <EOL> self . connect_output ( other ) <EOL> return other <EOL> def __ne__ ( self , other ) : <EOL> """<STR_LIT>""" <EOL> self << other << self <EOL> def wait_for_close ( self ) : <EOL> """<STR_LIT>""" <EOL> while self . connected ( ) : <EOL> time . sleep ( <NUM_LIT> ) <EOL> wait = wait_for_close <EOL> def can_recv ( self , timeout = <NUM_LIT:0> ) : <EOL> """<STR_LIT>""" <EOL> return bool ( self . buffer or self . can_recv_raw ( timeout ) ) <EOL> def settimeout ( self , timeout ) : <EOL> """<STR_LIT>""" <EOL> self . timeout = timeout <EOL> shutdown_directions = { <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> } <EOL> connected_directions = shutdown_directions . copy ( ) <EOL> connected_directions [ '<STR_LIT>' ] = '<STR_LIT>' <EOL> def shutdown ( self , direction = "<STR_LIT>" ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> direction = self . shutdown_directions [ direction ] <EOL> except KeyError : <EOL> raise KeyError ( '<STR_LIT>' % sorted ( self . shutdown_directions ) ) <EOL> else : <EOL> self . shutdown_raw ( self . shutdown_directions [ direction ] ) <EOL> def connected ( self , direction = '<STR_LIT>' ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> direction = self . connected_directions [ direction ] <EOL> except KeyError : <EOL> raise KeyError ( '<STR_LIT>' % sorted ( self . connected_directions ) ) <EOL> else : <EOL> return self . connected_raw ( direction ) <EOL> def __enter__ ( self ) : <EOL> """<STR_LIT>""" <EOL> return self <EOL> def __exit__ ( self , type , value , traceback ) : <EOL> """<STR_LIT>""" <EOL> self . close ( ) <EOL> def recv_raw ( self , numb ) : <EOL> """<STR_LIT>""" <EOL> raise EOFError ( '<STR_LIT>' ) <EOL> def send_raw ( self , data ) : <EOL> """<STR_LIT>""" <EOL> raise EOFError ( '<STR_LIT>' ) <EOL> def settimeout_raw ( self , timeout ) : <EOL> """<STR_LIT>""" <EOL> raise NotImplementedError ( ) <EOL> def timeout_change ( self ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> self . settimeout_raw ( self . timeout ) <EOL> except NotImplementedError : <EOL> pass <EOL> def can_recv_raw ( self , timeout ) : <EOL> """<STR_LIT>""" <EOL> raise NotImplementedError ( ) <EOL> def connected_raw ( self , direction ) : <EOL> """<STR_LIT>""" <EOL> raise NotImplementedError ( ) <EOL> def close ( self ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> def fileno ( self ) : <EOL> """<STR_LIT>""" <EOL> raise NotImplementedError ( ) <EOL> def shutdown_raw ( self , direction ) : <EOL> """<STR_LIT>""" <EOL> raise NotImplementedError ( ) <EOL> def read ( self , * a , ** kw ) : return self . recv ( * a , ** kw ) <EOL> def readpred ( self , * a , ** kw ) : return self . recvpred ( * a , ** kw ) <EOL> def readn ( self , * a , ** kw ) : return self . recvn ( * a , ** kw ) <EOL> def readuntil ( self , * a , ** kw ) : return self . recvuntil ( * a , ** kw ) <EOL> def readlines ( self , * a , ** kw ) : return self . recvlines ( * a , ** kw ) <EOL> def readline ( self , * a , ** kw ) : return self . recvline ( * a , ** kw ) <EOL> def readline_pred ( self , * a , ** kw ) : return self . recvline_pred ( * a , ** kw ) <EOL> def readline_contains ( self , * a , ** kw ) : return self . recvline_contains ( * a , ** kw ) <EOL> def readline_startswith ( self , * a , ** kw ) : return self . recvline_startswith ( * a , ** kw ) <EOL> def readline_endswith ( self , * a , ** kw ) : return self . recvline_endswith ( * a , ** kw ) <EOL> def readregex ( self , * a , ** kw ) : return self . recvregex ( * a , ** kw ) <EOL> def readline_regex ( self , * a , ** kw ) : return self . recvline_regex ( * a , ** kw ) <EOL> def readrepeat ( self , * a , ** kw ) : return self . recvrepeat ( * a , ** kw ) <EOL> def readall ( self , * a , ** kw ) : return self . recvall ( * a , ** kw ) <EOL> def write ( self , * a , ** kw ) : return self . send ( * a , ** kw ) <EOL> def writeline ( self , * a , ** kw ) : return self . sendline ( * a , ** kw ) <EOL> def writeafter ( self , * a , ** kw ) : return self . sendafter ( * a , ** kw ) <EOL> def writelineafter ( self , * a , ** kw ) : return self . sendlineafter ( * a , ** kw ) <EOL> def writethen ( self , * a , ** kw ) : return self . sendthen ( * a , ** kw ) <EOL> def writelinethen ( self , * a , ** kw ) : return self . sendlinethen ( * a , ** kw ) <EOL> def p64 ( self , * a , ** kwdata ) : return self . send ( packing . p64 ( * a , ** kw ) ) <EOL> def p32 ( self , * a , ** kw ) : return self . send ( packing . p32 ( * a , ** kw ) ) <EOL> def p16 ( self , * a , ** kw ) : return self . send ( packing . p16 ( * a , ** kw ) ) <EOL> def p8 ( self , * a , ** kw ) : return self . send ( packing . p8 ( * a , ** kw ) ) <EOL> def pack ( self , * a , ** kw ) : return self . send ( packing . pack ( * a , ** kw ) ) <EOL> def u64 ( self , * a , ** kw ) : return packing . u64 ( self . recvn ( <NUM_LIT:8> ) , * a , ** kw ) <EOL> def u32 ( self , * a , ** kw ) : return packing . u32 ( self . recvn ( <NUM_LIT:4> ) , * a , ** kw ) <EOL> def u16 ( self , * a , ** kw ) : return packing . u16 ( self . recvn ( <NUM_LIT:2> ) , * a , ** kw ) <EOL> def u8 ( self , * a , ** kw ) : return packing . u8 ( self . recvn ( <NUM_LIT:1> ) , * a , ** kw ) <EOL> def unpack ( self , * a , ** kw ) : return packing . unpack ( self . recvn ( context . bytes ) , * a , ** kw ) <EOL> def flat ( self , * a , ** kw ) : return self . send ( packing . flat ( * a , ** kw ) ) </s>
