<s> from collections import namedtuple <EOL> import json <EOL> import logging <EOL> import pprint <EOL> import re <EOL> import six <EOL> ( STATUS_OK , STATUS_ERROR ) = range ( <NUM_LIT:2> ) <EOL> CommandsResponse = namedtuple ( '<STR_LIT>' , [ '<STR_LIT:status>' , '<STR_LIT:value>' ] ) <EOL> LOG = logging . getLogger ( '<STR_LIT>' ) <EOL> def default_help_formatter ( quick_helps ) : <EOL> """<STR_LIT>""" <EOL> ret = '<STR_LIT>' <EOL> for line in quick_helps : <EOL> cmd_path , param_hlp , cmd_hlp = line <EOL> ret += '<STR_LIT:U+0020>' . join ( cmd_path ) + '<STR_LIT:U+0020>' <EOL> if param_hlp : <EOL> ret += param_hlp + '<STR_LIT:U+0020>' <EOL> ret += '<STR_LIT>' + cmd_hlp + '<STR_LIT:\n>' <EOL> return ret <EOL> class Command ( object ) : <EOL> """<STR_LIT>""" <EOL> help_msg = '<STR_LIT>' <EOL> param_help_msg = '<STR_LIT>' <EOL> command = '<STR_LIT>' <EOL> cli_resp_line_template = '<STR_LIT>' <EOL> def __init__ ( self , api = None , parent = None , <EOL> help_formatter = default_help_formatter , <EOL> resp_formatter_name = '<STR_LIT>' ) : <EOL> """<STR_LIT>""" <EOL> self . resp_formatter_name = resp_formatter_name <EOL> if hasattr ( self , resp_formatter_name + '<STR_LIT>' ) : <EOL> self . resp_formatter = getattr ( self , resp_formatter_name + '<STR_LIT>' ) <EOL> else : <EOL> self . resp_formatter = self . cli_resp_formatter <EOL> self . api = api <EOL> self . parent_cmd = parent <EOL> self . help_formatter = help_formatter <EOL> if not hasattr ( self , '<STR_LIT>' ) : <EOL> self . subcommands = { } <EOL> def __call__ ( self , params ) : <EOL> """<STR_LIT>""" <EOL> if len ( params ) == <NUM_LIT:0> : <EOL> return self . _action_wrapper ( [ ] ) <EOL> first_param = params [ <NUM_LIT:0> ] <EOL> if first_param == '<STR_LIT:?>' : <EOL> return self . question_mark ( ) <EOL> if first_param in self . subcommands : <EOL> return self . _instantiate_subcommand ( first_param ) ( params [ <NUM_LIT:1> : ] ) <EOL> return self . _action_wrapper ( params ) <EOL> @ classmethod <EOL> def cli_resp_formatter ( cls , resp ) : <EOL> """<STR_LIT>""" <EOL> if not resp . value : <EOL> return '<STR_LIT>' <EOL> if resp . status == STATUS_OK : <EOL> if type ( resp . value ) in ( str , bool , int , float , six . text_type ) : <EOL> return str ( resp . value ) <EOL> ret = '<STR_LIT>' <EOL> val = resp . value <EOL> if not isinstance ( val , list ) : <EOL> val = [ val ] <EOL> for line in val : <EOL> for k , v in line . items ( ) : <EOL> if isinstance ( v , dict ) : <EOL> ret += cls . cli_resp_line_template . format ( <EOL> k , '<STR_LIT:\n>' + pprint . pformat ( v ) <EOL> ) <EOL> else : <EOL> ret += cls . cli_resp_line_template . format ( k , v ) <EOL> return ret <EOL> else : <EOL> return "<STR_LIT>" . format ( resp . value ) <EOL> @ classmethod <EOL> def json_resp_formatter ( cls , resp ) : <EOL> """<STR_LIT>""" <EOL> return json . dumps ( resp . value ) <EOL> @ classmethod <EOL> def dict_resp_formatter ( cls , resp ) : <EOL> return resp . value <EOL> def _action_wrapper ( self , params ) : <EOL> filter_params = [ ] <EOL> if '<STR_LIT:|>' in params : <EOL> ind = params . index ( '<STR_LIT:|>' ) <EOL> new_params = params [ : ind ] <EOL> filter_params = params [ ind : ] <EOL> params = new_params <EOL> action_resp = self . action ( params ) <EOL> if len ( filter_params ) > <NUM_LIT:1> : <EOL> action_resp = self . filter_resp ( action_resp , filter_params [ <NUM_LIT:1> : ] ) <EOL> action_resp = CommandsResponse ( <EOL> action_resp . status , <EOL> self . resp_formatter ( action_resp ) <EOL> ) <EOL> return action_resp , self . __class__ <EOL> def action ( self , params ) : <EOL> """<STR_LIT>""" <EOL> return CommandsResponse ( STATUS_ERROR , '<STR_LIT>' ) <EOL> def filter_resp ( self , action_resp , filter_params ) : <EOL> """<STR_LIT>""" <EOL> if action_resp . status == STATUS_OK : <EOL> try : <EOL> return CommandsResponse ( <EOL> STATUS_OK , <EOL> TextFilter . filter ( action_resp . value , filter_params ) <EOL> ) <EOL> except FilterError as e : <EOL> return CommandsResponse ( STATUS_ERROR , str ( e ) ) <EOL> else : <EOL> return action_resp <EOL> def question_mark ( self ) : <EOL> """<STR_LIT>""" <EOL> ret = [ ] <EOL> if self . param_help_msg or len ( self . subcommands ) == <NUM_LIT:0> : <EOL> ret . append ( self . _quick_help ( ) ) <EOL> if len ( self . subcommands ) > <NUM_LIT:0> : <EOL> for k , _ in sorted ( self . subcommands . items ( ) ) : <EOL> command_path , param_help , cmd_help = self . _instantiate_subcommand ( k ) . _quick_help ( nested = True ) <EOL> if command_path or param_help or cmd_help : <EOL> ret . append ( ( command_path , param_help , cmd_help ) ) <EOL> return ( <EOL> CommandsResponse ( STATUS_OK , self . help_formatter ( ret ) ) , <EOL> self . __class__ <EOL> ) <EOL> def _quick_help ( self , nested = False ) : <EOL> """<STR_LIT>""" <EOL> if nested : <EOL> return self . command_path ( ) , None , self . help_msg <EOL> else : <EOL> return self . command_path ( ) , self . param_help_msg , self . help_msg <EOL> def command_path ( self ) : <EOL> if self . parent_cmd : <EOL> return self . parent_cmd . command_path ( ) + [ self . command ] <EOL> else : <EOL> return [ self . command ] <EOL> def _instantiate_subcommand ( self , key ) : <EOL> return self . subcommands [ key ] ( <EOL> api = self . api , <EOL> parent = self , <EOL> help_formatter = self . help_formatter , <EOL> resp_formatter_name = self . resp_formatter_name <EOL> ) <EOL> class TextFilter ( object ) : <EOL> @ classmethod <EOL> def filter ( cls , action_resp_value , filter_params ) : <EOL> try : <EOL> action , expected_value = filter_params <EOL> except ValueError : <EOL> raise FilterError ( '<STR_LIT>' ) <EOL> if action == '<STR_LIT>' : <EOL> if isinstance ( action_resp_value , list ) : <EOL> resp = list ( action_resp_value ) <EOL> iterator = enumerate ( action_resp_value ) <EOL> else : <EOL> resp = dict ( action_resp_value ) <EOL> iterator = iter ( action_resp_value . items ( ) ) <EOL> remove = [ ] <EOL> for key , value in iterator : <EOL> if not re . search ( expected_value , str ( value ) ) : <EOL> remove . append ( key ) <EOL> if isinstance ( resp , list ) : <EOL> resp = [ resp [ key ] for key , value in enumerate ( resp ) <EOL> if key not in remove ] <EOL> else : <EOL> resp = dict ( [ ( key , value ) <EOL> for key , value in resp . items ( ) <EOL> if key not in remove ] ) <EOL> return resp <EOL> else : <EOL> raise FilterError ( '<STR_LIT>' ) <EOL> class FilterError ( Exception ) : <EOL> pass </s>
