Rework prompt: add exception classes for errors and reload/quit
This commit is contained in:
parent
0d21b1fa2c
commit
fd6d9288f7
6 changed files with 89 additions and 19 deletions
|
@ -26,6 +26,7 @@ import sys
|
|||
import bot
|
||||
import prompt
|
||||
from prompt.builtins import load_file
|
||||
from prompt.reset import PromptReset
|
||||
import importer
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
@ -116,7 +117,13 @@ if __name__ == "__main__":
|
|||
print ("Nemubot v%s ready, my PID is %i!" % (bot.__version__,
|
||||
os.getpid()))
|
||||
context.start()
|
||||
while prmpt.run(context):
|
||||
while True:
|
||||
try:
|
||||
prmpt.run(context)
|
||||
except PromptReset as e:
|
||||
if e.type == "quit":
|
||||
break
|
||||
|
||||
try:
|
||||
# Reload context
|
||||
imp.reload(bot)
|
||||
|
|
|
@ -23,6 +23,8 @@ import shlex
|
|||
import sys
|
||||
import traceback
|
||||
|
||||
from .error import PromptError
|
||||
from .reset import PromptReset
|
||||
from . import builtins
|
||||
|
||||
|
||||
|
@ -30,12 +32,14 @@ class Prompt:
|
|||
|
||||
def __init__(self):
|
||||
self.selectedServer = None
|
||||
self.lastretcode = 0
|
||||
|
||||
self.HOOKS_CAPS = dict()
|
||||
self.HOOKS_LIST = dict()
|
||||
|
||||
def add_cap_hook(self, name, call, data=None):
|
||||
self.HOOKS_CAPS[name] = (lambda d, t, c, p: call(d, t, c, p), data)
|
||||
self.HOOKS_CAPS[name] = lambda t, c: call(t, data=data,
|
||||
context=c, prompt=self)
|
||||
|
||||
def add_list_hook(self, name, call):
|
||||
self.HOOKS_LIST[name] = call
|
||||
|
@ -77,13 +81,12 @@ class Prompt:
|
|||
"""
|
||||
|
||||
if toks[0] in builtins.CAPS:
|
||||
return builtins.CAPS[toks[0]](toks, context, self)
|
||||
self.lastretcode = builtins.CAPS[toks[0]](toks, context, self)
|
||||
elif toks[0] in self.HOOKS_CAPS:
|
||||
f, d = self.HOOKS_CAPS[toks[0]]
|
||||
return f(d, toks, context, self)
|
||||
self.lastretcode = self.HOOKS_CAPS[toks[0]](toks, context)
|
||||
else:
|
||||
print("Unknown command: `%s'" % toks[0])
|
||||
return ""
|
||||
self.lastretcode = 127
|
||||
|
||||
def getPS1(self):
|
||||
"""Get the PS1 associated to the selected server"""
|
||||
|
@ -99,14 +102,19 @@ class Prompt:
|
|||
context -- current bot context
|
||||
"""
|
||||
|
||||
ret = ""
|
||||
while ret != "quit" and ret != "reset" and ret != "refresh":
|
||||
while True: # Stopped by exception
|
||||
try:
|
||||
line = input("\033[0;33m%s§\033[0m " % self.getPS1())
|
||||
line = input("\033[0;33m%s\033[0;%dm§\033[0m " %
|
||||
(self.getPS1(), 31 if self.lastretcode else 32))
|
||||
cmds = self.lex_cmd(line.strip())
|
||||
for toks in cmds:
|
||||
try:
|
||||
ret = self.exec_cmd(toks, context)
|
||||
self.exec_cmd(toks, context)
|
||||
except PromptReset:
|
||||
raise
|
||||
except PromptError as e:
|
||||
print(e.message)
|
||||
self.lastretcode = 128
|
||||
except:
|
||||
exc_type, exc_value, exc_traceback = sys.exc_info()
|
||||
traceback.print_exception(exc_type, exc_value,
|
||||
|
@ -114,9 +122,8 @@ class Prompt:
|
|||
except KeyboardInterrupt:
|
||||
print("")
|
||||
except EOFError:
|
||||
ret = "quit"
|
||||
print("quit")
|
||||
return ret != "quit"
|
||||
raise PromptReset("quit")
|
||||
|
||||
|
||||
def hotswap(bak):
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
import logging
|
||||
|
||||
from .reset import PromptReset
|
||||
from tools.config import load_file
|
||||
|
||||
logger = logging.getLogger("nemubot.prompt.builtins")
|
||||
|
@ -26,12 +27,10 @@ logger = logging.getLogger("nemubot.prompt.builtins")
|
|||
def end(toks, context, prompt):
|
||||
"""Quit the prompt for reload or exit"""
|
||||
if toks[0] == "refresh":
|
||||
return "refresh"
|
||||
raise PromptReset("refresh")
|
||||
elif toks[0] == "reset":
|
||||
return "reset"
|
||||
else:
|
||||
context.quit()
|
||||
return "quit"
|
||||
raise PromptReset("reset")
|
||||
raise PromptReset("quit")
|
||||
|
||||
|
||||
def liste(toks, context, prompt):
|
||||
|
@ -58,8 +57,11 @@ def liste(toks, context, prompt):
|
|||
|
||||
else:
|
||||
print (" Unknown list `%s'" % l)
|
||||
return 2
|
||||
return 0
|
||||
else:
|
||||
print (" Please give a list to show: servers, ...")
|
||||
return 1
|
||||
|
||||
|
||||
def load(toks, context, prompt):
|
||||
|
@ -69,7 +71,7 @@ def load(toks, context, prompt):
|
|||
load_file(filename, context)
|
||||
else:
|
||||
print ("Not enough arguments. `load' takes a filename.")
|
||||
return
|
||||
return 1
|
||||
|
||||
|
||||
def select(toks, context, prompt):
|
||||
|
@ -80,9 +82,9 @@ def select(toks, context, prompt):
|
|||
prompt.selectedServer = context.servers[toks[1]]
|
||||
else:
|
||||
print ("select: server `%s' not found." % toks[1])
|
||||
return 1
|
||||
else:
|
||||
prompt.selectedServer = None
|
||||
return
|
||||
|
||||
|
||||
def unload(toks, context, prompt):
|
||||
|
@ -96,8 +98,10 @@ def unload(toks, context, prompt):
|
|||
print (" Module `%s' successfully unloaded." % name)
|
||||
else:
|
||||
print (" No module `%s' loaded, can't unload!" % name)
|
||||
return 2
|
||||
else:
|
||||
print ("Not enough arguments. `unload' takes a module name.")
|
||||
return 1
|
||||
|
||||
|
||||
def debug(toks, context, prompt):
|
||||
|
@ -112,8 +116,10 @@ def debug(toks, context, prompt):
|
|||
print (" Debug for module module `%s' disabled." % name)
|
||||
else:
|
||||
print (" No module `%s' loaded, can't debug!" % name)
|
||||
return 2
|
||||
else:
|
||||
print ("Not enough arguments. `debug' takes a module name.")
|
||||
return 1
|
||||
|
||||
|
||||
# Register build-ins
|
||||
|
|
23
prompt/error.py
Normal file
23
prompt/error.py
Normal file
|
@ -0,0 +1,23 @@
|
|||
# coding=utf-8
|
||||
|
||||
# Nemubot is a modulable IRC bot, built around XML configuration files.
|
||||
# Copyright (C) 2012 Mercier Pierre-Olivier
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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 Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
class PromptError(Exception):
|
||||
|
||||
def __init__(self, message):
|
||||
super(PromptError, self).__init__(message)
|
||||
self.message = message
|
23
prompt/reset.py
Normal file
23
prompt/reset.py
Normal file
|
@ -0,0 +1,23 @@
|
|||
# coding=utf-8
|
||||
|
||||
# Nemubot is a modulable IRC bot, built around XML configuration files.
|
||||
# Copyright (C) 2012 Mercier Pierre-Olivier
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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 Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
class PromptReset(Exception):
|
||||
|
||||
def __init__(self, type):
|
||||
super(PromptReset, self).__init__("Prompt reset asked")
|
||||
self.type = type
|
|
@ -69,6 +69,8 @@ class AbstractServer(io.IOBase):
|
|||
if not hasattr(self, "_open") or self._open():
|
||||
_rlist.append(self)
|
||||
_xlist.append(self)
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def close(self):
|
||||
|
@ -82,6 +84,8 @@ class AbstractServer(io.IOBase):
|
|||
_wlist.remove(self)
|
||||
if self in _xlist:
|
||||
_xlist.remove(self)
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
# Writes
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue