Created
November 7, 2009 22:42
-
-
Save goozbach/228925 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# include file for python | |
[defaults] | |
PREFIX=changeme | |
PKG=byobu | |
SHARE=%(PREFIX)s/share/%(PKG)s | |
DOC=%(SHARE)s/doc/%(PKG)s |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# python path | |
# | |
# byobu-config | |
# Copyright (C) 2008 Canonical Ltd. | |
# | |
# Authors: Nick Barcet <[email protected]> | |
# Dustin Kirkland <[email protected]> | |
# | |
# This program is free software: you can redistribute it and/or modify | |
# it under the terms of the GNU General Public License as published by | |
# the Free Software Foundation, version 3 of the License. | |
# | |
# This program 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 this program. If not, see <http://www.gnu.org/licenses/>. | |
# If you change any strings, please generate localization information with: | |
# ./debian/rules get-po | |
import sys, os, os.path, time, string, commands, gettext, glob, snack | |
import ConfigParser | |
from ConfigParser import SafeConfigParser | |
from snack import * | |
HOME=os.getenv("HOME") | |
USER=os.getenv("USER") | |
# import important vars from include file | |
_config = ConfigParser.ConfigParser() | |
_execdir = os.path.dirname(sys.argv[0]) | |
_configfile = os.path.join(_execdir,'byobu-config.ini') | |
_config.read(_configfile) | |
# set those items as global vars | |
for foo in _config.items('defaults'): | |
item, value = foo | |
globals()[item] = value | |
# debug | |
print _config.items('defaults',0) | |
# end debug | |
## start vars which should be imported | |
PKG=pkg | |
#PREFIX='/usr/local/' | |
SHARE=share | |
DOC=doc | |
## end vars which should be included | |
RUN="/var/run/screen/S-"+USER+"/" | |
RELOAD_FLAG=RUN+PKG+".reload-required" | |
DEF_ESC="A" | |
RELOAD = "If you are using the default set of keybindings, press\n<F5> or <ctrl-a-R> to activate these changes.\n\nOtherwise, exit this screen session and start a new one." | |
RELOAD_CMD="screen -X at 0 source $HOME/."+PKG+"/profile" | |
ESC = '' | |
snack.hotkeys[ESC] = ord(ESC) | |
snack.hotkeys[ord(ESC)] = ESC | |
gettext.bindtextdomain(PKG, SHARE+'/po') | |
gettext.textdomain(PKG) | |
_ = gettext.gettext | |
# Command presets for windows creation | |
cmd=( ("System activity", "top", "top"), | |
("System log", "log", "watch -n 10 tail -n 5 /var/log/syslog /var/log/auth.log /var/log/dmesg"), | |
("Disk and ram usage", "mem", 'watch -n 30 "df -h; echo ""; free -mt"')) | |
def ioctl_GWINSZ(fd): #### TABULATION FUNCTIONS | |
try: ### Discover terminal width | |
import fcntl, termios, struct, os | |
cr = struct.unpack('hh', fcntl.ioctl(fd, termios.TIOCGWINSZ, '1234')) | |
except: | |
return None | |
return cr | |
def reload_required(): | |
f = open(RELOAD_FLAG,'w') | |
f.close() | |
commands.getoutput(RELOAD_CMD) | |
def terminal_size(): ### decide on *some* terminal size | |
cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2) # try open fds | |
if not cr: # ...then ctty | |
try: | |
fd = os.open(os.ctermid(), os.O_RDONLY) | |
cr = ioctl_GWINSZ(fd) | |
os.close(fd) | |
except: | |
pass | |
if not cr: # env vars or finally defaults | |
try: | |
cr = (env['LINES'], env['COLUMNS']) | |
except: | |
cr = (25, 80) | |
return int(cr[1]-5), int(cr[0]-5) # reverse rows, cols | |
def menu(screen, size, isInstalled): | |
if isInstalled: | |
installtext=_("Byobu currently launches at login (toggle off)") | |
else: | |
installtext=_("Byobu currently does not launch at login (toggle on)") | |
li = Listbox(height = 8, width = 60, returnExit = 1) | |
li.append(_("Help"), 1) | |
li.append(_("Change Byobu's colors"), 2) | |
li.append(_("Toggle status notifications"), 3) | |
li.append(_("Change keybinding set"), 4) | |
li.append(_("Change escape sequence"), 5) | |
li.append(_("Create new windows"), 6) | |
li.append(_("Manage default windows"), 7) | |
li.append(installtext, 8) | |
bb = ButtonBar(screen, (("Exit", "exit", ESC),), compact=1) | |
g = GridForm(screen, _(" Byobu Configuration Menu"), 1, 2) | |
g.add(li, 0, 0, padding=(4,2,4,2)) | |
g.add(bb, 0, 1, padding=(1,1,0,0)) | |
if bb.buttonPressed(g.runOnce()) == "exit": | |
return 0 | |
else: | |
return li.current() | |
def messagebox(screen, width, height, title, text, \ | |
scroll=0, \ | |
buttons=((_("Okay"), "okay"),(_("Cancel"), "cancel", ESC)) ): | |
t = Textbox(width, height, text, scroll=scroll ) | |
bb = ButtonBar(screen, buttons, compact = 1) | |
g = GridForm(screen, title, 1, 2) | |
g.add(t, 0, 0, padding=(0,0,0,0)) | |
g.add(bb, 0, 1, padding=(1,1,0,0)) | |
return bb.buttonPressed(g.runOnce()) | |
def help(screen, size, config): | |
for fn in glob.glob(DOC+'*/help.txt'): | |
f=file(fn) | |
text=f.read() | |
f.close() | |
text=text.replace("<esckey>", getesckey(), 1) | |
t = Textbox(70, 14, text, scroll=0) | |
bb = ButtonBar(screen, ((_("Menu"), "menu", ESC),), compact = 1) | |
g = GridForm(screen, _("Byobu Help"), 1, 3) | |
g.add(t, 0, 0, padding=(0,0,0,0)) | |
g.add(bb, 0, 2, padding=(1,1,0,0)) | |
button = bb.buttonPressed(g.runOnce()) | |
return 100 | |
def profile(screen, size): | |
li = Listbox(height = 8, width = 60, scroll = 1, returnExit = 1) | |
for choice in commands.getoutput('byobu-select-profile -l').splitlines(): | |
li.append(choice, choice) | |
bb = ButtonBar(screen, ((_("Apply"), "apply"), (_("Cancel"), "cancel", ESC)), compact = 1) | |
g = GridForm(screen, _("Which profile would you like to use?"), 1, 2) | |
g.add(li, 0, 0, padding=(4,2,4,2)) | |
g.add(bb, 0, 1, padding=(1,1,0,0)) | |
if bb.buttonPressed(g.runOnce()) != "cancel": | |
commands.getoutput('byobu-select-profile --set %s' % li.current()) | |
reload_required() | |
return 100 | |
def keybindings(screen, size): | |
li = Listbox(height = 6, width = 60, returnExit = 1) | |
for choice in commands.getoutput('ls '+SHARE+'/keybindings').splitlines(): | |
if choice != "common" and choice != "none": | |
li.append(choice, choice) | |
li.append("none", "none") | |
bb = ButtonBar(screen, ((_("Apply"), "apply"), (_("Cancel"), "cancel", ESC)), compact = 1) | |
g = GridForm(screen, _("Which set of keybindings would you like to use?"), 1, 2) | |
g.add(li, 0, 0, padding=(4,2,4,2)) | |
g.add(bb, 0, 1, padding=(1,1,0,0)) | |
if bb.buttonPressed(g.runOnce()) != "cancel": | |
switch_keybindings(li.current()) | |
reload_required() | |
return 100 | |
def switch_keybindings(set): | |
commands.getoutput("sed -i -e 's:^source .*$:source "+SHARE+"/keybindings/"+set+":' "+HOME+"/."+PKG+"/keybindings") | |
def newwindow(screen, size): | |
title=Entry(8, text="bash", returnExit=1) | |
titlel=Label(_("Title: ")) | |
command=Entry(20, text="/bin/bash", returnExit=1) | |
commandl=Label(_("Command: ")) | |
rl=Label(_("Presets: ")) | |
if len(cmd) > 10: | |
scroll=1 | |
size=10 | |
else: | |
scroll=0 | |
size = len(cmd) | |
r=CheckboxTree(size, scroll=scroll) | |
count=0 | |
for cur in cmd: | |
r.append(cur[0], count) | |
count=count+1 | |
cb=Checkbox(_("Add to default windows")) | |
bb = ButtonBar(screen, ((_("Apply"), "apply"), (_("Cancel"), "cancel", ESC)), compact = 1) | |
g = GridForm(screen, _("Create new window(s):"), 2, 5 ) | |
g.add(titlel, 0, 0, anchorLeft=1,padding=(4,1,0,1)) | |
g.add(title, 1, 0, anchorLeft=1) | |
g.add(commandl, 0, 1, anchorLeft=1, anchorTop=1,padding=(4,0,0,1)) | |
g.add(command, 1, 1, anchorLeft=1) | |
g.add(rl, 0, 2, anchorLeft=1,padding=(4,0,0,1)) | |
g.add(r, 1, 2) | |
g.add(cb, 1, 3, padding=(4,1,0,1)) | |
g.add(bb, 1, 4, padding=(4,1,0,0)) | |
if bb.buttonPressed(g.runOnce()) != "cancel": | |
sel=r.getSelection() | |
if sel: | |
for s in sel: | |
win='screen -t %s %s' % (cmd[s][1], cmd[s][2]) | |
commands.getoutput(win) | |
if cb.value(): | |
appendwindow(win) | |
else: | |
win='screen -t %s %s' % (title.value(), command.value()) | |
commands.getoutput(win) | |
if cb.value(): | |
appendwindow(win) | |
return 100 | |
def appendwindow(win): | |
f=open(HOME+'/.'+PKG+'/windows', 'a') | |
try: | |
f.write(win+"\n") | |
except IOError: | |
f.close() | |
return None | |
f.close() | |
def readwindows(): | |
if not os.path.isfile(HOME+'/.'+PKG+'/windows'): | |
windowsfile=SHARE+'/windows/common' | |
elif os.path.getsize(HOME+'/.'+PKG+'/windows') == 0: | |
windowsfile=SHARE+'/windows/common' | |
else: | |
windowsfile=HOME+'/.'+PKG+'/windows' | |
f=open(windowsfile) | |
try: | |
li=[] | |
for line in f.readlines(): | |
if line.startswith("# "): | |
# this is a comment | |
window=[-1, line] | |
elif line.startswith("#"): | |
# this is an inactive window | |
window=[0, line.lstrip("#")] | |
else: | |
window=[1, line] | |
li.append(window) | |
return li | |
except IOError: | |
f.close() | |
return None | |
f.close() | |
def readstatus(): | |
status={} | |
status["arch"]=0 | |
status["battery"]=0 | |
status["cpu_count"]=1 | |
status["cpu_freq"]=1 | |
status["date"]=1 | |
status["disk"]=0 | |
status["ec2_cost"]=0 | |
status["fan_speed"]=0 | |
status["hostname"]=0 | |
status["ip_address"]=0 | |
status["load_average"]=1 | |
status["logo"]=1 | |
status["mail"]=0 | |
status["mem_available"]=1 | |
status["mem_used"]=1 | |
status["menu"]=1 | |
status["network"]=0 | |
status["processes"]=0 | |
status["reboot_required"]=1 | |
status["release"]=1 | |
status["temp_c"]=0 | |
status["temp_f"]=0 | |
status["time"]=1 | |
status["users"]=0 | |
status["updates_available"]=1 | |
status["uptime"]=1 | |
status["whoami"]=0 | |
status["wifi_quality"]=0 | |
if os.path.exists(HOME+'/.'+PKG+'/status'): | |
f=open(HOME+'/.'+PKG+'/status', 'r') | |
for line in f.readlines(): | |
try: | |
line = line.rstrip() | |
(key, val) = line.split("=", 2) | |
if status.has_key(key) and (val == "1" or val == "0"): | |
status[key] = val | |
except: | |
continue | |
f.close() | |
li=[] | |
keys = status.keys() | |
keys.sort() | |
for i in keys: | |
window=[int(status[i]), i] | |
li.append(window) | |
return li | |
def writestatus(items): | |
f=open(HOME+'/.'+PKG+'/status', 'w') | |
try: | |
for i in items: | |
if i[0] == 1: | |
f.write(i[1]+"=1\n") | |
elif i[0] == 0: | |
f.write(i[1]+"=0\n") | |
except IOError: | |
f.close() | |
return None | |
f.close() | |
def togglestatus(screen, size): | |
itemlist=readstatus() | |
rl=Label("") | |
r=CheckboxTree(12, scroll=1) | |
count=0 | |
for item in itemlist: | |
if item[0] != -1: | |
r.append(item[1],count,selected=item[0]) | |
count=count+1 | |
bb = ButtonBar(screen, ((_("Apply"), "apply"), (_("Cancel"), "cancel", ESC)), compact = 1) | |
g = GridForm(screen, _("Toggle status notifications:"), 2, 4 ) | |
g.add(rl, 0, 0, anchorLeft=1, anchorTop=1, padding=(4,0,0,1)) | |
g.add(r, 1, 0) | |
g.add(bb, 1, 1, padding=(4,1,0,0)) | |
if bb.buttonPressed(g.runOnce()) != "cancel": | |
count=0 | |
for item in itemlist: | |
if item[0] != -1: | |
item[0] = r.getEntryValue(count)[1] | |
count=count+1 | |
writestatus(itemlist) | |
reload_required() | |
return 100 | |
def writewindows(winlist): | |
f=open(HOME+'/.'+PKG+'/windows', 'w') | |
try: | |
for win in winlist: | |
if win[0] == -1: | |
f.write(win[1]) | |
elif win[0] == 0: | |
f.write("#"+win[1]) | |
else: | |
f.write(win[1]) | |
except IOError: | |
f.close() | |
return None | |
f.close() | |
def defaultwindows(screen, size): | |
winlist=readwindows() | |
rl=Label(_("Windows:")) | |
r=CheckboxTree(10, scroll=1) | |
count=0 | |
for win in winlist: | |
if win[0] != -1: | |
r.append(win[1],count,selected=win[0]) | |
count=count+1 | |
bb = ButtonBar(screen, ((_("Apply"), "apply"), (_("Cancel"), "cancel", ESC)), compact = 1) | |
g = GridForm(screen, _("Select window(s) to create by default:"), 2, 4 ) | |
g.add(rl, 0, 0, anchorLeft=1, anchorTop=1, padding=(4,0,0,1)) | |
g.add(r, 1, 0) | |
g.add(bb, 1, 1, padding=(4,1,0,0)) | |
if bb.buttonPressed(g.runOnce()) != "cancel": | |
count=0 | |
for win in winlist: | |
if win[0] != -1: | |
win[0] = r.getEntryValue(count)[1] | |
count=count+1 | |
writewindows(winlist) | |
return 100 | |
def install(screen, size, isInstalled): | |
if not isInstalled: | |
out = commands.getoutput("bash /usr/share/"+PKG+"/byobu-launcher-install") | |
if out == "": | |
out = _("Byobu will be launched automatically next time you login.") | |
button = messagebox(screen, 60, 2, "Message", out, \ | |
buttons=((_("Menu"), ))) | |
return 100 | |
else: | |
out = commands.getoutput("bash /usr/share/"+PKG+"/byobu-launcher-uninstall") | |
if out == "": | |
out = _("Byobu will not be used next time you login.") | |
button = messagebox(screen, 60, 2, _("Message"), out, \ | |
buttons=((_("Menu"), ))) | |
return 101 | |
def appendtofile(p, s): | |
f = open(p, 'a') | |
try: | |
f.write(s) | |
except IOError: | |
f.close() | |
return | |
f.close() | |
return | |
def getesckey(): | |
path=HOME+'/.'+PKG+'/keybindings' | |
if not os.path.exists(path): | |
return DEF_ESC | |
line = commands.getoutput("grep ^escape "+path) | |
if line == "": | |
return DEF_ESC | |
return line[line.find('^')+1] | |
def setesckey(key): | |
path = HOME+'/.'+PKG+'/keybindings' | |
if key != "": | |
u = key[0].upper() | |
l = key[0].lower() | |
if os.path.exists(path): | |
out = commands.getoutput("sed -i -e 's/^escape.*$//' "+path) | |
appendtofile(path, "escape ^"+u+l+"\n") | |
out = commands.getoutput("sed -i -e 's/^register.*$//' "+path) | |
out = commands.getoutput("grep -h ^register "+SHARE+"/keybindings/*keys") | |
appendtofile(path, out+"\n") | |
out = commands.getoutput("sed -i -e 's/\"\^a/\"\^"+l+"/g' "+path) | |
out = commands.getoutput("sed -i -e '/^$/d' "+path) | |
def chgesc(screen, size): | |
esc=Entry(2, text=getesckey(), returnExit=1) | |
escl=Label(_("Escape key: ctrl-")) | |
bb = ButtonBar(screen, ((_("Apply"), "apply"), (_("Cancel"), "cancel", ESC)), compact = 1) | |
g = GridForm(screen, _("Change escape sequence:"), 2, 4 ) | |
g.add(escl, 0, 0, anchorLeft=1, padding=(1,0,0,1)) | |
g.add(esc, 1, 0, anchorLeft=1) | |
g.add(bb, 1, 1) | |
g.setTimer(100) | |
loop=1 | |
while loop: | |
which=g.run() | |
if which == "TIMER": | |
val=esc.value() | |
if len(val) > 1: | |
esc.set(val[1]) | |
# Ensure that the escape sequence is not set to a number | |
try: | |
dummy = int(esc.value()) | |
esc.set(DEF_ESC) | |
except: | |
# do nothing | |
dummy = "foo" | |
else: | |
loop=0 | |
screen.popWindow() | |
button = bb.buttonPressed(which) | |
if button != "cancel": | |
setesckey(esc.value()) | |
reload_required() | |
if button == "exit": | |
return 0 | |
return 100 | |
def main(): | |
"""This is the main loop of our utility | |
""" | |
size = terminal_size() | |
screen = SnackScreen() | |
screen.drawRootText(1,0,_(' Byobu Configuration Menu')) | |
screen.pushHelpLine(_('<Tab>/<Alt-Tab> between elements | <Enter> selects | <Esc> exits')) | |
config = SafeConfigParser() | |
isInstalled = (commands.getoutput('grep byobu-launcher '+(HOME+'/.profile')) != "") | |
tag = 100 | |
while tag > 0 : | |
tag = menu(screen, size, isInstalled) | |
if tag == 1: | |
tag = help(screen, size, config) | |
elif tag == 2: | |
tag = profile(screen, size) | |
elif tag == 3: | |
tag = togglestatus(screen, size) | |
elif tag == 4: | |
tag = keybindings(screen, size) | |
elif tag == 5: | |
tag = chgesc(screen, size) | |
elif tag == 6: | |
tag = newwindow(screen, size) | |
elif tag == 7: | |
tag = defaultwindows(screen, size) | |
elif tag == 8: | |
tag = install(screen, size, isInstalled) | |
isInstalled=(tag == 100) | |
screen.finish() | |
sys.exit(0) | |
if __name__ == "__main__": main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment