This commit is contained in:
Denis Zheleztsov 2017-07-25 16:39:02 +03:00
parent 37b6f6d5e0
commit 99374da328
1 changed files with 174 additions and 144 deletions

View File

@ -4,20 +4,21 @@
from __future__ import division from __future__ import division
from os import path from os import path
from sys import argv from sys import argv
from math import * from math import ceil
from getpass import getpass from getpass import getpass
from optparse import OptionParser from optparse import OptionParser
from curses import textpad, panel from curses import textpad
import ConfigParser import ConfigParser
import subprocess import subprocess
import base64 import base64
import curses import curses
# https://github.com/zlaxy/sshch # https://github.com/zlaxy/sshch
version="0.55" version = "0.55"
# 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'
def AddNewAlias(alias): def AddNewAlias(alias):
if not conf.has_section(alias): if not conf.has_section(alias):
conf.add_section(alias) conf.add_section(alias)
@ -26,21 +27,25 @@ def AddNewAlias(alias):
else: else:
return "error: '" + alias + "' already exists" return "error: '" + alias + "' already exists"
def SetAliasString(alias, string): def SetAliasString(alias, string):
conf.set(alias, "exec_string", string) conf.set(alias, "exec_string", string)
conf.write(open(conf_file, "w")) conf.write(open(conf_file, "w"))
def SetPassword(alias, string): def SetPassword(alias, string):
string = base64.b64encode(base64.b16encode( string = base64.b64encode(base64.b16encode(
base64.b32encode(string))) base64.b32encode(string)))
conf.set(alias, "password", string) conf.set(alias, "password", string)
conf.write(open(conf_file, "w")) conf.write(open(conf_file, "w"))
def RemoveAliases(aliases): def RemoveAliases(aliases):
for alias in aliases: for alias in aliases:
conf.remove_section(alias) conf.remove_section(alias)
conf.write(open(conf_file, "w")) conf.write(open(conf_file, "w"))
def ConnectAlias(alias, command=False): def ConnectAlias(alias, command=False):
print "Connecting to " + alias + "..." print "Connecting to " + alias + "..."
exec_string = "" exec_string = ""
@ -51,47 +56,52 @@ def ConnectAlias(alias, command=False):
exec_string = exec_string + conf.get(alias, "exec_string") exec_string = exec_string + conf.get(alias, "exec_string")
if command: if command:
exec_string = exec_string + " " + command exec_string = exec_string + " " + command
p = subprocess.Popen(exec_string, shell=True) # Variables bellow is newer used
streamdata = p.communicate()[0] subprocess.Popen(exec_string, shell=True)
# p.communicate()[0]
print "... " + alias + " session finished." print "... " + alias + " session finished."
def CMDAdd(alias): def CMDAdd(alias):
result = AddNewAlias(alias) result = AddNewAlias(alias)
if result == True: if result:
prompt_add = ("Enter connection string for new alias " + prompt_add = ("".join(["Enter connection string for new alias ",
"(example: ssh user@somehost.com):\n") "(example: ssh user@somehost.com):\n"]))
string = "" string = ""
while string == "": while string == "":
string = raw_input (prompt_add) string = raw_input(prompt_add)
SetAliasString(alias, string) SetAliasString(alias, string)
else: else:
print result print result
def CMDEdit(alias): def CMDEdit(alias):
if conf.has_section(alias): if conf.has_section(alias):
prompt_edit = ("Enter connection string for existing alias " + prompt_edit = ("".join(["Enter connection string for existing alias ",
"(example: ssh user@somehost.com):\n") "(example: ssh user@somehost.com):\n"]))
string = "" string = ""
while string == "": while string == "":
string = raw_input (prompt_edit) string = raw_input(prompt_edit)
SetAliasString(alias, string) SetAliasString(alias, string)
else: else:
print "error: '" + alias + "' alias is not exists" print "error: '" + alias + "' alias is not exists"
def CMDPassword(alias): def CMDPassword(alias):
if conf.has_section(alias): if conf.has_section(alias):
prompt_pass = ("[UNSAFE] Enter password for sshpass: ") prompt_pass = ("[UNSAFE] Enter password for sshpass: ")
string = "" string = ""
string = getpass (prompt_pass) string = getpass(prompt_pass)
if not string == "": SetPassword(alias, string) if not string == "":
SetPassword(alias, string)
else: else:
print "error: '" + alias + "' alias is not exists" print "error: '" + alias + "' alias is not exists"
def CMDRemove(alias): def CMDRemove(alias):
if conf.has_section(alias): if conf.has_section(alias):
prompt_remove = ("Type 'yes' if you sure to remove '" + prompt_remove = ("Type 'yes' if you sure to remove '" + alias + "' alias: ")
alias + "' alias: ") string = raw_input(prompt_remove)
string = raw_input (prompt_remove)
if string == "yes": if string == "yes":
RemoveAliases([alias]) RemoveAliases([alias])
else: else:
@ -99,6 +109,7 @@ def CMDRemove(alias):
else: else:
print "error: '" + alias + "' alias is not exists." print "error: '" + alias + "' alias is not exists."
def CMDConnect(aliases, command=False): def CMDConnect(aliases, command=False):
for alias in aliases: for alias in aliases:
if conf.has_section(alias): if conf.has_section(alias):
@ -106,13 +117,17 @@ def CMDConnect(aliases, command=False):
else: else:
print "error: '" + alias + "' alias is not exists" print "error: '" + alias + "' alias is not exists"
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): def CMDFullList(option, opt, value, parser):
print '\n'.join((str(p) + " - " + conf.get(p, "exec_string") + for p in conf.sections():
(" [password]" if conf.has_option(p, "password") else "")) to_print = "".join([str(p), " - ", conf.get(p, "exec_string"),
for p in conf.sections()) (" [password]" if conf.has_option(p, "password") else ""), "\n"])
print(to_print)
def CursesConnect(screen, aliases, command=False): def CursesConnect(screen, aliases, command=False):
curses.endwin() curses.endwin()
@ -121,21 +136,25 @@ def CursesConnect(screen, aliases, command=False):
print "Press 'enter' to continue." print "Press 'enter' to continue."
screen.getch() screen.getch()
def CursesExit(error=False): def CursesExit(error=False):
curses.endwin() curses.endwin()
if error: print error if error:
print error
exit() exit()
def CursesTextpadConfirm(value): def CursesTextpadConfirm(value):
if value == 10: if value == 10:
value = 7 value = 7
return value return value
def CursesTextpad(screen, h, w, y, x, title="", value="", 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.addnstr(0, 0, title, w , 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)
@ -143,10 +162,11 @@ 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.addnstr(0, 0 , value, h * w, 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
def CursesPanel(screen, h, w, y, x, text, def CursesPanel(screen, h, w, y, x, text,
text_colorpair=0, deco_colorpair=0, confirm=0): text_colorpair=0, deco_colorpair=0, confirm=0):
new_window = curses.newwin(h, w, y, x) new_window = curses.newwin(h, w, y, x)
@ -154,9 +174,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.insstr(0, 0, text) sub_window.insstr(0, 0, text)
panel = curses.panel.new_panel(new_window) curses.panel.new_panel(new_window)
curses.panel.update_panels() curses.panel.update_panels()
screen.refresh() screen.refresh()
if confirm == "password": if confirm == "password":
@ -193,67 +213,76 @@ def CursesPanel(screen, h, w, y, x, text,
else: else:
screen.getch() screen.getch()
def CMDOptions(): def CMDOptions():
class FormatedParser(OptionParser): class FormatedParser(OptionParser):
def format_epilog(self, formatter): def format_epilog(self, formatter):
return self.epilog return self.epilog
usage = "usage: %prog [options] [aliases]" usage = "usage: %prog [options] [aliases]"
progname = path.basename(__file__) progname = path.basename(__file__)
epilog = ("Examples:\n " + epilog = ("".join(["Examples:\n ",
progname + " existingalias\n " + progname, " existingalias\n ",
progname + " -a newremoteserver\n " + progname, " -a newremoteserver\n ",
progname + " --edit=newremoteserver -p newremoteserver\n " + progname, " --edit=newremoteserver -p newremoteserver\n ",
progname + ' -c "ls -l" newremoteserver\n ' + progname, ' -c "ls -l" newremoteserver\n ',
progname + " -c reboot existingalias newremoteserver\n" progname, " -c reboot existingalias newremoteserver\n",
"Examples of connection string:\n " + "Examples of connection string:\n ",
"ssh user@somehost.com\n " + "ssh user@somehost.com\n ",
"ssh gates@8.8.8.8 -p 667\n " + "ssh gates@8.8.8.8 -p 667\n ",
"ssh root@somehost.com -t tmux a\n" + "ssh root@somehost.com -t tmux a\n",
"Also, you can edit config file manually: " + conf_file + "\n") "Also, you can edit config file manually: ", conf_file, "\n"]))
opts = FormatedParser(usage=usage, version="%prog " + version, opts = FormatedParser(usage=usage, version="%prog " + version,
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", opts.add_option('-f', '--fulllist', action="callback",
callback=CMDFullList, help=("show list of all existing " + callback=CMDFullList, help=("show list of all existing " +
"aliases with connection strings")) "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")
opts.add_option('-c', '--command', action="store", type="string", opts.add_option('-c', '--command', action="store", type="string",
dest="command", metavar="command", default=False, dest="command", metavar="command", default=False,
help="add command for executing alias") help="add command for executing alias")
opts.add_option('-e', '--edit', action="store", type="string", opts.add_option('-e', '--edit', action="store", type="string",
dest='edit', metavar="alias", default=False, dest='edit', metavar="alias", default=False,
help="edit existing connection string") help="edit existing connection string")
opts.add_option('-p', '--password', action="store", type="string", opts.add_option('-p', '--password', action="store", type="string",
dest='password', metavar="alias", default=False, dest='password', metavar="alias", default=False,
help="set and store password for sshpass [UNSAFE]") help="set and store password for sshpass [UNSAFE]")
opts.add_option('-r', '--remove', action="store", type="string", opts.add_option('-r', '--remove', action="store", type="string",
dest='remove', metavar="alias", default=False, dest='remove', metavar="alias", default=False,
help="remove existing alias of connection string") help="remove existing alias of connection string")
options, alias = opts.parse_args() options, alias = opts.parse_args()
if options.add: CMDAdd(options.add) if options.add:
if options.edit: CMDEdit(options.edit) CMDAdd(options.add)
if options.password: CMDPassword(options.password) if options.edit:
if options.remove: CMDRemove(options.remove) CMDEdit(options.edit)
if alias: CMDConnect(alias, options.command) if options.password:
CMDPassword(options.password)
if options.remove:
CMDRemove(options.remove)
if alias:
CMDConnect(alias, options.command)
# curses template from: https://stackoverflow.com/a/30828805/6224462 # curses template from: https://stackoverflow.com/a/30828805/6224462
def CursesMain(): def CursesMain():
help_screen = (" Press:\n" + help_screen = ("".join([" Press:\n",
" 'z'/'x' or arrows - navigation\n" + " 'z'/'x' or arrows - navigation\n",
" 'a'/'F2' - add new alias\n" + " 'a'/'F2' - add new alias\n",
" 'e'/'F4' - edit existing alias\n" + " 'e'/'F4' - edit existing alias\n",
" 'p'/'F6' - set alias's password for sshpass [UNSAFE]\n" + " 'p'/'F6' - set alias's password for sshpass [UNSAFE]\n",
" 'space'/'insert' - select\n" + " 'space'/'insert' - select\n",
" 'r'/'F8' - remove selected alias/aliases\n" + " 'r'/'F8' - remove selected alias/aliases\n",
" 'c'/'F3' - execute specific command with selected alias/aliases\n" + " 'c'/'F3' - execute specific command with selected alias/aliases\n",
" 'enter'/'F9' - connect to selected alias/aliases\n" + " 'enter'/'F9' - connect to selected alias/aliases\n",
" 'q'/'F10' - quit\n" + " 'q'/'F10' - quit\n",
" Run program with '--help' option to view command line help.\n" + " Run program with '--help' option to view command line help.\n",
" Also, you can edit config file manually:\n" + " Also, you can edit config file manually:\n",
" " + conf_file) " ", conf_file]))
strings = conf.sections() strings = conf.sections()
row_num = len(strings) row_num = len(strings)
selected_strings = [" " for i in range(0, row_num + 1)] selected_strings = [" " for i in range(0, row_num + 1)]
@ -278,21 +307,20 @@ 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.addnstr(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.",
" to add new one.", width - 6, highlight_text) width - 6, highlight_text)
else: else:
if (i == position): if conf.has_option(strings[i - 1], "password"):
box.addnstr(i, 2, "[" + selected_strings[i] + "] " + password = " [password]"
str(i) + " " + strings[i - 1] + " (" +
conf.get(strings[i - 1], "exec_string") + ")" +
(" [password]" if conf.has_option(strings[i - 1],
"password") else ""), width - 6, highlight_text)
else: else:
box.addnstr(i, 2, "[" + selected_strings[i] + "] " + password = ""
str(i) + " " + strings[i - 1] + " (" + exec_string = ["[", selected_strings[i], "] ", str(i), " ",
conf.get(strings[i - 1], "exec_string") + ")" + strings[i - 1], " (", conf.get(strings[i - 1], "exec_string"),
(" [password]" if conf.has_option(strings[i - 1], ")", password]
"password") else ""), width - 6, normal_text) if (i == position):
box.addnstr(i, 2, "".join(exec_string), width - 6, highlight_text)
else:
box.addnstr(i, 2, "".join(exec_string), width - 6, normal_text)
if i == row_num: if i == row_num:
break break
screen.refresh() screen.refresh()
@ -300,35 +328,36 @@ def CursesMain():
key_pressed = screen.getch() key_pressed = screen.getch()
while True: while True:
if key_pressed == ord('q') or key_pressed == ord( if key_pressed == ord('q') or key_pressed == ord(
'Q') or key_pressed == ( 'Q') or key_pressed == (
27) or key_pressed == curses.KEY_F10: 27) or key_pressed == curses.KEY_F10:
CursesExit() CursesExit()
if key_pressed == ord('h') or key_pressed == ord( if key_pressed == ord('h') or key_pressed == ord(
'H') or key_pressed == curses.KEY_F1: 'H') or key_pressed == curses.KEY_F1:
CursesPanel(screen, height - 4, width - 6, 2, 3, CursesPanel(screen, height - 4, width - 6, 2, 3,
help_screen, normal_text, highlight_text) help_screen, normal_text, highlight_text)
if key_pressed == ord('a') or key_pressed == ord( if key_pressed == ord('a') or key_pressed == ord(
'A') or key_pressed == curses.KEY_F2: 'A') or key_pressed == curses.KEY_F2:
new_alias_textpad = CursesTextpad(screen, 1, width - 8, new_alias_textpad = CursesTextpad(screen, 1, width - 8,
(height // 2) - 1, 4, "Enter new alias:", "", (height // 2) - 1, 4, "Enter new alias:", "",
normal_text, highlight_text) normal_text, highlight_text)
add_alias = new_alias_textpad.edit(CursesTextpadConfirm) add_alias = new_alias_textpad.edit(CursesTextpadConfirm)
if not add_alias.rstrip() == "": if not add_alias.rstrip() == "":
add_result = AddNewAlias(add_alias.rstrip()) add_result = AddNewAlias(add_alias.rstrip())
if not add_result == True: CursesPanel(screen, 3, if not add_result:
width - 6, (height // 2) - 1, 3, add_result, CursesPanel(screen, 3,
normal_text, highlight_text) width - 6, (height // 2) - 1, 3, add_result,
normal_text, highlight_text)
else: else:
add_string = "" add_string = ""
while add_string.rstrip() == "": while add_string.rstrip() == "":
string_textpad = CursesTextpad(screen, 3, string_textpad = CursesTextpad(screen, 3,
width - 8, (height // 2) - 1, 4, width - 8, (height // 2) - 1, 4,
"Enter full execution string:", "Enter full execution string:",
"ssh ", normal_text, highlight_text) "ssh ", normal_text, highlight_text)
add_string = string_textpad.edit( add_string = string_textpad.edit(
CursesTextpadConfirm) CursesTextpadConfirm)
SetAliasString(add_alias.rstrip(), SetAliasString(add_alias.rstrip(),
add_string.replace("\n", "").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(" ")
@ -339,20 +368,20 @@ def CursesMain():
edit_string = "" edit_string = ""
while edit_string.rstrip() == "": while edit_string.rstrip() == "":
string_textpad = CursesTextpad(screen, 3, width - 8, string_textpad = CursesTextpad(screen, 3, width - 8,
(height // 2) - 1, 4, "Enter new execution string:", (height // 2) - 1, 4, "Enter new execution string:",
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], SetAliasString(strings[position - 1],
edit_string.replace("\n", "").rstrip()) 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:
set_password = "" set_password = ""
set_password = CursesPanel(screen, 4, width - 6, set_password = CursesPanel(screen, 4, width - 6,
(height // 2) - 1, 3, (height // 2) - 1, 3,
" Enter user password for sshpass and press 'enter':" + " Enter user password for sshpass and press 'enter':\n>",
"\n>", normal_text, highlight_text, "password") normal_text, highlight_text, "password")
if not set_password == "": if not set_password == "":
SetPassword(strings[position - 1], set_password) SetPassword(strings[position - 1], set_password)
if (key_pressed == ord('r') or key_pressed == ord( if (key_pressed == ord('r') or key_pressed == ord(
@ -363,17 +392,18 @@ def CursesMain():
if selected_strings[i] == "*": if selected_strings[i] == "*":
selected.append(strings[i - 1]) selected.append(strings[i - 1])
if len(selected) > 0: if len(selected) > 0:
remove_confirm = ("Are you sure to remove " + remove_confirm = (
str(len(selected)) + " selected aliases? (y/N)") "".join(["Are you sure to remove ",
str(len(selected)), " selected aliases? (y/N)"]))
else: else:
remove_confirm = ("Are you sure to remove '" + remove_confirm = ("".join(["Are you sure to remove '",
strings[position - 1] + "' alias? (y/N)") strings[position - 1], "' alias? (y/N)"]))
selected.append(strings[position - 1]) selected.append(strings[position - 1])
remove_result = CursesPanel(screen, 4, width - 6, remove_result = CursesPanel(screen, 4, width - 6,
(height // 2) - 1, 3, remove_confirm, normal_text, (height // 2) - 1, 3, remove_confirm, normal_text,
highlight_text, "remove") highlight_text, "remove")
if remove_result == "confirm": if remove_result == "confirm":
RemoveAliases(selected) RemoveAliases(selected)
strings = conf.sections() strings = conf.sections()
row_num = len(strings) row_num = len(strings)
selected_strings = [" " for i in range(0, row_num + 1)] selected_strings = [" " for i in range(0, row_num + 1)]
@ -390,12 +420,14 @@ def CursesMain():
if not len(selected) > 0: if not len(selected) > 0:
selected.append(strings[position - 1]) selected.append(strings[position - 1])
command_textpad = CursesTextpad(screen, 3, width - 8, command_textpad = CursesTextpad(screen, 3, width - 8,
(height // 2) - 1, 4, (height // 2) - 1, 4,
"Enter specific command to execute with selected " + "".join([
"alias/aliases:", "", normal_text, highlight_text) "Enter specific command to execute with selected ",
"alias/aliases:"]
), "", normal_text, highlight_text)
command_string = command_textpad.edit(CursesTextpadConfirm) command_string = command_textpad.edit(CursesTextpadConfirm)
CursesConnect(screen, selected, CursesConnect(screen, selected,
command_string.replace("\n", "").rstrip()) 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 = []
@ -409,7 +441,8 @@ def CursesMain():
curses.KEY_IC)) and row_num != 0: 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] = ' '
if page == 1: if page == 1:
if position < i: if position < i:
position = position + 1 position = position + 1
@ -427,7 +460,7 @@ def CursesMain():
page = page + 1 page = page + 1
position = 1 + (max_row * (page - 1)) position = 1 + (max_row * (page - 1))
if key_pressed == curses.KEY_DOWN or key_pressed == ord( if key_pressed == curses.KEY_DOWN or key_pressed == ord(
'x') or key_pressed == ord('X'): 'x') or key_pressed == ord('X'):
if page == 1: if page == 1:
if position < i: if position < i:
position = position + 1 position = position + 1
@ -445,7 +478,7 @@ def CursesMain():
page = page + 1 page = page + 1
position = 1 + (max_row * (page - 1)) position = 1 + (max_row * (page - 1))
if key_pressed == curses.KEY_UP or key_pressed == ord( if key_pressed == curses.KEY_UP or key_pressed == ord(
'z') or key_pressed == ord('Z'): 'z') or key_pressed == ord('Z'):
if page == 1: if page == 1:
if position > 1: if position > 1:
position = position - 1 position = position - 1
@ -455,13 +488,13 @@ def CursesMain():
else: else:
page = page - 1 page = page - 1
position = max_row + (max_row * (page - 1)) position = max_row + (max_row * (page - 1))
if key_pressed == curses.KEY_LEFT or (key_pressed == if key_pressed == curses.KEY_LEFT or (key_pressed ==
curses.KEY_PPAGE): curses.KEY_PPAGE):
if page > 1: if page > 1:
page = page - 1 page = page - 1
position = 1 + (max_row * (page - 1)) position = 1 + (max_row * (page - 1))
if key_pressed == curses.KEY_RIGHT or (key_pressed == if key_pressed == curses.KEY_RIGHT or (key_pressed ==
curses.KEY_NPAGE): curses.KEY_NPAGE):
if page < pages: if page < pages:
page = page + 1 page = page + 1
position = (1 + (max_row * (page - 1))) position = (1 + (max_row * (page - 1)))
@ -471,32 +504,30 @@ 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.addnstr(1, 1, "There aren't any aliases yet. " + box.addnstr(1, 1, "There aren't any aliases yet. Press 'a' to add new one.",
"Press 'a' to add new one.", width - 6, width - 6, highlight_text)
highlight_text)
else: else:
if (i + (max_row * (page - 1)) == (position + if conf.has_option(strings[i - 1], "password"):
(max_row * (page - 1)))): password = " [password]"
box.addnstr(i - (max_row * (page - 1)), 2, "[" +
selected_strings[i] + "] " + str(i) + " " +
strings[i - 1] + " (" + conf.get(strings[i - 1],
"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, "[" + password = ""
selected_strings[i] + "] " + str(i) + " " + exec_string = ["[", selected_strings[i], "] ", str(i), " ",
strings[i - 1] + " (" + conf.get(strings[i - 1], strings[i - 1], " (", conf.get(strings[i - 1], "exec_string"),
"exec_string") + ")" + (" [password]" if ")", password]
conf.has_option(strings[i - 1], "password") else if (i + (max_row * (page - 1)) == (position + (max_row * (page - 1)))):
""), width - 6, normal_text) box.addnstr(i - (max_row * (page - 1)), 2, "".join(
exec_string), width - 6, highlight_text)
else:
box.addnstr(i - (max_row * (page - 1)), 2, "".join(
exec_string), width - 6, normal_text)
if i == row_num: if i == row_num:
break break
screen.refresh() screen.refresh()
box.refresh() box.refresh()
key_pressed = screen.getch() key_pressed = screen.getch()
CursesExit() CursesExit()
if __name__ == "__main__": if __name__ == "__main__":
conf = ConfigParser.RawConfigParser() conf = ConfigParser.RawConfigParser()
if not path.exists(conf_file): if not path.exists(conf_file):
@ -508,8 +539,7 @@ if __name__ == "__main__":
except KeyboardInterrupt: except KeyboardInterrupt:
exit() exit()
except ConfigParser.Error: except ConfigParser.Error:
print ("Error: can't parse your config file, please check" + print ("Error: can't parse your config file, please check it manually or make new one")
" it manually or make new one")
exit() exit()
else: else:
try: try:
@ -517,8 +547,8 @@ if __name__ == "__main__":
except KeyboardInterrupt: except KeyboardInterrupt:
CursesExit() CursesExit()
except ConfigParser.NoOptionError: except ConfigParser.NoOptionError:
CursesExit("Error: can't parse your config file, please " + CursesExit("".join(["Error: can't parse your config file, please ",
"check it manually or make new one") "check it manually or make new one"]))
except curses.error: except curses.error:
CursesExit("Error: can't show some curses element, maybe " + CursesExit("".join(["Error: can't show some curses element, maybe ",
"your terminal is too small") "your terminal is too small"]))