| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279 | #============================================================================# This file is part of Pwman3.## Pwman3 is free software; you can redistribute it and/or modify# it under the terms of the GNU General Public License, version 2# as published by the Free Software Foundation;## Pwman3 is distributed in the hope that it will be useful,# but WITHOUT ANY WARRANTY; without even the implied warranty of# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the# GNU General Public License for more details.## You should have received a copy of the GNU General Public License# along with Pwman3; if not, write to the Free Software# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA#============================================================================# Copyright (C) 2013 Oz Nahum <nahumoz@gmail.com>#============================================================================"""Define the CLI interface for pwman3 and the helper functions"""from pwman.util.callback import Callbackimport pwman.util.config as configimport subprocess as spimport getpassimport sysimport structimport osimport colorama# import tracebackif sys.platform != 'win32':    import termios    import fcntl    import tty    try:        import pyreadline as readline        _readline_available = True    except ImportError:        _readline_available = False       # raise ImportError("You need 'pyreadline' on Windows")else:    try:        import readline        _readline_available = True    except ImportError, e:        _readline_available = False_defaultwidth = 10class ANSI(object):    """    ANSI Colors    """    Reset = 0    Bold = 1    Underscore = 2    Black = 30    Red = 31    Green = 32    Yellow = 33    Blue = 34    Magenta = 35    Cyan = 36    White = 37def typeset(text, color, bold=False, underline=False):    """    print colored strings using colorama    """    if not config.get_value("Global", "colors") == 'yes':        return text    if bold:        text = colorama.Style.BRIGHT + text    if underline and not 'win32' in sys.platform:        text = ANSI.Underscore + text    return color+text+colorama.Style.RESET_ALLdef select(question, possible):    """    select input from user    """    for i in range(0, len(possible)):        print ("%d - %-"+str(_defaultwidth)+"s") % (i+1, possible[i])    while 1:        uinput = getonechar(question)        if uinput.isdigit() and int(uinput) in range(1, len(possible)+1):            return possible[int(uinput)-1]def text_to_clipboards(text):    """    copy text to clipboard    credit:    https://pythonadventures.wordpress.com/tag/xclip/    """    # "primary":    try:        xsel_proc = sp.Popen(['xsel', '-pi'], stdin=sp.PIPE)        xsel_proc.communicate(text)        # "clipboard":        xsel_proc = sp.Popen(['xsel', '-bi'], stdin=sp.PIPE)        xsel_proc.communicate(text)    except OSError, e:        print e, "\nExecuting xsel failed, is it installed ?\n \please check your configuration file ... "def text_to_mcclipboard(text):    """    copy text to mac os x clip board    credit:    https://pythonadventures.wordpress.com/tag/xclip/    """    # "primary":    try:        pbcopy_proc = sp.Popen(['pbcopy'], stdin=sp.PIPE)        pbcopy_proc.communicate(text)    except OSError, e:        print e, "\nExecuting pbcoy failed..."def open_url(link, macosx=False):    """    launch xdg-open or open in MacOSX with url    """    uopen = "xdg-open"    if macosx:        uopen = "open"    try:        sp.Popen([uopen, link], stdin=sp.PIPE)    except OSError, e:        print "Executing open_url failed with:\n", edef getpassword(question, width=_defaultwidth, echo=False):    if echo:        print question.ljust(width),        return sys.stdin.readline().rstrip()    else:        while 1:            a1 = getpass.getpass(question.ljust(width))            if len(a1) == 0:                return a1            a2 = getpass.getpass("[Repeat] %s" % (question.ljust(width)))            if a1 == a2:                return a1            else:                print "Passwords don't match. Try again."def gettermsize():    s = struct.pack("HHHH", 0, 0, 0, 0)    f = sys.stdout.fileno()    x = fcntl.ioctl(f, termios.TIOCGWINSZ, s)    rows, cols, width, height = struct.unpack("HHHH", x)    return rows, colsdef getinput(question, default="", completer=None, width=_defaultwidth):    if not _readline_available:        return raw_input(question.ljust(width))    else:        def defaulter():            """define default behavior startup"""            if _readline_available:                readline.insert_text(default)            readline.set_startup_hook(defaulter)            oldcompleter = readline.get_completer()            readline.set_completer(completer)        x = raw_input(question.ljust(width))        readline.set_completer(completer)        readline.set_startup_hook()        return xdef getyesno(question, defaultyes=False, width=_defaultwidth):    if (defaultyes):        default = "[Y/n]"    else:        default = "[y/N]"    ch = getonechar("%s %s" % (question, default), width)    if (ch == '\n'):        if (defaultyes):            return True        else:            return False    elif (ch == 'y' or ch == 'Y'):        return True    elif (ch == 'n' or ch == 'N'):        return False    else:        return getyesno(question, defaultyes, width)class CliMenu(object):    def __init__(self):        self.items = []    def add(self, item):        if (isinstance(item, CliMenuItem)):            self.items.append(item)        else:            print item.__class__    def run(self):        while True:            i = 0            for x in self.items:                i = i + 1                current = x.getter()                currentstr = ''                if type(current) == list:                    for c in current:                        currentstr += ("%s " % (c))                else:                    currentstr = current                print ("%d - %-"+str(_defaultwidth)                       + "s %s") % (i, x.name+":",                                    currentstr)            print "%c - Finish editing" % ('X')            option = getonechar("Enter your choice:")            try:                print "selection, ", option                # substract 1 because array subscripts start at 0                selection = int(option) - 1                # new value is created by calling the editor with the                # previous value as a parameter                # TODO: enable overriding password policy as if new node                # is created.                if selection == 1:  # for password                    value = self.items[selection].editor(0)                else:                    edit = self.items[selection].getter()                    value = self.items[selection].editor(edit)                self.items[selection].setter(value)            except (ValueError, IndexError):                if (option.upper() == 'X'):                    break                print "Invalid selection"def getonechar(question, width=_defaultwidth):    question = "%s " % (question)    print question.ljust(width),    sys.stdout.flush()    fd = sys.stdin.fileno()    tty_mode = tty.tcgetattr(fd)    tty.setcbreak(fd)    try:        ch = os.read(fd, 1)    finally:        tty.tcsetattr(fd, tty.TCSAFLUSH, tty_mode)    print ch    return chclass CliMenuItem(object):    def __init__(self, name, editor, getter, setter):        self.name = name        self.editor = editor        self.getter = getter        self.setter = setterclass CLICallback(Callback):    def getinput(self, question):        return raw_input(question)    def getsecret(self, question):        return getpass.getpass(question + ":")
 |