admintty 6.29 KB
Newer Older
nextime's avatar
nextime committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Topmenu and the submenus are based of the example found at this location http://blog.skeltonnetworks.com/2010/03/python-curses-custom-menu/
# The rest of the work was done by Matthew Bennett and he requests you keep these two mentions when you reuse the code :-)
# Basic code refactoring by Andrew Scheller
 
from time import sleep
import curses, os #curses is the interface for capturing key presses on the menu, os launches the files
screen = curses.initscr() #initializes a new window for capturing key presses
curses.noecho() # Disables automatic echoing of key presses (prevents program from input each key twice)
curses.cbreak() # Disables line buffering (runs each key as it is pressed rather than waiting for the return key to pressed)
curses.start_color() # Lets you use colors when highlighting selected menu option
screen.keypad(1) # Capture input from keypad
 
# Change this to use different colors when highlighting
curses.init_pair(1,curses.COLOR_BLACK, curses.COLOR_WHITE) # Sets up color pair #1, it does black text with white background
h = curses.color_pair(1) #h is the coloring for a highlighted menu option
n = curses.A_NORMAL #n is the coloring for a non highlighted menu option
 
MENU = "menu"
COMMAND = "command"
EXITMENU = "exitmenu"
 
menu_data = {
  'title': "Unixmedia Domotikad", 'type': MENU, 'subtitle': "Please select an option...",
  'options':[
    { 'title': "Restart Domotika Daemon", 'type': COMMAND, 'command': '/etc/init.d/domotikad stop && kill -9 `pgrep -f domotikad` && /etc/init.d/domotikad start' },
    { 'title': "Restart VPN", 'type': COMMAND, 'command': '/etc/init.d/openvpn restart' },
    { 'title': "Reboot", 'type': MENU, 'subtitle': "Select Yes to Reboot",
      'options': [
        {'title': "NO", 'type': EXITMENU, },
        {'title': "", 'type': COMMAND, 'command': '' },
        {'title': "", 'type': COMMAND, 'command': '' },
        {'title': "", 'type': COMMAND, 'command': '' },
        {'title': "YES", 'type': COMMAND, 'command': 'reboot' },
        {'title': "", 'type': COMMAND, 'command': '' },
        {'title': "", 'type': COMMAND, 'command': '' },
        {'title': "", 'type': COMMAND, 'command': '' },
      ]
    },
    { 'title': "Halt", 'type': MENU, 'subtitle': "Select Yes to Shutdown",
      'options': [
        {'title': "NO", 'type': EXITMENU, },
        {'title': "", 'type': COMMAND, 'command': '' },
        {'title': "", 'type': COMMAND, 'command': '' },
        {'title': "", 'type': COMMAND, 'command': '' },
        {'title': "YES", 'type': COMMAND, 'command': 'halt' },
        {'title': "", 'type': COMMAND, 'command': '' },
        {'title': "", 'type': COMMAND, 'command': '' },
        {'title': "", 'type': COMMAND, 'command': '' },
      ]
    },  

  ]
}
 
 
 
# This function displays the appropriate menu and returns the option selected
def runmenu(menu, parent):
 
  # work out what text to display as the last menu option
  if parent is None:
    lastoption = "Exit"
  else:
    lastoption = "Return to %s menu" % parent['title']
 
  optioncount = len(menu['options']) # how many options in this menu
 
  pos=0 #pos is the zero-based index of the hightlighted menu option. Every time runmenu is called, position returns to 0, when runmenu ends the position is returned and tells the program what opt$
  oldpos=None # used to prevent the screen being redrawn every time
  x = None #control for while loop, let's you scroll through options until return key is pressed then returns pos to program
 
  # Loop until return key is pressed
  while x !=ord('\n'):
    if pos != oldpos:
      oldpos = pos
      screen.border(0)
      screen.addstr(2,2, menu['title'], curses.A_STANDOUT) # Title for this menu
      screen.addstr(4,2, menu['subtitle'], curses.A_BOLD) #Subtitle for this menu
 
      # Display all the menu items, showing the 'pos' item highlighted
      for index in range(optioncount):
        textstyle = n
        if pos==index:
          textstyle = h
        screen.addstr(5+index,4, "%d - %s" % (index+1, menu['options'][index]['title']), textstyle)
      # Now display Exit/Return at bottom of menu
      textstyle = n
      if pos==optioncount:
        textstyle = h
      screen.addstr(5+optioncount,4, "%d - %s" % (optioncount+1, lastoption), textstyle)
      screen.refresh()
      # finished updating screen
 
    x = screen.getch() # Gets user input
 
    # What is user input?
    if x >= ord('1') and x <= ord(str(optioncount+1)):
      pos = x - ord('0') - 1 # convert keypress back to a number, then subtract 1 to get index
    elif x == 258: # down arrow
      if pos < optioncount:
        pos += 1
      else: pos = 0
    elif x == 259: # up arrow
      if pos > 0:
        pos += -1
      else: pos = optioncount
 
  # return index of the selected item
  return pos
 
# This function calls showmenu and then acts on the selected item
def processmenu(menu, parent=None):
  optioncount = len(menu['options'])
  exitmenu = False
  while not exitmenu: #Loop until the user exits the menu
    getin = runmenu(menu, parent)
    if getin == optioncount:
        exitmenu = True
    elif menu['options'][getin]['type'] == COMMAND:
      curses.def_prog_mode()    # save curent curses environment
      os.system('reset')
      if menu['options'][getin]['title'] == 'Pianobar':
        os.system('amixer cset numid=3 1') # Sets audio output on the pi to 3.5mm headphone jack
      screen.clear() #clears previous screen
      os.system(menu['options'][getin]['command']) # run the command
      screen.clear() #clears previous screen on key press and updates display based on pos
      curses.reset_prog_mode()   # reset to 'current' curses environment
      curses.curs_set(1)         # reset doesn't do this right
      curses.curs_set(0)
      os.system('amixer cset numid=3 2') # Sets audio output on the pi back to HDMI
    elif menu['options'][getin]['type'] == MENU:
          screen.clear() #clears previous screen on key press and updates display based on pos
          processmenu(menu['options'][getin], menu) # display the submenu
          screen.clear() #clears previous screen on key press and updates display based on pos
    elif menu['options'][getin]['type'] == EXITMENU:
          exitmenu = True
 
# Main program
processmenu(menu_data)
curses.endwin() #VITAL! This closes out the menu system and returns you to the bash prompt.
os.system('clear')