add exceptions and -f option
This commit is contained in:
parent
8c4cdf3707
commit
0e42810911
83
sshch.py
83
sshch.py
|
@ -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,14 +173,16 @@ 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:
|
||||||
|
if position == len(hidden_password) + 2:
|
||||||
sub_window.addstr(1, position - 1, " ",
|
sub_window.addstr(1, position - 1, " ",
|
||||||
text_colorpair)
|
text_colorpair)
|
||||||
sub_window.refresh()
|
sub_window.refresh()
|
||||||
position = position - 1
|
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)
|
||||||
|
if position < w - 4:
|
||||||
position += 1
|
position += 1
|
||||||
sub_window.refresh()
|
sub_window.refresh()
|
||||||
return hidden_password
|
return hidden_password
|
||||||
|
@ -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:
|
||||||
|
try:
|
||||||
CMDOptions()
|
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:
|
||||||
|
try:
|
||||||
CursesMain()
|
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")
|
||||||
|
|
Loading…
Reference in New Issue