~ubuntu-branches/debian/wheezy/byobu/wheezy

« back to all changes in this revision

Viewing changes to byobu-config

  • Committer: Bazaar Package Importer
  • Author(s): Philipp Kern
  • Date: 2010-06-28 18:04:16 UTC
  • mfrom: (0.5.1 upstream) (0.3.4 squeeze)
  • Revision ID: james.westby@ubuntu.com-20100628180416-3xgfpga8cvp872ye
Upload to Debian unstable.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#! /usr/bin/env python
2
 
#
3
 
#    byobu-config
4
 
#    Copyright (C) 2008 Canonical Ltd.
5
 
#
6
 
#    Authors: Nick Barcet <nick.barcet@ubuntu.com>
7
 
#             Dustin Kirkland <kirkland@canonical.com>
8
 
#
9
 
#    This program is free software: you can redistribute it and/or modify
10
 
#    it under the terms of the GNU General Public License as published by
11
 
#    the Free Software Foundation, version 3 of the License.
12
 
#
13
 
#    This program is distributed in the hope that it will be useful,
14
 
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 
#    GNU General Public License for more details.
17
 
#
18
 
#    You should have received a copy of the GNU General Public License
19
 
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
 
 
21
 
# If you change any strings, please generate localization information with:
22
 
#       ./debian/rules get-po
23
 
 
24
 
 
25
 
import sys, os, os.path, time, string, commands, gettext, glob, snack
26
 
from ConfigParser import SafeConfigParser
27
 
from snack import *
28
 
 
29
 
HOME=os.getenv("HOME")
30
 
USER=os.getenv("USER")
31
 
PKG="byobu"
32
 
SHARE='/usr/share/'+PKG
33
 
DOC='/usr/share/doc/'+PKG
34
 
DEF_ESC="A"
35
 
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."
36
 
RELOAD_FLAG="/var/run/screen/S-"+USER+"/"+PKG+".reload-required"
37
 
RELOAD_CMD="screen -X at 0 source $HOME/."+PKG+"/profile"
38
 
ESC = ''
39
 
snack.hotkeys[ESC] = ord(ESC)
40
 
snack.hotkeys[ord(ESC)] = ESC
41
 
 
42
 
gettext.bindtextdomain(PKG, SHARE+'/po')
43
 
gettext.textdomain(PKG)
44
 
_ = gettext.gettext
45
 
 
46
 
# Command presets for windows creation
47
 
cmd=(   ("System activity", "top", "top"),
48
 
        ("System log", "log", "watch -n 10 tail -n 5 /var/log/syslog /var/log/auth.log /var/log/dmesg"),
49
 
        ("Disk and ram usage", "mem", 'watch -n 30 "df -h; echo ""; free -mt"'))
50
 
 
51
 
 
52
 
def ioctl_GWINSZ(fd):                  #### TABULATION FUNCTIONS
53
 
    try:                                ### Discover terminal width
54
 
        import fcntl, termios, struct, os
55
 
        cr = struct.unpack('hh', fcntl.ioctl(fd, termios.TIOCGWINSZ, '1234'))
56
 
    except:
57
 
        return None
58
 
    return cr
59
 
 
60
 
def reload_required():
61
 
    f = open(RELOAD_FLAG,'w')
62
 
    f.close()
63
 
    commands.getoutput(RELOAD_CMD)
64
 
 
65
 
def terminal_size():                    ### decide on *some* terminal size
66
 
    cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2)  # try open fds
67
 
    if not cr:                                                  # ...then ctty
68
 
        try:
69
 
            fd = os.open(os.ctermid(), os.O_RDONLY)
70
 
            cr = ioctl_GWINSZ(fd)
71
 
            os.close(fd)
72
 
        except:
73
 
            pass
74
 
    if not cr:                            # env vars or finally defaults
75
 
        try:
76
 
            cr = (env['LINES'], env['COLUMNS'])
77
 
        except:
78
 
            cr = (25, 80)
79
 
    return int(cr[1]-5), int(cr[0]-5)         # reverse rows, cols
80
 
 
81
 
def menu(screen, size, isInstalled):
82
 
    if isInstalled:
83
 
        installtext=_("Byobu currently launches at login (toggle off)")
84
 
    else:
85
 
        installtext=_("Byobu currently does not launch at login (toggle on)")
86
 
 
87
 
 
88
 
    li = Listbox(height = 8, width = 60, returnExit = 1)
89
 
    li.append(_("Help"), 1)
90
 
    li.append(_("Change Byobu's colors"), 2)
91
 
    li.append(_("Toggle status notifications"), 3)
92
 
    li.append(_("Change keybinding set"), 4)
93
 
    li.append(_("Change escape sequence"), 5)
94
 
    li.append(_("Create new windows"), 6)
95
 
    li.append(_("Manage default windows"), 7)
96
 
    li.append(installtext, 8)
97
 
    bb = ButtonBar(screen, (("Exit", "exit", ESC),), compact=1)
98
 
 
99
 
    g = GridForm(screen, _(" Byobu Configuration Menu"), 1, 2)
100
 
    g.add(li, 0, 0, padding=(4,2,4,2))
101
 
    g.add(bb, 0, 1, padding=(1,1,0,0))
102
 
 
103
 
    if bb.buttonPressed(g.runOnce()) == "exit":
104
 
        return 0
105
 
    else:
106
 
        return li.current()
107
 
 
108
 
def messagebox(screen, width, height, title, text, \
109
 
    scroll=0, \
110
 
    buttons=((_("Okay"), "okay"),(_("Cancel"), "cancel", ESC)) ):
111
 
 
112
 
    t = Textbox(width, height, text, scroll=scroll )
113
 
    bb = ButtonBar(screen, buttons, compact = 1)
114
 
    g = GridForm(screen, title, 1, 2)
115
 
    g.add(t, 0, 0, padding=(0,0,0,0))
116
 
    g.add(bb, 0, 1, padding=(1,1,0,0))
117
 
 
118
 
    return bb.buttonPressed(g.runOnce())
119
 
 
120
 
def help(screen, size, config):
121
 
    for fn in glob.glob(DOC+'*/help.txt'):
122
 
        f=file(fn)
123
 
        text=f.read()
124
 
        f.close()
125
 
 
126
 
    text=text.replace("<esckey>", getesckey(), 1)
127
 
 
128
 
    t = Textbox(70, 14, text, scroll=0)
129
 
    bb = ButtonBar(screen, ((_("Menu"), "menu", ESC),), compact = 1)
130
 
    g = GridForm(screen, _("Byobu Help"), 1, 3)
131
 
    g.add(t, 0, 0, padding=(0,0,0,0))
132
 
    g.add(bb, 0, 2, padding=(1,1,0,0))
133
 
 
134
 
    button = bb.buttonPressed(g.runOnce())
135
 
 
136
 
    return 100
137
 
 
138
 
def profile(screen, size):
139
 
    li = Listbox(height = 8, width = 60, scroll = 1, returnExit = 1)
140
 
 
141
 
    for choice in commands.getoutput('byobu-select-profile -l').splitlines():
142
 
        li.append(choice, choice)
143
 
 
144
 
    bb = ButtonBar(screen, ((_("Apply"), "apply"), (_("Cancel"), "cancel", ESC)), compact = 1)
145
 
 
146
 
    g = GridForm(screen, _("Which profile would you like to use?"), 1, 2)
147
 
    g.add(li, 0, 0, padding=(4,2,4,2))
148
 
    g.add(bb, 0, 1, padding=(1,1,0,0))
149
 
 
150
 
    if bb.buttonPressed(g.runOnce()) != "cancel":
151
 
        commands.getoutput('byobu-select-profile --set %s' % li.current())
152
 
        reload_required()
153
 
    return 100
154
 
 
155
 
def keybindings(screen, size):
156
 
    li = Listbox(height = 6, width = 60, returnExit = 1)
157
 
    for choice in commands.getoutput('ls '+SHARE+'/keybindings').splitlines():
158
 
        if choice != "common" and choice != "none":
159
 
            li.append(choice, choice)
160
 
    li.append("none", "none")
161
 
    bb = ButtonBar(screen, ((_("Apply"), "apply"), (_("Cancel"), "cancel", ESC)), compact = 1)
162
 
    g = GridForm(screen, _("Which set of keybindings would you like to use?"), 1, 2)
163
 
    g.add(li, 0, 0, padding=(4,2,4,2))
164
 
    g.add(bb, 0, 1, padding=(1,1,0,0))
165
 
    if bb.buttonPressed(g.runOnce()) != "cancel":
166
 
        switch_keybindings(li.current())
167
 
        reload_required()
168
 
    return 100
169
 
 
170
 
def switch_keybindings(set):
171
 
    commands.getoutput("sed -i -e 's:^source .*$:source "+SHARE+"/keybindings/"+set+":' "+HOME+"/."+PKG+"/keybindings")
172
 
 
173
 
def newwindow(screen, size):
174
 
    title=Entry(8, text="bash", returnExit=1)
175
 
    titlel=Label(_("Title: "))
176
 
    command=Entry(20, text="/bin/bash", returnExit=1)
177
 
    commandl=Label(_("Command: "))
178
 
 
179
 
    rl=Label(_("Presets: "))
180
 
    if len(cmd) > 10:
181
 
        scroll=1
182
 
        size=10
183
 
    else:
184
 
        scroll=0
185
 
        size = len(cmd)
186
 
 
187
 
    r=CheckboxTree(size, scroll=scroll)
188
 
    count=0
189
 
    for cur in cmd:
190
 
        r.append(cur[0], count)
191
 
        count=count+1
192
 
 
193
 
    cb=Checkbox(_("Add to default windows"))
194
 
 
195
 
    bb = ButtonBar(screen, ((_("Apply"), "apply"), (_("Cancel"), "cancel", ESC)), compact = 1)
196
 
 
197
 
    g = GridForm(screen, _("Create new window(s):"), 2, 5 )
198
 
    g.add(titlel, 0, 0, anchorLeft=1,padding=(4,1,0,1))
199
 
    g.add(title, 1, 0, anchorLeft=1)
200
 
    g.add(commandl, 0, 1, anchorLeft=1, anchorTop=1,padding=(4,0,0,1))
201
 
    g.add(command, 1, 1, anchorLeft=1)
202
 
    g.add(rl, 0, 2, anchorLeft=1,padding=(4,0,0,1))
203
 
    g.add(r, 1, 2)
204
 
    g.add(cb, 1, 3, padding=(4,1,0,1))
205
 
    g.add(bb, 1, 4, padding=(4,1,0,0))
206
 
 
207
 
    if bb.buttonPressed(g.runOnce()) != "cancel":
208
 
        sel=r.getSelection()
209
 
        if sel:
210
 
            for s in sel:
211
 
                win='screen -t %s %s' % (cmd[s][1], cmd[s][2])
212
 
                commands.getoutput(win)
213
 
                if cb.value():
214
 
                    appendwindow(win)
215
 
        else:
216
 
            win='screen -t %s %s' % (title.value(), command.value())
217
 
            commands.getoutput(win)
218
 
            if cb.value():
219
 
                appendwindow(win)
220
 
 
221
 
    return 100
222
 
 
223
 
def appendwindow(win):
224
 
    f=open(HOME+'/.'+PKG+'/windows', 'a')
225
 
    try:
226
 
        f.write(win+"\n")
227
 
 
228
 
    except IOError:
229
 
        return None
230
 
 
231
 
    finally:
232
 
        f.close()
233
 
 
234
 
def readwindows():
235
 
    if not os.path.isfile(HOME+'/.'+PKG+'/windows'):
236
 
        windowsfile=SHARE+'/windows/common'
237
 
    elif os.path.getsize(HOME+'/.'+PKG+'/windows') == 0:
238
 
        windowsfile=SHARE+'/windows/common'
239
 
    else:
240
 
        windowsfile=HOME+'/.'+PKG+'/windows'
241
 
    f=open(windowsfile)
242
 
    try:
243
 
        li=[]
244
 
        for line in f.readlines():
245
 
            if line.startswith("# "):
246
 
               # this is a comment
247
 
               window=[-1, line]
248
 
            elif line.startswith("#"):
249
 
               # this is an inactive window
250
 
               window=[0, line.lstrip("#")]
251
 
            else:
252
 
               window=[1, line]
253
 
            li.append(window)
254
 
 
255
 
        return li
256
 
 
257
 
    except IOError:
258
 
        return None
259
 
 
260
 
    finally:
261
 
        f.close()
262
 
 
263
 
def readstatus():
264
 
    status={}
265
 
    status["arch"]=0
266
 
    status["battery"]=0
267
 
    status["cpu_count"]=1
268
 
    status["cpu_freq"]=1
269
 
    status["date"]=1
270
 
    status["disk"]=0
271
 
    status["ec2_cost"]=0
272
 
    status["fan_speed"]=0
273
 
    status["hostname"]=0
274
 
    status["ip_address"]=0
275
 
    status["load_average"]=1
276
 
    status["logo"]=1
277
 
    status["mail"]=0
278
 
    status["mem_available"]=1
279
 
    status["mem_used"]=1
280
 
    status["menu"]=1
281
 
    status["network"]=0
282
 
    status["processes"]=0
283
 
    status["reboot_required"]=1
284
 
    status["release"]=1
285
 
    status["temp_c"]=0
286
 
    status["temp_f"]=0
287
 
    status["time"]=1
288
 
    status["users"]=0
289
 
    status["updates_available"]=1
290
 
    status["uptime"]=1
291
 
    status["whoami"]=0
292
 
    status["wifi_quality"]=0
293
 
    if os.path.exists(HOME+'/.'+PKG+'/status'):
294
 
        f=open(HOME+'/.'+PKG+'/status', 'r')
295
 
        for line in f.readlines():
296
 
           try:
297
 
               line = line.rstrip()
298
 
               (key, val) = line.split("=", 2)
299
 
               if status.has_key(key) and (val == "1" or val == "0"):
300
 
                   status[key] = val
301
 
           except:
302
 
               continue
303
 
        f.close()
304
 
    li=[]
305
 
    keys = status.keys()
306
 
    keys.sort()
307
 
    for i in keys:
308
 
        window=[int(status[i]), i]
309
 
        li.append(window)
310
 
    return li
311
 
 
312
 
def writestatus(items):
313
 
    f=open(HOME+'/.'+PKG+'/status', 'w')
314
 
    try:
315
 
        for i in items:
316
 
            if i[0] == 1:
317
 
                f.write(i[1]+"=1\n")
318
 
            elif i[0] == 0:
319
 
                f.write(i[1]+"=0\n")
320
 
    except IOError:
321
 
        return None
322
 
    finally:
323
 
        f.close()
324
 
 
325
 
def togglestatus(screen, size):
326
 
    itemlist=readstatus()
327
 
    rl=Label("")
328
 
    r=CheckboxTree(12, scroll=1)
329
 
    count=0
330
 
    for item in itemlist:
331
 
       if item[0] != -1:
332
 
            r.append(item[1],count,selected=item[0])
333
 
       count=count+1
334
 
    bb = ButtonBar(screen, ((_("Apply"), "apply"), (_("Cancel"), "cancel", ESC)), compact = 1)
335
 
    g = GridForm(screen, _("Toggle status notifications:"), 2, 4 )
336
 
    g.add(rl, 0, 0, anchorLeft=1, anchorTop=1, padding=(4,0,0,1))
337
 
    g.add(r, 1, 0)
338
 
    g.add(bb, 1, 1, padding=(4,1,0,0))
339
 
    if bb.buttonPressed(g.runOnce()) != "cancel":
340
 
        count=0
341
 
        for item in itemlist:
342
 
            if item[0] != -1:
343
 
                item[0] = r.getEntryValue(count)[1]
344
 
            count=count+1
345
 
        writestatus(itemlist)
346
 
        reload_required()
347
 
    return 100
348
 
 
349
 
def writewindows(winlist):
350
 
    f=open(HOME+'/.'+PKG+'/windows', 'w')
351
 
    try:
352
 
        for win in winlist:
353
 
            if win[0] == -1:
354
 
                f.write(win[1])
355
 
            elif win[0] == 0:
356
 
                f.write("#"+win[1])
357
 
            else:
358
 
                f.write(win[1])
359
 
    except IOError:
360
 
        return None
361
 
    finally:
362
 
        f.close()
363
 
 
364
 
def defaultwindows(screen, size):
365
 
    winlist=readwindows()
366
 
 
367
 
    rl=Label(_("Windows:"))
368
 
    r=CheckboxTree(10, scroll=1)
369
 
    count=0
370
 
    for win in winlist:
371
 
       if win[0] != -1:
372
 
            r.append(win[1],count,selected=win[0])
373
 
       count=count+1
374
 
 
375
 
    bb = ButtonBar(screen, ((_("Apply"), "apply"), (_("Cancel"), "cancel", ESC)), compact = 1)
376
 
 
377
 
    g = GridForm(screen, _("Select window(s) to create by default:"), 2, 4 )
378
 
    g.add(rl, 0, 0, anchorLeft=1, anchorTop=1, padding=(4,0,0,1))
379
 
    g.add(r, 1, 0)
380
 
    g.add(bb, 1, 1, padding=(4,1,0,0))
381
 
 
382
 
    if bb.buttonPressed(g.runOnce()) != "cancel":
383
 
        count=0
384
 
        for win in winlist:
385
 
            if win[0] != -1:
386
 
                win[0] = r.getEntryValue(count)[1]
387
 
            count=count+1
388
 
 
389
 
        writewindows(winlist)
390
 
 
391
 
    return 100
392
 
 
393
 
def install(screen, size, isInstalled):
394
 
    if not isInstalled:
395
 
        out = commands.getoutput("bash /usr/share/"+PKG+"/byobu-launcher-install")
396
 
        if out == "":
397
 
            out = _("Byobu will be launched automatically next time you login.")
398
 
 
399
 
        button = messagebox(screen, 60, 2, "Message", out, \
400
 
        buttons=((_("Menu"), )))
401
 
        return 100
402
 
    else:
403
 
        out = commands.getoutput("bash /usr/share/"+PKG+"/byobu-launcher-uninstall")
404
 
        if out == "":
405
 
            out = _("Byobu will not be used next time you login.")
406
 
 
407
 
        button = messagebox(screen, 60, 2, _("Message"), out, \
408
 
        buttons=((_("Menu"), )))
409
 
        return 101
410
 
 
411
 
def appendtofile(p, s):
412
 
    f = open(p, 'a')
413
 
    try:
414
 
        f.write(s)
415
 
    except IOError:
416
 
        return
417
 
    finally:
418
 
        f.close()
419
 
    return
420
 
 
421
 
 
422
 
def getesckey():
423
 
    path=HOME+'/.'+PKG+'/keybindings'
424
 
    if not os.path.exists(path):
425
 
        return DEF_ESC
426
 
    line = commands.getoutput("grep ^escape "+path)
427
 
    if line == "":
428
 
        return DEF_ESC
429
 
    return line[line.find('^')+1]
430
 
 
431
 
def setesckey(key):
432
 
    path = HOME+'/.'+PKG+'/keybindings'
433
 
    if key != "":
434
 
        u = key[0].upper()
435
 
        l = key[0].lower()
436
 
        if os.path.exists(path):
437
 
            out = commands.getoutput("sed -i -e 's/^escape.*$//' "+path)
438
 
            appendtofile(path, "escape ^"+u+l+"\n")
439
 
            out = commands.getoutput("sed -i -e 's/^register.*$//' "+path)
440
 
            out = commands.getoutput("grep -h ^register "+SHARE+"/keybindings/*keys")
441
 
            appendtofile(path, out+"\n")
442
 
            out = commands.getoutput("sed -i -e 's/\"\^a/\"\^"+l+"/g' "+path)
443
 
            out = commands.getoutput("sed -i -e '/^$/d' "+path)
444
 
 
445
 
def chgesc(screen, size):
446
 
    esc=Entry(2, text=getesckey(), returnExit=1)
447
 
    escl=Label(_("Escape key: ctrl-"))
448
 
    bb = ButtonBar(screen, ((_("Apply"), "apply"), (_("Cancel"), "cancel", ESC)), compact = 1)
449
 
 
450
 
    g = GridForm(screen, _("Change escape sequence:"), 2, 4 )
451
 
    g.add(escl, 0, 0, anchorLeft=1, padding=(1,0,0,1))
452
 
    g.add(esc, 1, 0, anchorLeft=1)
453
 
    g.add(bb, 1, 1)
454
 
    g.setTimer(100)
455
 
    loop=1
456
 
    while loop:
457
 
        which=g.run()
458
 
        if which == "TIMER":
459
 
            val=esc.value()
460
 
            if len(val) > 1:
461
 
                esc.set(val[1])
462
 
            # Ensure that the escape sequence is not set to a number
463
 
            try:
464
 
                dummy = int(esc.value())
465
 
                esc.set(DEF_ESC)
466
 
            except:
467
 
               # do nothing
468
 
               dummy = "foo"
469
 
        else:
470
 
            loop=0
471
 
    screen.popWindow()
472
 
    if bb.buttonPressed(which) != "cancel":
473
 
        setesckey(esc.value())
474
 
        reload_required()
475
 
        if button == "exit":
476
 
            return 0
477
 
    return 100
478
 
 
479
 
def main():
480
 
    """This is the main loop of our utility
481
 
    """
482
 
 
483
 
    size = terminal_size()
484
 
    screen = SnackScreen()
485
 
    screen.drawRootText(1,0,_(' Byobu Configuration Menu'))
486
 
    screen.pushHelpLine(_('<Tab>/<Alt-Tab> between elements | <Enter> selects | <Esc> exits'))
487
 
 
488
 
    config = SafeConfigParser()
489
 
 
490
 
    isInstalled = (commands.getoutput('grep byobu-launcher '+(HOME+'/.profile')) != "")
491
 
 
492
 
    tag = 100
493
 
 
494
 
    while tag > 0 :
495
 
        tag = menu(screen, size, isInstalled)
496
 
        if tag == 1:
497
 
            tag = help(screen, size, config)
498
 
        elif tag == 2:
499
 
            tag = profile(screen, size)
500
 
        elif tag == 3:
501
 
            tag = togglestatus(screen, size)
502
 
        elif tag == 4:
503
 
            tag = keybindings(screen, size)
504
 
        elif tag == 5:
505
 
            tag = chgesc(screen, size)
506
 
        elif tag == 6:
507
 
            tag = newwindow(screen, size)
508
 
        elif tag == 7:
509
 
            tag = defaultwindows(screen, size)
510
 
        elif tag == 8:
511
 
            tag = install(screen, size, isInstalled)
512
 
            isInstalled=(tag == 100)
513
 
 
514
 
    screen.finish()
515
 
    sys.exit(0)
516
 
 
517
 
 
518
 
if __name__ == "__main__": main()