def __init__(self, xyz): super(XYZPlugin, self).__init__(xyz) self.attr = lambda x: self.xyz.skin.get_palette(u"plugin.console", x) self._keys= ui.Keys() self._index = 1 self.output = [] self.edit = lowui.Edit(self.conf["prompt"], wrap="clip") self._input = lowui.AttrWrap(self.edit, self.attr("input")) self._header = lowui.AttrWrap(lowui.Text(_(u"Management console")), self.attr("header")) self._history = Queue(self.conf["history_depth"]) self.export(self.show)
def __init__(self, xyz, levels, lines=100): """ @param xyz: XYZ data @param levels: A list of levels to track @param lines: Max number of lines to be shown in logger console """ self.xyz = xyz try: self.lines = int(lines) except ValueError: pass self.loglevel = LogLevel() self.tracked_levels = self._calc_levels(levels) self._lines = lines self._data = Queue(self._lines) self._pending = [] self._set_internal_plugin()
class XYZPlugin(BasePlugin): "Plugin console" NAME = u"console" AUTHOR = u"Max E. Kuznecov <*****@*****.**>" VERSION = u"0.1" BRIEF_DESCRIPTION = _(u"Interactive management console") FULL_DESCRIPTION = _(u"Provides interactive management console") NAMESPACE = u"core" DOC = _(u"Configuration variables:\n"\ u"history_depth - Specifies how many entered "\ u"commands to keep. Default - 50\n"\ u"prompt - Command line prompt. Default - '> '") EVENTS = [(u"show", _(u"Fires upon showing console. Arguments: No.")), (u"cmd_prev", _(u"Fires when scrolling through history. "\ u"Arguments: Current command from history buffer")), (u"execute", _(u"Fires when typed command is to be executed. "\ u"Arguments: typed command")), ] def __init__(self, xyz): super(XYZPlugin, self).__init__(xyz) self.attr = lambda x: self.xyz.skin.get_palette(u"plugin.console", x) self._keys= ui.Keys() self._index = 1 self.output = [] self.edit = lowui.Edit(self.conf["prompt"], wrap="clip") self._input = lowui.AttrWrap(self.edit, self.attr("input")) self._header = lowui.AttrWrap(lowui.Text(_(u"Management console")), self.attr("header")) self._history = Queue(self.conf["history_depth"]) self.export(self.show) #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def show(self): """ Show console window """ def _get_cmd(k): """ Fetch previous command from history """ if k == self._keys.UP: _i = -1 else: _i = 1 _pos = len(self._history) - 1 + (self._index + _i) if _pos < 0: return None elif _pos > len(self._history): return None else: self._index += _i if _pos == len(self._history): return "" try: cmd = self._history[_pos] except Exception: return None else: return cmd #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ self.fire_event("show") _stop = False while True: walker = lowui.SimpleListWalker(self.output) walker.focus = len(walker) - 1 lbox = lowui.AttrWrap(lowui.ListBox(walker), self.attr("output")) console = lowui.Frame(lbox, header=self._header, footer=self._input, focus_part='footer') dim = self.xyz.screen.get_cols_rows() self.xyz.screen.draw_screen(dim, console.render(dim, True)) data = self.xyz.input.get() for k in data: if k in (self._keys.UP, self._keys.DOWN): cmd = _get_cmd(k) if cmd is not None: self.fire_event("cmd_prev", cmd) self.edit.set_edit_text("") self.edit.insert_text(cmd) elif k == self._keys.ENTER: self._index = 1 chunk = self.edit.get_edit_text() self.edit.set_edit_text("") compiled = None if not chunk: continue self._history.push(chunk) self._write("> %s" % chunk) try: compiled = compile(chunk, "<input>", "eval") except Exception, e: self._write(str(e)) break else: # Incomplete if compiled is None: break else: self.fire_event("execute", chunk) chunk = "" try: self._write( eval(compiled, dsl.XYZ.get_env())) except Exception, e: self._write(str(e)) elif k == self._keys.ESCAPE: _stop = True break else:
class Logger(object): """ Logger console is used to collect system messages. There are several message levels: PANIC: Critical error. ERROR: Non-critical error. WARNING: Warning. INFO: Informational message. DEBUG: Debug messages. ALL: All of the above. """ def __init__(self, xyz, levels, lines=100): """ @param xyz: XYZ data @param levels: A list of levels to track @param lines: Max number of lines to be shown in logger console """ self.xyz = xyz try: self.lines = int(lines) except ValueError: pass self.loglevel = LogLevel() self.tracked_levels = self._calc_levels(levels) self._lines = lines self._data = Queue(self._lines) self._pending = [] self._set_internal_plugin() #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def show_console(self): """ Show logger console """ # Queue is actually subclassed from list, but SimpleListWalker # checks arg type by type(), not by isinstance(), so cast explicitly _walker = lowui.SimpleListWalker(list(self._data)) _walker.focus = len(_walker) - 1 _dim = tuple([x - 2 for x in self.xyz.screen.get_cols_rows()]) uilib.XYZListBox(self.xyz, self.xyz.top, _walker, _(u"Logger console"), _dim).show() #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def log(self, msg, level=None): """ Add new message to log @param msg: Message @param level: Log level @type level: L{LogLevel} attribute """ if level is None: level = self.loglevel.UNKNOWN # Urwid is not yet inited, postpone if self.xyz.skin is None: self._pending.append((level, msg)) return _sel_attr = self.xyz.skin.attr(uilib.XYZListBox.resolution, u"selected") if self.tracked_levels & level: self._data.append(LogEntry(msg, self.loglevel.str_level(level), _sel_attr)) #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def process_pending(self): """ Process pending messages """ if self._pending: for l, m in self._pending: self.log(m, l) self._pending = [] #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ panic = lambda self, msg: self.log(msg, level=self.loglevel.PANIC) error = lambda self, msg: self.log(msg, level=self.loglevel.ERROR) warning = lambda self, msg: self.log(msg, level=self.loglevel.WARNING) info = lambda self, msg: self.log(msg, level=self.loglevel.INFO) debug = lambda self, msg: self.log(msg, level=self.loglevel.DEBUG) #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def clear(self): """ Clear log queue """ self._data.clear() #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def _calc_levels(self, level_list): """ Parse levels from config """ _level = self.loglevel.NONE for _lvl in level_list: _level |= _lvl return _level #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def _set_internal_plugin(self): """ Set own virtual plugin """ _logger_plugin = VirtualPlugin(self.xyz, u"logger") _logger_plugin.AUTHOR = u"Max E. Kuznecov <*****@*****.**>" _logger_plugin.VERSION = u"0.1" _logger_plugin.BRIEF_DESCRIPTION = _(u"Logger plugin") _logger_plugin.FULL_DESCRIPTION = re.sub(r"\ {2,}", r"", self.__doc__).strip() _logger_plugin.HOMEPAGE = u"xyzcmd.syhpoon.name" _logger_plugin.export(self.show_console) _logger_plugin.export(self.log) _logger_plugin.export(self.clear) self.xyz.pm.register(_logger_plugin)