<s> from __future__ import print_function <EOL> import os <EOL> import sys <EOL> import logging <EOL> import pprint <EOL> import re <EOL> import signal <EOL> import time <EOL> import argparse <EOL> import traceback <EOL> import subprocess <EOL> from requests import ConnectionError <EOL> from blessed import Terminal <EOL> try : <EOL> import pygments <EOL> import pygments . lexers <EOL> import pygments . formatters <EOL> have_pygments = True <EOL> except : <EOL> have_pygments = False <EOL> try : <EOL> import cursor <EOL> except : <EOL> cursor = None <EOL> from collections import defaultdict <EOL> from scruffy import Config <EOL> from . core import * <EOL> from . colour import * <EOL> from . plugin import * <EOL> log = logging . getLogger ( "<STR_LIT>" ) <EOL> ADDR_FORMAT_128 = '<STR_LIT>' <EOL> ADDR_FORMAT_64 = '<STR_LIT>' <EOL> ADDR_FORMAT_32 = '<STR_LIT>' <EOL> ADDR_FORMAT_16 = '<STR_LIT>' <EOL> SHORT_ADDR_FORMAT_128 = '<STR_LIT>' <EOL> SHORT_ADDR_FORMAT_64 = '<STR_LIT>' <EOL> SHORT_ADDR_FORMAT_32 = '<STR_LIT>' <EOL> SHORT_ADDR_FORMAT_16 = '<STR_LIT>' <EOL> class AliasedSubParsersAction ( argparse . _SubParsersAction ) : <EOL> class _AliasedPseudoAction ( argparse . Action ) : <EOL> def __init__ ( self , name , aliases , help ) : <EOL> dest = name <EOL> if aliases : <EOL> dest += '<STR_LIT>' % '<STR_LIT:U+002C>' . join ( aliases ) <EOL> sup = super ( AliasedSubParsersAction . _AliasedPseudoAction , self ) <EOL> sup . __init__ ( option_strings = [ ] , dest = dest , help = help ) <EOL> def add_parser ( self , name , ** kwargs ) : <EOL> aliases = kwargs . pop ( '<STR_LIT>' , [ ] ) <EOL> parser = super ( AliasedSubParsersAction , self ) . add_parser ( name , ** kwargs ) <EOL> for alias in aliases : <EOL> self . _name_parser_map [ alias ] = parser <EOL> if '<STR_LIT>' in kwargs : <EOL> help = kwargs . pop ( '<STR_LIT>' ) <EOL> self . _choices_actions . pop ( ) <EOL> pseudo_action = self . _AliasedPseudoAction ( name , aliases , help ) <EOL> self . _choices_actions . append ( pseudo_action ) <EOL> return parser <EOL> class AnsiString ( object ) : <EOL> def __init__ ( self , string ) : <EOL> chunks = string . split ( '<STR_LIT>' ) <EOL> self . chars = [ ] <EOL> chars = list ( chunks [ <NUM_LIT:0> ] ) <EOL> if len ( chunks ) > <NUM_LIT:1> : <EOL> for chunk in chunks [ <NUM_LIT:1> : ] : <EOL> if chunk == '<STR_LIT>' : <EOL> chars . append ( '<STR_LIT>' + chunk ) <EOL> else : <EOL> p = chunk . find ( '<STR_LIT:m>' ) <EOL> if p > <NUM_LIT:0> : <EOL> chars . append ( '<STR_LIT>' + chunk [ : p + <NUM_LIT:1> ] ) <EOL> chars . extend ( list ( chunk [ p + <NUM_LIT:1> : ] ) ) <EOL> else : <EOL> chars . extend ( list ( chunk ) ) <EOL> ansi = [ ] <EOL> for char in chars : <EOL> if char [ <NUM_LIT:0> ] == '<STR_LIT>' : <EOL> ansi . append ( char ) <EOL> else : <EOL> self . chars . append ( '<STR_LIT>' . join ( ansi ) + char ) <EOL> ansi = [ ] <EOL> if len ( self . chars ) > <NUM_LIT:2> : <EOL> if self . chars [ - <NUM_LIT:1> ] [ <NUM_LIT:0> ] == '<STR_LIT>' : <EOL> self . chars [ - <NUM_LIT:2> ] = self . chars [ - <NUM_LIT:2> ] + self . chars [ - <NUM_LIT:1> ] <EOL> self . chars = self . chars [ : - <NUM_LIT:1> ] <EOL> def __getitem__ ( self , key ) : <EOL> if isinstance ( key , slice ) : <EOL> return '<STR_LIT>' . join ( self . chars [ key . start : key . stop ] ) + '<STR_LIT>' <EOL> else : <EOL> return self . chars [ key ] <EOL> def __str__ ( self ) : <EOL> return '<STR_LIT>' . join ( self . chars ) <EOL> def __len__ ( self ) : <EOL> return len ( self . chars ) <EOL> def clean ( self ) : <EOL> return re . sub ( '<STR_LIT>' , '<STR_LIT>' , str ( self ) ) <EOL> class VoltronView ( object ) : <EOL> """<STR_LIT>""" <EOL> view_type = None <EOL> block = False <EOL> supports_blocking = True <EOL> @ classmethod <EOL> def add_generic_arguments ( cls , sp ) : <EOL> sp . add_argument ( '<STR_LIT>' , '<STR_LIT>' , dest = "<STR_LIT>" , action = '<STR_LIT:store_true>' , help = '<STR_LIT>' , default = None ) <EOL> sp . add_argument ( '<STR_LIT>' , '<STR_LIT>' , dest = "<STR_LIT>" , action = '<STR_LIT>' , help = '<STR_LIT>' ) <EOL> sp . add_argument ( '<STR_LIT>' , '<STR_LIT>' , dest = "<STR_LIT>" , action = '<STR_LIT:store_true>' , help = '<STR_LIT>' , default = None ) <EOL> sp . add_argument ( '<STR_LIT>' , '<STR_LIT>' , dest = "<STR_LIT>" , action = '<STR_LIT>' , help = '<STR_LIT>' ) <EOL> sp . add_argument ( '<STR_LIT>' , '<STR_LIT>' , action = '<STR_LIT:store>' , help = '<STR_LIT>' , default = None ) <EOL> @ classmethod <EOL> def configure_subparser ( cls , subparsers ) : <EOL> if hasattr ( cls . _plugin , '<STR_LIT>' ) : <EOL> sp = subparsers . add_parser ( cls . view_type , aliases = cls . _plugin . aliases , help = '<STR_LIT>' . format ( cls . view_type ) ) <EOL> else : <EOL> sp = subparsers . add_parser ( cls . view_type , help = '<STR_LIT>' . format ( cls . view_type ) ) <EOL> VoltronView . add_generic_arguments ( sp ) <EOL> sp . set_defaults ( func = cls ) <EOL> def __init__ ( self , args = { } , loaded_config = { } ) : <EOL> log . debug ( '<STR_LIT>' + self . __class__ . __name__ ) <EOL> self . client = Client ( url = voltron . config . view . api_url ) <EOL> self . pm = None <EOL> self . args = args <EOL> self . loaded_config = loaded_config <EOL> self . server_version = None <EOL> self . title = '<STR_LIT>' <EOL> self . info = '<STR_LIT>' <EOL> self . body = '<STR_LIT>' <EOL> self . build_config ( ) <EOL> log . debug ( "<STR_LIT>" + pprint . pformat ( self . config ) ) <EOL> log . debug ( "<STR_LIT>" + str ( self . args ) ) <EOL> self . setup ( ) <EOL> if self . args . header != None : <EOL> self . config . header . show = self . args . header <EOL> if self . args . footer != None : <EOL> self . config . footer . show = self . args . footer <EOL> try : <EOL> signal . signal ( signal . SIGWINCH , self . sigwinch_handler ) <EOL> except : <EOL> pass <EOL> def build_config ( self ) : <EOL> self . config = self . loaded_config . view . all_views <EOL> self . config . type = self . view_type <EOL> name = self . view_type + '<STR_LIT>' <EOL> if '<STR_LIT>' in self . loaded_config and name in self . loaded_config . view : <EOL> self . config . update ( self . loaded_config . view [ name ] ) <EOL> if self . args . name != None : <EOL> self . config . update ( self . loaded_config [ self . args . name ] ) <EOL> self . apply_cli_config ( ) <EOL> def apply_cli_config ( self ) : <EOL> if self . args . header != None : <EOL> self . config . header . show = self . args . header <EOL> if self . args . footer != None : <EOL> self . config . footer . show = self . args . footer <EOL> def setup ( self ) : <EOL> log . debug ( '<STR_LIT>' ) <EOL> def cleanup ( self ) : <EOL> log . debug ( '<STR_LIT>' ) <EOL> def run ( self ) : <EOL> res = None <EOL> os . system ( '<STR_LIT>' ) <EOL> while True : <EOL> try : <EOL> if not self . server_version : <EOL> self . server_version = self . client . perform_request ( '<STR_LIT:version>' ) <EOL> if self . server_version . capabilities and '<STR_LIT>' in self . server_version . capabilities : <EOL> self . block = False <EOL> elif self . supports_blocking : <EOL> self . block = True <EOL> else : <EOL> raise BlockingNotSupportedError ( "<STR_LIT>" ) <EOL> self . render ( ) <EOL> if not self . block : <EOL> done = False <EOL> while not done : <EOL> res = self . client . perform_request ( '<STR_LIT:version>' , block = True ) <EOL> if res . is_success : <EOL> done = True <EOL> except ConnectionError as e : <EOL> try : <EOL> msg = e . message . args [ <NUM_LIT:1> ] . strerror <EOL> except : <EOL> try : <EOL> msg = e . message . args [ <NUM_LIT:0> ] <EOL> except : <EOL> msg = str ( e ) <EOL> traceback . print_exc ( ) <EOL> self . do_render ( error = '<STR_LIT>' . format ( msg ) ) <EOL> self . server_version = None <EOL> time . sleep ( <NUM_LIT:1> ) <EOL> def render ( self ) : <EOL> log . warning ( '<STR_LIT>' ) <EOL> def do_render ( error = None ) : <EOL> pass <EOL> def should_reconnect ( self ) : <EOL> try : <EOL> return self . loaded_config . view . reconnect <EOL> except : <EOL> return True <EOL> def sigwinch_handler ( self , sig , stack ) : <EOL> pass <EOL> class TerminalView ( VoltronView ) : <EOL> def __init__ ( self , * a , ** kw ) : <EOL> self . init_window ( ) <EOL> self . trunc_top = False <EOL> super ( TerminalView , self ) . __init__ ( * a , ** kw ) <EOL> def init_window ( self ) : <EOL> self . t = Terminal ( ) <EOL> print ( self . t . civis ) <EOL> if cursor : <EOL> cursor . hide ( ) <EOL> def cleanup ( self ) : <EOL> log . debug ( '<STR_LIT>' ) <EOL> print ( self . t . cnorm ) <EOL> if cursor : <EOL> cursor . show ( ) <EOL> def clear ( self ) : <EOL> os . system ( '<STR_LIT>' ) <EOL> def render ( self ) : <EOL> self . do_render ( ) <EOL> def do_render ( self , error = None ) : <EOL> self . clear ( ) <EOL> if error : <EOL> self . body = self . colour ( error , '<STR_LIT>' ) <EOL> self . fmt_body = self . body <EOL> self . pad_body ( ) <EOL> self . truncate_body ( ) <EOL> try : <EOL> if self . config . header . show : <EOL> print ( self . format_header_footer ( self . config . header ) ) <EOL> print ( self . fmt_body , end = '<STR_LIT>' ) <EOL> if self . config . footer . show : <EOL> print ( '<STR_LIT:\n>' + self . format_header_footer ( self . config . footer ) , end = '<STR_LIT>' ) <EOL> sys . stdout . flush ( ) <EOL> except IOError as e : <EOL> if e . errno == socket . EINTR : <EOL> self . do_render ( ) <EOL> def sigwinch_handler ( self , sig , stack ) : <EOL> self . do_render ( ) <EOL> def window_size ( self ) : <EOL> height , width = subprocess . check_output ( [ '<STR_LIT>' , '<STR_LIT:size>' ] ) . split ( ) <EOL> height = int ( height ) - int ( self . config . pad . pad_bottom ) <EOL> width = int ( width ) - int ( self . config . pad . pad_right ) <EOL> return ( height , width ) <EOL> def body_height ( self ) : <EOL> height , width = self . window_size ( ) <EOL> if self . config . header . show : <EOL> height -= <NUM_LIT:1> <EOL> if self . config . footer . show : <EOL> height -= <NUM_LIT:1> <EOL> return height <EOL> def colour ( self , text = '<STR_LIT>' , colour = None , background = None , attrs = [ ] ) : <EOL> s = '<STR_LIT>' <EOL> if colour != None : <EOL> s += fmt_esc ( colour ) <EOL> if background != None : <EOL> s += fmt_esc ( '<STR_LIT>' + background ) <EOL> if attrs != [ ] : <EOL> s += '<STR_LIT>' . join ( map ( lambda x : fmt_esc ( '<STR_LIT>' + x ) , attrs ) ) <EOL> s += text <EOL> s += fmt_esc ( '<STR_LIT>' ) <EOL> return s <EOL> def format_header_footer ( self , c ) : <EOL> height , width = self . window_size ( ) <EOL> l = getattr ( self , c . label_left . name ) if c . label_left . name != None else '<STR_LIT>' <EOL> r = getattr ( self , c . label_right . name ) if c . label_right . name != None else '<STR_LIT>' <EOL> p = c . pad <EOL> llen = len ( l ) <EOL> rlen = len ( r ) <EOL> l = self . colour ( l , c . label_left . colour , c . label_left . bg_colour , c . label_left . attrs ) <EOL> r = self . colour ( r , c . label_right . colour , c . label_right . bg_colour , c . label_right . attrs ) <EOL> p = self . colour ( p , c . colour , c . bg_colour , c . attrs ) <EOL> data = l + ( width - llen - rlen ) * p + r <EOL> return data <EOL> def pad_body ( self ) : <EOL> height , width = self . window_size ( ) <EOL> lines = self . fmt_body . split ( '<STR_LIT:\n>' ) <EOL> pad = self . body_height ( ) - len ( lines ) <EOL> if pad < <NUM_LIT:0> : <EOL> pad = <NUM_LIT:0> <EOL> self . fmt_body += int ( pad ) * '<STR_LIT:\n>' <EOL> def truncate_body ( self ) : <EOL> height , width = self . window_size ( ) <EOL> lines = [ ] <EOL> for line in self . fmt_body . split ( '<STR_LIT:\n>' ) : <EOL> s = AnsiString ( line ) <EOL> if len ( s ) > width : <EOL> line = s [ : width - <NUM_LIT:1> ] + self . colour ( '<STR_LIT:>>' , '<STR_LIT>' ) <EOL> lines . append ( line ) <EOL> if len ( lines ) > self . body_height ( ) : <EOL> if self . trunc_top : <EOL> lines = lines [ len ( lines ) - self . body_height ( ) : ] <EOL> else : <EOL> lines = lines [ : self . body_height ( ) ] <EOL> self . fmt_body = '<STR_LIT:\n>' . join ( lines ) <EOL> def merge ( d1 , d2 ) : <EOL> for k1 , v1 in d1 . items ( ) : <EOL> if isinstance ( v1 , dict ) and k1 in d2 . keys ( ) and isinstance ( d2 [ k1 ] , dict ) : <EOL> merge ( v1 , d2 [ k1 ] ) <EOL> else : <EOL> d2 [ k1 ] = v1 <EOL> return d2 </s>
