add exceptions and -f option

This commit is contained in:
ivan 2017-07-24 17:50:08 +03:00
parent 8c4cdf3707
commit 0e42810911
1 changed files with 68 additions and 29 deletions

View File

@ -14,7 +14,7 @@ import base64
import curses import curses
# https://github.com/zlaxy/sshch # https://github.com/zlaxy/sshch
version="0.4" version="0.5"
# path to conf file, default: ~/.config/sshch.conf # path to conf file, default: ~/.config/sshch.conf
conf_file = path.expanduser("~") + '/.config/sshch.conf' conf_file = path.expanduser("~") + '/.config/sshch.conf'
@ -109,6 +109,11 @@ def CMDConnect(aliases, command=False):
def CMDList(option, opt, value, parser): def CMDList(option, opt, value, parser):
print ', '.join(str(p) for p in conf.sections()) print ', '.join(str(p) for p in conf.sections())
def CMDFullList(option, opt, value, parser):
print '\n'.join((str(p) + " - " + conf.get(p, "exec_string") +
(" [password]" if conf.has_option(p, "password") else ""))
for p in conf.sections())
def CursesConnect(screen, aliases, command=False): def CursesConnect(screen, aliases, command=False):
curses.endwin() curses.endwin()
for alias in aliases: for alias in aliases:
@ -116,8 +121,9 @@ def CursesConnect(screen, aliases, command=False):
print "Press 'enter' to continue." print "Press 'enter' to continue."
screen.getch() screen.getch()
def CursesExit(): def CursesExit(error=False):
curses.endwin() curses.endwin()
if error: print error
exit() exit()
def CursesTextpadConfirm(value): def CursesTextpadConfirm(value):
@ -129,7 +135,7 @@ def CursesTextpad(screen, h, w, y, x, title="", value="",
text_colorpair=0, deco_colorpair=0): text_colorpair=0, deco_colorpair=0):
new_window = curses.newwin(h + 3, w + 2, y - 1, x - 1) new_window = curses.newwin(h + 3, w + 2, y - 1, x - 1)
title_window = new_window.subwin(1, w , y , x) title_window = new_window.subwin(1, w , y , x)
title_window.addstr(0, 0, title, text_colorpair) title_window.addnstr(0, 0, title, w , text_colorpair)
title_window.refresh() title_window.refresh()
sub_window = new_window.subwin(h, w, y + 1, x) sub_window = new_window.subwin(h, w, y + 1, x)
textbox_field = textpad.Textbox(sub_window, insert_mode=True) textbox_field = textpad.Textbox(sub_window, insert_mode=True)
@ -137,7 +143,7 @@ def CursesTextpad(screen, h, w, y, x, title="", value="",
new_window.box() new_window.box()
new_window.attroff(deco_colorpair) new_window.attroff(deco_colorpair)
new_window.refresh() new_window.refresh()
sub_window.addstr(0, 0 , value, text_colorpair) sub_window.addnstr(0, 0 , value, h * w, text_colorpair)
sub_window.attron(text_colorpair) sub_window.attron(text_colorpair)
return textbox_field return textbox_field
@ -148,8 +154,9 @@ def CursesPanel(screen, h, w, y, x, text,
new_window.attron(deco_colorpair) new_window.attron(deco_colorpair)
new_window.box() new_window.box()
new_window.attroff(deco_colorpair) new_window.attroff(deco_colorpair)
sub_window = new_window.subwin(h - 2, w - 2 , y + 1 , x + 1 ) sub_window = new_window.subwin(h - 2, w - 2 , y + 1 , x + 1)
sub_window.addstr(0, 0, text) sub_window.insstr(0, 0, text)
# sub_window.addnstr(0, 0, text, ((h - 2) * (w - 2) - 1))
panel = curses.panel.new_panel(new_window) panel = curses.panel.new_panel(new_window)
curses.panel.update_panels() curses.panel.update_panels()
screen.refresh() screen.refresh()
@ -166,15 +173,17 @@ def CursesPanel(screen, h, w, y, x, text,
break break
if keych == curses.KEY_BACKSPACE: if keych == curses.KEY_BACKSPACE:
if position > 2: if position > 2:
sub_window.addstr(1, position - 1, " ", if position == len(hidden_password) + 2:
text_colorpair) sub_window.addstr(1, position - 1, " ",
sub_window.refresh() text_colorpair)
position = position - 1 sub_window.refresh()
position = position - 1
hidden_password = hidden_password[0:-1] hidden_password = hidden_password[0:-1]
else: if keych > 31 and keych < 127:
hidden_password += curses.keyname(keych) hidden_password += curses.keyname(keych)
sub_window.addstr(1, position, "*", text_colorpair) sub_window.addstr(1, position, "*", text_colorpair)
position += 1 if position < w - 4:
position += 1
sub_window.refresh() sub_window.refresh()
return hidden_password return hidden_password
elif confirm == "remove": elif confirm == "remove":
@ -206,6 +215,9 @@ def CMDOptions():
epilog=epilog) epilog=epilog)
opts.add_option('-l', '--list', action = "callback", opts.add_option('-l', '--list', action = "callback",
callback=CMDList, help="show list of all existing aliases") callback=CMDList, help="show list of all existing aliases")
opts.add_option('-f', '--fulllist', action = "callback",
callback=CMDFullList, help=("show list of all existing " +
"aliases with connection strings"))
opts.add_option('-a', '--add', action="store", type="string", opts.add_option('-a', '--add', action="store", type="string",
dest="add", metavar="alias", default=False, dest="add", metavar="alias", default=False,
help="add new alias for connection string") help="add new alias for connection string")
@ -258,7 +270,8 @@ def CursesMain():
screen.border(0) screen.border(0)
curses.curs_set(0) curses.curs_set(0)
max_row = height - 5 max_row = height - 5
screen.addstr(1, 2, "sshch " + version + ", press 'h' for help") screen.addnstr(1, 2, "sshch " + version + ", press 'h' for help",
width - 4)
box = curses.newwin(max_row + 2, width - 2, 2, 1) box = curses.newwin(max_row + 2, width - 2, 2, 1)
box.box() box.box()
pages = int(ceil(row_num / max_row)) pages = int(ceil(row_num / max_row))
@ -266,19 +279,21 @@ def CursesMain():
page = 1 page = 1
for i in range(1, max_row + 1): for i in range(1, max_row + 1):
if row_num == 0: if row_num == 0:
box.addstr(1, 1, "There aren't any aliases yet. Press 'a'" + box.addnstr(1, 1, "There aren't any aliases yet. Press 'a'" +
" to add new one.", highlight_text) " to add new one.", width - 6, highlight_text)
else: else:
if (i == position): if (i == position):
box.addnstr(i, 2, "[" + selected_strings[i] + "] " + box.addnstr(i, 2, "[" + selected_strings[i] + "] " +
str(i) + " " + strings[i - 1] + " (" + str(i) + " " + strings[i - 1] + " (" +
conf.get(strings[i - 1], "exec_string") + ")", conf.get(strings[i - 1], "exec_string") + ")" +
width - 6, highlight_text) (" [password]" if conf.has_option(strings[i - 1],
"password") else ""), width - 6, highlight_text)
else: else:
box.addnstr(i, 2, "[" + selected_strings[i] + "] " + box.addnstr(i, 2, "[" + selected_strings[i] + "] " +
str(i) + " " + strings[i - 1] + " (" + str(i) + " " + strings[i - 1] + " (" +
conf.get(strings[i - 1], "exec_string") + ")", conf.get(strings[i - 1], "exec_string") + ")" +
width - 6, normal_text) (" [password]" if conf.has_option(strings[i - 1],
"password") else ""), width - 6, normal_text)
if i == row_num: if i == row_num:
break break
screen.refresh() screen.refresh()
@ -314,7 +329,7 @@ def CursesMain():
add_string = string_textpad.edit( add_string = string_textpad.edit(
CursesTextpadConfirm) CursesTextpadConfirm)
SetAliasString(add_alias.rstrip(), SetAliasString(add_alias.rstrip(),
add_string.rstrip()) add_string.replace("\n", "").rstrip())
strings = conf.sections() strings = conf.sections()
row_num = len(strings) row_num = len(strings)
selected_strings.append(" ") selected_strings.append(" ")
@ -329,7 +344,8 @@ def CursesMain():
conf.get(strings[position - 1], "exec_string"), conf.get(strings[position - 1], "exec_string"),
normal_text, highlight_text) normal_text, highlight_text)
edit_string = string_textpad.edit(CursesTextpadConfirm) edit_string = string_textpad.edit(CursesTextpadConfirm)
SetAliasString(strings[position - 1], edit_string.rstrip()) SetAliasString(strings[position - 1],
edit_string.replace("\n", "").rstrip())
strings = conf.sections() strings = conf.sections()
if (key_pressed == ord('p') or key_pressed == ord( if (key_pressed == ord('p') or key_pressed == ord(
'P') or key_pressed == curses.KEY_F6) and row_num != 0: 'P') or key_pressed == curses.KEY_F6) and row_num != 0:
@ -379,7 +395,8 @@ def CursesMain():
"Enter specific command to execute with selected " + "Enter specific command to execute with selected " +
"alias/aliases:", "", normal_text, highlight_text) "alias/aliases:", "", normal_text, highlight_text)
command_string = command_textpad.edit(CursesTextpadConfirm) command_string = command_textpad.edit(CursesTextpadConfirm)
CursesConnect(screen, selected, command_string.rstrip()) CursesConnect(screen, selected,
command_string.replace("\n", "").rstrip())
if (key_pressed == ord("\n") or key_pressed == ( if (key_pressed == ord("\n") or key_pressed == (
curses.KEY_F9)) and row_num != 0: curses.KEY_F9)) and row_num != 0:
selected = [] selected = []
@ -389,7 +406,8 @@ def CursesMain():
if not len(selected) > 0: if not len(selected) > 0:
selected.append(strings[position - 1]) selected.append(strings[position - 1])
CursesConnect(screen, selected) CursesConnect(screen, selected)
if key_pressed == 32 or key_pressed == curses.KEY_IC: if (key_pressed == 32 or key_pressed == (
curses.KEY_IC)) and row_num != 0:
if selected_strings[position] == ' ': if selected_strings[position] == ' ':
selected_strings[position] = '*' selected_strings[position] = '*'
else: selected_strings[position] = ' ' else: selected_strings[position] = ' '
@ -454,20 +472,25 @@ def CursesMain():
for i in range(1 + (max_row * (page - 1)), max_row + 1 + for i in range(1 + (max_row * (page - 1)), max_row + 1 +
(max_row * (page - 1))): (max_row * (page - 1))):
if row_num == 0: if row_num == 0:
box.addstr(1, 1, "There aren't any aliases yet. Press" + box.addnstr(1, 1, "There aren't any aliases yet. " +
" 'a' to add new one.", highlight_text) "Press 'a' to add new one.", width - 6,
highlight_text)
else: else:
if (i + (max_row * (page - 1)) == (position + if (i + (max_row * (page - 1)) == (position +
(max_row * (page - 1)))): (max_row * (page - 1)))):
box.addnstr(i - (max_row * (page - 1)), 2, "[" + box.addnstr(i - (max_row * (page - 1)), 2, "[" +
selected_strings[i] + "] " + str(i) + " " + selected_strings[i] + "] " + str(i) + " " +
strings[i - 1] + " (" + conf.get(strings[i - 1], strings[i - 1] + " (" + conf.get(strings[i - 1],
"exec_string") + ")", width - 6, highlight_text) "exec_string") + ")" + (" [password]" if
conf.has_option(strings[i - 1], "password") else
""), width - 6, highlight_text)
else: else:
box.addnstr(i - (max_row * (page - 1)), 2, "[" + box.addnstr(i - (max_row * (page - 1)), 2, "[" +
selected_strings[i] + "] " + str(i) + " " + selected_strings[i] + "] " + str(i) + " " +
strings[i - 1] + " (" + conf.get(strings[i - 1], strings[i - 1] + " (" + conf.get(strings[i - 1],
"exec_string") + ")", width - 6, normal_text) "exec_string") + ")" + (" [password]" if
conf.has_option(strings[i - 1], "password") else
""), width - 6, normal_text)
if i == row_num: if i == row_num:
break break
screen.refresh() screen.refresh()
@ -481,6 +504,22 @@ if __name__ == "__main__":
open(conf_file, 'w') open(conf_file, 'w')
conf.read(conf_file) conf.read(conf_file)
if len(argv) > 1: if len(argv) > 1:
CMDOptions() try:
CMDOptions()
except KeyboardInterrupt:
exit()
except ConfigParser.Error:
print ("Error: can't parse your config file, please check" +
" it manually or make new one")
exit()
else: else:
CursesMain() try:
CursesMain()
except KeyboardInterrupt:
CursesExit()
except ConfigParser.NoOptionError:
CursesExit("Error: can't parse your config file, please " +
"check it manually or make new one")
except curses.error:
CursesExit("Error: can't show some curses element, maybe " +
"your terminal is too small")