#!/usr/bin/env python #coding=utf8 ''' CloudControl CLI Printer module ''' import sys import os import getpass import cccli from cccli.exception import * color = { # regular "red": "\001\033[0;31m\002", "green": "\001\033[0;32m\002", "yellow": "\001\033[0;33m\002", "blue": "\001\033[0;34m\002", "purple": "\001\033[0;35m\002", "cyan": "\001\033[0;36m\002", "white": "\001\033[0;37m\002", # lighted "lred": "\001\033[1;31m", "lgreen": "\001\033[1;32m\002", "lyellow": "\001\033[1;33m\002", "lblue": "\001\033[1;34m\002", "lpurple": "\001\033[1;35m\002", "lcyan": "\001\033[1;36m\002", "lwhite": "\001\033[1;37m\002", # underline "ured": "\001\033[4;31m\002", "ugreen": "\001\033[4;32m\002", "uyellow": "\001\033[4;33m\002", "ublue": "\001\033[4;34m\002", "upurple": "\001\033[4;35m\002", "ucyan": "\001\033[4;36m\002", # others "reset": "\001\033[m\002", } class Printer(object): '''Print relative class''' def __init__(self, interactive=False, forceyes=False, historyfile=None, historysize=None): self.readline = None self.history = History() self.historyfile = historyfile self.historysize = historysize self.forceyes = forceyes if interactive: self.setinteractive() def isinteractive(self): '''Return if printer is in interactive mode''' return self.readline is not None def setinteractive(self): if self.readline is not None: return import readline self.readline = readline if self.history is None: self.history = History(self.readline) else: self.history.readline = readline self.history.load(self.historyfile) self.history.maxsize(self.historysize) def out(self, message, fd=sys.stdout, nl=os.linesep, flush=True): '''Print a message in fd ended by nl''' fd.write("%s%s"%(message, nl)) if flush: fd.flush() def err(self, message, fd=sys.stderr, nl=os.linesep): self.out(message, fd, nl) def fatal(self, message, quit=True, fd=sys.stderr, nl=os.linesep): self.out("%sFatal%s: %s%s"%(color["lred"],color["red"],message, color["reset"]), fd, nl) if quit: os.kill(0, 15) def error(self, message, fd=sys.stderr, nl=os.linesep): self.out("%sError%s: %s%s"%(color["lred"],color["red"],message,color["reset"]), fd, nl) def warn(self, message, fd=sys.stderr, nl=os.linesep): self.out("%sWarning%s: %s%s"%(color["lyellow"],color["yellow"],message,color["reset"]), fd, nl) def debug(self, message, fd=sys.stderr, nl=os.linesep): if cccli.debug: self.out(message, fd, nl) def getline(self, prompt, history=True): try: s = raw_input(prompt) except EOFError: raise except KeyboardInterrupt: raise except: raise cliError if not history and s: self.history.removelast() return s def getpass(self, prompt): '''Ask for a password. No echo. Not in history''' if self.readline is None: raise cliError("Unable to ask a password in non-interactive mode") return getpass.getpass(prompt) def ask(self, prompt, goodans=None): '''Used to ask a question. Default answer not saved to history''' if self.forceyes and goodans is not None: return goodans if self.readline is None: raise cliError("Unable to ask question in non-interactive mode") return self.getline(prompt, history=False) class History(object): '''History class''' def __init__(self): self.readline = None def __nonzero__(self): return self.readline is not None def __getattribute__(self, name): r = object.__getattribute__(self, "readline") if name == "readline": return r if r is None: return lambda *a,**k: None return object.__getattribute__(self, name) def __iter__(self): for i in range(1, len(self)): yield self.readline.get_history_item(i) def __len__(self): if self.readline is None: return 0 return self.readline.get_current_history_length() def load(self, path): '''Load history from a file''' try: self.readline.read_history_file(path) except IOError: pass def save(self, path): '''Save history into path''' try: self.readline.write_history_file(path) except IOError: pass def maxsize(self, size=None): '''Set or return max history size''' if size is not None: self.readline.set_history_length(size) return self.readline.get_history_length() def removelast(self): '''Remove last history line''' self.readline.remove_history_item(self.readline.get_current_history_length() - 1) def clear(self): '''Clear history''' self.readline.clear_history()