def respond(me, hunoz, rid, *hukairz):
if rid >= 0: me.rmap[rid]()
+def makeactiongroup(name, acts):
+ """Creates an ActionGroup called NAME. ACTS is a list of tuples
+ containing:
+ ACT: an action name
+ LABEL: the label string for the action
+ ACCEL: accelerator string, or None
+ FUNC: thunk to call when the action is invoked"""
+ actgroup = G.ActionGroup(name)
+ for act, label, accel, func in acts:
+ a = G.Action(act, label, None, None)
+ if func: a.connect('activate', invoker(func))
+ actgroup.add_action_with_accel(a, accel)
+ return actgroup
+
+class GridPacker (G.Table):
+ """Like a Table, but with more state: makes filling in the widgets
+ easier."""
+ def __init__(me):
+ G.Table.__init__(me)
+ me.row = 0
+ me.col = 0
+ me.rows = 1
+ me.cols = 1
+ me.set_border_width(4)
+ me.set_col_spacings(4)
+ me.set_row_spacings(4)
+ def pack(me, w, width = 1, newlinep = False,
+ xopt = G.EXPAND | G.FILL | G.SHRINK, yopt = 0,
+ xpad = 0, ypad = 0):
+ """Packs a new widget. W is the widget to add. XOPY, YOPT, XPAD and
+ YPAD are as for Table. WIDTH is how many cells to take up horizontally.
+ NEWLINEP is whether to start a new line for this widget. Returns W."""
+ if newlinep:
+ me.row += 1
+ me.col = 0
+ bot = me.row + 1
+ right = me.col + width
+ if bot > me.rows or right > me.cols:
+ if bot > me.rows: me.rows = bot
+ if right > me.cols: me.cols = right
+ me.resize(me.rows, me.cols)
+ me.attach(w, me.col, me.col + width, me.row, me.row + 1,
+ xopt, yopt, xpad, ypad)
+ me.col += width
+ return w
+ def labelled(me, lab, w, newlinep = False, **kw):
+ """Packs a labelled widget. Other arguments are as for pack. Returns
+ W."""
+ label = G.Label(lab)
+ label.set_alignment(1.0, 0)
+ me.pack(label, newlinep = newlinep, xopt = G.FILL)
+ me.pack(w, **kw)
+ return w
+ def info(me, label, text = None, len = 18, **kw):
+ """Packs an information widget with a label. LABEL is the label; TEXT is
+ the initial text; LEN is the estimated length in characters. Returns the
+ entry widget."""
+ e = G.Entry()
+ if text is not None: e.set_text(text)
+ e.set_width_chars(len)
+ e.set_editable(False)
+ me.labelled(label, e, **kw)
+ return e
+
class WindowSlot (HookClient):
"""A place to store a window. If the window is destroyed, remember this;
when we come to open the window, raise it if it already exists; otherwise
d.run()
d.destroy()
+def unimplemented(*hunoz):
+ """Indicator of laziness."""
+ moanbox("I've not written that bit yet.")
+
+class ServInfo (MyWindow):
+ def __init__(me, monitor):
+ MyWindow.__init__(me)
+ me.set_title('TrIPE server info')
+ me.mon = monitor
+ me.table = GridPacker()
+ me.add(me.table)
+ me.e = {}
+ def add(label, tag, text = None, **kw):
+ me.e[tag] = me.table.info(label, text, **kw)
+ add('Implementation', 'implementation')
+ add('Version', 'version', newlinep = True)
+ me.update()
+ me.hook(me.mon.connecthook, me.update)
+ me.show_all()
+ def update(me):
+ info = parseinfo(me.mon.simplecmd('SERVINFO'))
+ for i in me.e:
+ me.e[i].set_text(info[i])
+
+class TraceOptions (MyDialog):
+ """Tracing options window."""
+ def __init__(me, monitor):
+ MyDialog.__init__(me, title = 'Tracing options',
+ buttons = [(G.STOCK_CLOSE, me.destroy),
+ (G.STOCK_OK, me.ok)])
+ me.mon = monitor
+ me.opts = []
+ for o in me.mon.simplecmd('TRACE'):
+ char = o[0]
+ onp = o[1]
+ text = o[3].upper() + o[4:]
+ if char.isupper(): continue
+ ticky = G.CheckButton(text)
+ ticky.set_active(onp != ' ')
+ me.vbox.pack_start(ticky)
+ me.opts.append((char, ticky))
+ me.show_all()
+ def ok(me):
+ on = []
+ off = []
+ for char, ticky in me.opts:
+ if ticky.get_active():
+ on.append(char)
+ else:
+ off.append(char)
+ setting = ''.join(on) + '-' + ''.join(off)
+ me.mon.simplecmd('TRACE %s' % setting)
+ me.destroy()
+
#----- Logging windows ------------------------------------------------------
class LogModel (G.ListStore):
me.add(scr)
me.show_all()
-def makeactiongroup(name, acts):
- """Creates an ActionGroup called NAME. ACTS is a list of tuples
- containing:
- ACT: an action name
- LABEL: the label string for the action
- ACCEL: accelerator string, or None
- FUNC: thunk to call when the action is invoked"""
- actgroup = G.ActionGroup(name)
- for act, label, accel, func in acts:
- a = G.Action(act, label, None, None)
- if func: a.connect('activate', invoker(func))
- actgroup.add_action_with_accel(a, accel)
- return actgroup
-
-class TraceOptions (MyDialog):
- """Tracing options window."""
- def __init__(me, monitor):
- MyDialog.__init__(me, title = 'Tracing options',
- buttons = [(G.STOCK_CLOSE, me.destroy),
- (G.STOCK_OK, me.ok)])
- me.mon = monitor
- me.opts = []
- for o in me.mon.simplecmd('TRACE'):
- char = o[0]
- onp = o[1]
- text = o[3].upper() + o[4:]
- if char.isupper(): continue
- ticky = G.CheckButton(text)
- ticky.set_active(onp != ' ')
- me.vbox.pack_start(ticky)
- me.opts.append((char, ticky))
- me.show_all()
- def ok(me):
- on = []
- off = []
- for char, ticky in me.opts:
- if ticky.get_active():
- on.append(char)
- else:
- off.append(char)
- setting = ''.join(on) + '-' + ''.join(off)
- me.mon.simplecmd('TRACE %s' % setting)
- me.destroy()
-
-def unimplemented(*hunoz):
- """Indicator of laziness."""
- moanbox("I've not written that bit yet.")
-
-class GridPacker (G.Table):
- """Like a Table, but with more state: makes filling in the widgets
- easier."""
- def __init__(me):
- G.Table.__init__(me)
- me.row = 0
- me.col = 0
- me.rows = 1
- me.cols = 1
- me.set_border_width(4)
- me.set_col_spacings(4)
- me.set_row_spacings(4)
- def pack(me, w, width = 1, newlinep = False,
- xopt = G.EXPAND | G.FILL | G.SHRINK, yopt = 0,
- xpad = 0, ypad = 0):
- """Packs a new widget. W is the widget to add. XOPY, YOPT, XPAD and
- YPAD are as for Table. WIDTH is how many cells to take up horizontally.
- NEWLINEP is whether to start a new line for this widget. Returns W."""
- if newlinep:
- me.row += 1
- me.col = 0
- bot = me.row + 1
- right = me.col + width
- if bot > me.rows or right > me.cols:
- if bot > me.rows: me.rows = bot
- if right > me.cols: me.cols = right
- me.resize(me.rows, me.cols)
- me.attach(w, me.col, me.col + width, me.row, me.row + 1,
- xopt, yopt, xpad, ypad)
- me.col += width
- return w
- def labelled(me, lab, w, newlinep = False, **kw):
- """Packs a labelled widget. Other arguments are as for pack. Returns
- W."""
- label = G.Label(lab)
- label.set_alignment(1.0, 0)
- me.pack(label, newlinep = newlinep, xopt = G.FILL)
- me.pack(w, **kw)
- return w
- def info(me, label, text = None, len = 18, **kw):
- e = G.Entry()
- if text is not None: e.set_text(text)
- e.set_width_chars(len)
- e.set_editable(False)
- me.labelled(label, e, **kw)
- return e
+#----- Peer window ----------------------------------------------------------
def xlate_time(t):
"""Translate a time in tripe's stats format to something a human might
s += '; %.2f ms (last %.1f ms)' % (ping.ttot/ping.ngood, ping.tlast);
me.e[ping.cmd].set_text(s)
+#----- Add peer -------------------------------------------------------------
+
class AddPeerCommand (SimpleBackgroundCommand):
def __init__(me, conn, dlg, name, addr, port,
keepalive = None, tunnel = None):
GDK.beep()
return
-class ServInfo (MyWindow):
- def __init__(me, monitor):
- MyWindow.__init__(me)
- me.set_title('TrIPE server info')
- me.mon = monitor
- me.table = GridPacker()
- me.add(me.table)
- me.e = {}
- def add(label, tag, text = None, **kw):
- me.e[tag] = me.table.info(label, text, **kw)
- add('Implementation', 'implementation')
- add('Version', 'version', newlinep = True)
- me.update()
- me.hook(me.mon.connecthook, me.update)
- me.show_all()
- def update(me):
- info = parseinfo(me.mon.simplecmd('SERVINFO'))
- for i in me.e:
- me.e[i].set_text(info[i])
+#----- The server monitor ---------------------------------------------------
class PingCommand (SimpleBackgroundCommand):
def __init__(me, conn, cmd, peer, func):
me.add(vbox)
me.ui = G.UIManager()
+ def cmd(c): me.mon.simplecmd(c)
actgroup = makeactiongroup('monitor',
[('file-menu', '_File', None, None),
('connect', '_Connect', '<Alt>C', me.mon.connect),
('disconnect', '_Disconnect', '<Alt>D', me.mon.disconnect),
('quit', '_Quit', '<Alt>Q', me.close),
('server-menu', '_Server', None, None),
- ('daemon', 'Run in _background', None,
- lambda: me.mon.simplecmd('DAEMON')),
- ('server-version', 'Server version', None, me.servinfo.open),
- ('server-quit', 'Terminate server', None,
- lambda: me.mon.simplecmd('QUIT')),
+ ('daemon', 'Run in _background', None, cmd('DAEMON')),
+ ('server-version', 'Server version', '<Alt>V', me.servinfo.open),
+ ('reload-keys', 'Reload keys', '<Alt>R', cmd('RELOAD')),
+ ('server-quit', 'Terminate server', None, cmd('QUIT')),
('logs-menu', '_Logs', None, None),
('show-warnings', 'Show _warnings', '<Alt>W', me.warnview.open),
('show-trace', 'Show _trace', '<Alt>T', me.traceview.open),
<menuitem action="quit"/>
</menu>
<menu action="server-menu">
- <menuitem action="connect"/>
+ <menuitem action="connect"/>
<menuitem action="disconnect"/>
<separator/>
+ <menuitem action="server-version"/>
<menuitem action="add-peer"/>
<menuitem action="daemon"/>
- <menuitem action="server-version"/>
+ <menuitem action="reload-keys"/>
<separator/>
<menuitem action="server-quit"/>
</menu>
if __name__ == '__main__':
main()
+#----- That's all, folks ----------------------------------------------------