pyterm: make Guido happy
This commit is contained in:
parent
73f6a0c518
commit
af24a947f6
176
dist/tools/pyterm/pyterm.py
vendored
176
dist/tools/pyterm/pyterm.py
vendored
@ -15,7 +15,8 @@
|
|||||||
#
|
#
|
||||||
# You should have received a copy of the GNU Lesser General Public
|
# You should have received a copy of the GNU Lesser General Public
|
||||||
# License along with this library; if not, write to the Free Software
|
# License along with this library; if not, write to the Free Software
|
||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
# 02110-1301 USA
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -24,16 +25,18 @@ except ImportError:
|
|||||||
import ConfigParser as configparser
|
import ConfigParser as configparser
|
||||||
|
|
||||||
|
|
||||||
import cmd, serial, socket, sys, threading, readline, time, logging, os, \
|
import cmd, serial, socket, sys, threading, readline, time, logging, \
|
||||||
argparse, re, codecs, signal
|
os, argparse, re, codecs, signal
|
||||||
|
|
||||||
### import twisted if available, define dummy classes otherwise
|
### import twisted if available, define dummy classes otherwise
|
||||||
try:
|
try:
|
||||||
from twisted.internet import reactor
|
from twisted.internet import reactor
|
||||||
from twisted.internet.protocol import Protocol, ReconnectingClientFactory
|
from twisted.internet.protocol import Protocol, \
|
||||||
|
ReconnectingClientFactory
|
||||||
except ImportError:
|
except ImportError:
|
||||||
logging.getLogger("").warn("Twisted not available, please install it if you"
|
logging.getLogger("").warn("Twisted not available, please install "
|
||||||
"want to use pyterm's JSON capabilities")
|
"it if you want to use pyterm's JSON "
|
||||||
|
"capabilities")
|
||||||
|
|
||||||
class Protocol():
|
class Protocol():
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@ -67,11 +70,12 @@ default_fmt_str = '%(asctime)s - %(levelname)s # %(message)s'
|
|||||||
class SerCmd(cmd.Cmd):
|
class SerCmd(cmd.Cmd):
|
||||||
"""Main class for pyterm based on Python's Cmd class.
|
"""Main class for pyterm based on Python's Cmd class.
|
||||||
|
|
||||||
Runs an interactive terminal that transfer between stdio and serial port.
|
Runs an interactive terminal that transfer between stdio and serial
|
||||||
|
port.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, port=None, baudrate=None, tcp_serial=None, confdir=None,
|
def __init__(self, port=None, baudrate=None, tcp_serial=None,
|
||||||
conffile=None, host=None, run_name=None):
|
confdir=None, conffile=None, host=None, run_name=None):
|
||||||
"""Constructor.
|
"""Constructor.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -123,7 +127,8 @@ class SerCmd(cmd.Cmd):
|
|||||||
|
|
||||||
### create Logging object
|
### create Logging object
|
||||||
my_millis = "{:.4f}".format(time.time())
|
my_millis = "{:.4f}".format(time.time())
|
||||||
date_str = '{}.{}'.format(time.strftime('%Y%m%d-%H:%M:%S'), my_millis[-4:])
|
date_str = '{}.{}'.format(time.strftime('%Y%m%d-%H:%M:%S'),
|
||||||
|
my_millis[-4:])
|
||||||
self.startup = date_str
|
self.startup = date_str
|
||||||
# create formatter
|
# create formatter
|
||||||
formatter = logging.Formatter(self.fmt_str)
|
formatter = logging.Formatter(self.fmt_str)
|
||||||
@ -131,8 +136,10 @@ class SerCmd(cmd.Cmd):
|
|||||||
directory = self.configdir + os.path.sep + self.host
|
directory = self.configdir + os.path.sep + self.host
|
||||||
if not os.path.exists(directory):
|
if not os.path.exists(directory):
|
||||||
os.makedirs(directory)
|
os.makedirs(directory)
|
||||||
logging.basicConfig(filename=directory + os.path.sep + self.run_name + '.log', \
|
logging.basicConfig(filename = directory + os.path.sep +
|
||||||
level=logging.DEBUG, format=self.fmt_str)
|
self.run_name + '.log',
|
||||||
|
level=logging.DEBUG,
|
||||||
|
format=self.fmt_str)
|
||||||
ch = logging.StreamHandler()
|
ch = logging.StreamHandler()
|
||||||
ch.setLevel(logging.DEBUG)
|
ch.setLevel(logging.DEBUG)
|
||||||
|
|
||||||
@ -152,13 +159,16 @@ class SerCmd(cmd.Cmd):
|
|||||||
|
|
||||||
# if no serial or TCP is specified use default serial port
|
# if no serial or TCP is specified use default serial port
|
||||||
if not self.port and not self.tcp_serial:
|
if not self.port and not self.tcp_serial:
|
||||||
sys.stderr.write("No port specified, using default (%s)!\n" % (defaultport))
|
sys.stderr.write("No port specified, using default (%s)!\n"
|
||||||
|
% (defaultport))
|
||||||
self.port = defaultport
|
self.port = defaultport
|
||||||
# if a TCP port is specified try to connect
|
# if a TCP port is specified try to connect
|
||||||
if self.tcp_serial:
|
if self.tcp_serial:
|
||||||
self.logger.info("Connect to localhost:%s" % self.tcp_serial)
|
self.logger.info("Connect to localhost:%s"
|
||||||
for res in socket.getaddrinfo('localhost', self.tcp_serial, \
|
% self.tcp_serial)
|
||||||
socket.AF_UNSPEC, socket.SOCK_STREAM):
|
for res in socket.getaddrinfo('localhost', self.tcp_serial,
|
||||||
|
socket.AF_UNSPEC,
|
||||||
|
socket.SOCK_STREAM):
|
||||||
af, socktype, proto, canonname, sa = res
|
af, socktype, proto, canonname, sa = res
|
||||||
try:
|
try:
|
||||||
s = fdsocket(af, socktype, proto)
|
s = fdsocket(af, socktype, proto)
|
||||||
@ -175,15 +185,16 @@ class SerCmd(cmd.Cmd):
|
|||||||
if s:
|
if s:
|
||||||
self.ser = s
|
self.ser = s
|
||||||
else:
|
else:
|
||||||
self.logger.error("Something went wrong connecting to localhost:%s"
|
self.logger.error("Something went wrong connecting to "
|
||||||
% self.tcp_serial)
|
"localhost:%s" % self.tcp_serial)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
# otherwise go for the serial port
|
# otherwise go for the serial port
|
||||||
elif self.port:
|
elif self.port:
|
||||||
self.logger.info("Connect to serial port %s" % self.port)
|
self.logger.info("Connect to serial port %s" % self.port)
|
||||||
self.serial_connect()
|
self.serial_connect()
|
||||||
|
|
||||||
# wait until connection is established and fire startup commands to the node
|
# wait until connection is established and fire startup
|
||||||
|
# commands to the node
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
for cmd in self.init_cmd:
|
for cmd in self.init_cmd:
|
||||||
self.logger.debug("WRITE ----->>>>>> '" + cmd + "'\n")
|
self.logger.debug("WRITE ----->>>>>> '" + cmd + "'\n")
|
||||||
@ -195,8 +206,8 @@ class SerCmd(cmd.Cmd):
|
|||||||
receiver_thread.start()
|
receiver_thread.start()
|
||||||
|
|
||||||
def precmd(self, line):
|
def precmd(self, line):
|
||||||
"""Check for command prefixes to distinguish between Pyterm interal
|
"""Check for command prefixes to distinguish between Pyterm
|
||||||
commands and commands that should be send to the node.
|
interal commands and commands that should be send to the node.
|
||||||
"""
|
"""
|
||||||
self.logger.debug("processing line #%s#" % line)
|
self.logger.debug("processing line #%s#" % line)
|
||||||
if (line.startswith("/")):
|
if (line.startswith("/")):
|
||||||
@ -204,16 +215,18 @@ class SerCmd(cmd.Cmd):
|
|||||||
return line
|
return line
|
||||||
|
|
||||||
def default(self, line):
|
def default(self, line):
|
||||||
"""In case of no Pyterm specific prefix is detected, split string by
|
"""In case of no Pyterm specific prefix is detected, split
|
||||||
colons and send it to the node.
|
string by colons and send it to the node.
|
||||||
"""
|
"""
|
||||||
self.logger.debug("%s is no pyterm command, sending to default out" % line)
|
self.logger.debug("%s is no pyterm command, sending to default "
|
||||||
|
"out" % line)
|
||||||
for tok in line.split(';'):
|
for tok in line.split(';'):
|
||||||
tok = self.get_alias(tok)
|
tok = self.get_alias(tok)
|
||||||
self.ser.write((tok.strip() + "\n").encode("utf-8"))
|
self.ser.write((tok.strip() + "\n").encode("utf-8"))
|
||||||
|
|
||||||
def do_help(self, line):
|
def do_help(self, line):
|
||||||
"""Do not use Cmd's internal help function, but redirect to the node.
|
"""Do not use Cmd's internal help function, but redirect to the
|
||||||
|
node.
|
||||||
"""
|
"""
|
||||||
self.ser.write("help\n".encode("utf-8"))
|
self.ser.write("help\n".encode("utf-8"))
|
||||||
|
|
||||||
@ -257,12 +270,14 @@ class SerCmd(cmd.Cmd):
|
|||||||
if not self.config.has_section("triggers"):
|
if not self.config.has_section("triggers"):
|
||||||
self.config.add_section("triggers")
|
self.config.add_section("triggers")
|
||||||
for trigger in self.triggers:
|
for trigger in self.triggers:
|
||||||
self.config.set("triggers", trigger.pattern, self.triggers[trigger])
|
self.config.set("triggers", trigger.pattern,
|
||||||
|
self.triggers[trigger])
|
||||||
if len(self.json_regs):
|
if len(self.json_regs):
|
||||||
if not self.config.has_section("json_regs"):
|
if not self.config.has_section("json_regs"):
|
||||||
self.config.add_section("json_regs")
|
self.config.add_section("json_regs")
|
||||||
for j in self.json_regs:
|
for j in self.json_regs:
|
||||||
self.config.set("json_regs", j, self.json_regs[j].pattern)
|
self.config.set("json_regs", j,
|
||||||
|
self.json_regs[j].pattern)
|
||||||
if len(self.filters):
|
if len(self.filters):
|
||||||
if not self.config.has_section("filters"):
|
if not self.config.has_section("filters"):
|
||||||
self.config.add_section("filters")
|
self.config.add_section("filters")
|
||||||
@ -285,7 +300,8 @@ class SerCmd(cmd.Cmd):
|
|||||||
self.config.set("init_cmd", "init_cmd%i" % i, ic)
|
self.config.set("init_cmd", "init_cmd%i" % i, ic)
|
||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
with open(self.configdir + os.path.sep + self.configfile, 'wb') as config_fd:
|
with open(self.configdir + os.path.sep + self.configfile, 'wb')\
|
||||||
|
as config_fd:
|
||||||
self.config.write(config_fd)
|
self.config.write(config_fd)
|
||||||
self.logger.info("Config saved")
|
self.logger.info("Config saved")
|
||||||
|
|
||||||
@ -296,18 +312,21 @@ class SerCmd(cmd.Cmd):
|
|||||||
print(str(key) + ": " + str(self.__dict__[key]))
|
print(str(key) + ": " + str(self.__dict__[key]))
|
||||||
|
|
||||||
def do_PYTERM_alias(self, line):
|
def do_PYTERM_alias(self, line):
|
||||||
"""Pyterm command: Register an alias or show an list of all registered aliases.
|
"""Pyterm command: Register an alias or show an list of all
|
||||||
|
registered aliases.
|
||||||
"""
|
"""
|
||||||
if line.endswith("list"):
|
if line.endswith("list"):
|
||||||
for alias in self.aliases:
|
for alias in self.aliases:
|
||||||
self.logger.info("{} = {}".format(alias, self.aliases[alias]))
|
self.logger.info("{} = {}".format(alias,
|
||||||
|
self.aliases[alias]))
|
||||||
return
|
return
|
||||||
if not line.count("="):
|
if not line.count("="):
|
||||||
sys.stderr.write("Usage: /alias <ALIAS> = <CMD>\n")
|
sys.stderr.write("Usage: /alias <ALIAS> = <CMD>\n")
|
||||||
return
|
return
|
||||||
alias = line.split('=')[0].strip()
|
alias = line.split('=')[0].strip()
|
||||||
command = line[line.index('=')+1:].strip()
|
command = line[line.index('=')+1:].strip()
|
||||||
self.logger.info("adding command %s for alias %s" % (command, alias))
|
self.logger.info("adding command %s for alias %s"
|
||||||
|
% (command, alias))
|
||||||
self.aliases[alias] = command
|
self.aliases[alias] = command
|
||||||
|
|
||||||
def do_PYTERM_rmalias(self, line):
|
def do_PYTERM_rmalias(self, line):
|
||||||
@ -332,7 +351,8 @@ class SerCmd(cmd.Cmd):
|
|||||||
return
|
return
|
||||||
trigger = line.split('=')[0].strip()
|
trigger = line.split('=')[0].strip()
|
||||||
action = line[line.index('=')+1:].strip()
|
action = line[line.index('=')+1:].strip()
|
||||||
self.logger.info("adding action %s for trigger %s" % (action, trigger))
|
self.logger.info("adding action %s for trigger %s" % (action,
|
||||||
|
trigger))
|
||||||
self.triggers[re.compile(trigger)] = action
|
self.triggers[re.compile(trigger)] = action
|
||||||
|
|
||||||
def do_PYTERM_rmtrigger(self, line):
|
def do_PYTERM_rmtrigger(self, line):
|
||||||
@ -372,9 +392,11 @@ class SerCmd(cmd.Cmd):
|
|||||||
sys.stderr.write("Filter for %s not found\n" % line.strip())
|
sys.stderr.write("Filter for %s not found\n" % line.strip())
|
||||||
|
|
||||||
def do_PYTERM_json(self, line):
|
def do_PYTERM_json(self, line):
|
||||||
"""Pyterm command: Transfer lines matching this Regex as JSON object.
|
"""Pyterm command: Transfer lines matching this Regex as JSON
|
||||||
|
object.
|
||||||
"""
|
"""
|
||||||
self.json_regs[line.split(' ')[0].strip()] = re.compile(line.partition(' ')[2].strip())
|
self.json_regs[line.split(' ')[0].strip()] = \
|
||||||
|
re.compile(line.partition(' ')[2].strip())
|
||||||
|
|
||||||
def do_PYTERM_unjson(self, line):
|
def do_PYTERM_unjson(self, line):
|
||||||
"""Pyterm command: Remove a JSON filter.
|
"""Pyterm command: Remove a JSON filter.
|
||||||
@ -383,7 +405,8 @@ class SerCmd(cmd.Cmd):
|
|||||||
sys.stderr.write("JSON regex with ID %s not found" % line)
|
sys.stderr.write("JSON regex with ID %s not found" % line)
|
||||||
|
|
||||||
def do_PYTERM_init(self, line):
|
def do_PYTERM_init(self, line):
|
||||||
"""Pyterm command: Add an startup command. (Only useful in addition with /save).
|
"""Pyterm command: Add an startup command. (Only useful in
|
||||||
|
addition with /save).
|
||||||
"""
|
"""
|
||||||
self.init_cmd.append(line.strip())
|
self.init_cmd.append(line.strip())
|
||||||
|
|
||||||
@ -391,25 +414,31 @@ class SerCmd(cmd.Cmd):
|
|||||||
"""Internal function to laod configuration from file.
|
"""Internal function to laod configuration from file.
|
||||||
"""
|
"""
|
||||||
self.config = configparser.SafeConfigParser()
|
self.config = configparser.SafeConfigParser()
|
||||||
self.config.read([self.configdir + os.path.sep + self.configfile])
|
self.config.read([self.configdir + os.path.sep + \
|
||||||
|
self.configfile])
|
||||||
|
|
||||||
for sec in self.config.sections():
|
for sec in self.config.sections():
|
||||||
if sec == "filters":
|
if sec == "filters":
|
||||||
for opt in self.config.options(sec):
|
for opt in self.config.options(sec):
|
||||||
self.filters.append(re.compile(self.config.get(sec, opt)))
|
self.filters.append(
|
||||||
|
re.compile(self.config.get(sec, opt)))
|
||||||
if sec == "ignores":
|
if sec == "ignores":
|
||||||
for opt in self.config.options(sec):
|
for opt in self.config.options(sec):
|
||||||
self.ignores.append(re.compile(self.config.get(sec, opt)))
|
self.ignores.append(
|
||||||
|
re.compile(self.config.get(sec, opt)))
|
||||||
if sec == "json_regs":
|
if sec == "json_regs":
|
||||||
for opt in self.config.options(sec):
|
for opt in self.config.options(sec):
|
||||||
self.logger.info("add json regex for %s" % self.config.get(sec, opt))
|
self.logger.info("add json regex for %s"
|
||||||
self.json_regs[opt] = re.compile(self.config.get(sec, opt))
|
% self.config.get(sec, opt))
|
||||||
|
self.json_regs[opt] = \
|
||||||
|
re.compile(self.config.get(sec, opt))
|
||||||
if sec == "aliases":
|
if sec == "aliases":
|
||||||
for opt in self.config.options(sec):
|
for opt in self.config.options(sec):
|
||||||
self.aliases[opt] = self.config.get(sec, opt)
|
self.aliases[opt] = self.config.get(sec, opt)
|
||||||
if sec == "triggers":
|
if sec == "triggers":
|
||||||
for opt in self.config.options(sec):
|
for opt in self.config.options(sec):
|
||||||
self.triggers[re.compile(opt)] = self.config.get(sec, opt)
|
self.triggers[re.compile(opt)] = \
|
||||||
|
self.config.get(sec, opt)
|
||||||
if sec == "init_cmd":
|
if sec == "init_cmd":
|
||||||
for opt in self.config.options(sec):
|
for opt in self.config.options(sec):
|
||||||
self.init_cmd.append(self.config.get(sec, opt))
|
self.init_cmd.append(self.config.get(sec, opt))
|
||||||
@ -419,7 +448,8 @@ class SerCmd(cmd.Cmd):
|
|||||||
self.__dict__[opt] = self.config.get(sec, opt)
|
self.__dict__[opt] = self.config.get(sec, opt)
|
||||||
|
|
||||||
def process_line(self, line):
|
def process_line(self, line):
|
||||||
"""Processes a valid line from node that should be printed and possibly forwarded.
|
"""Processes a valid line from node that should be printed and
|
||||||
|
possibly forwarded.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
line (str): input from node.
|
line (str): input from node.
|
||||||
@ -427,13 +457,16 @@ class SerCmd(cmd.Cmd):
|
|||||||
self.logger.info(line)
|
self.logger.info(line)
|
||||||
# check if line matches a trigger and fire the command(s)
|
# check if line matches a trigger and fire the command(s)
|
||||||
for trigger in self.triggers:
|
for trigger in self.triggers:
|
||||||
self.logger.debug("comparing input %s to trigger %s" % (line, trigger.pattern))
|
self.logger.debug("comparing input %s to trigger %s"
|
||||||
|
% (line, trigger.pattern))
|
||||||
m = trigger.search(line)
|
m = trigger.search(line)
|
||||||
if m:
|
if m:
|
||||||
self.onecmd(self.precmd(self.triggers[trigger]))
|
self.onecmd(self.precmd(self.triggers[trigger]))
|
||||||
|
|
||||||
# ckecking if the line should be sent as JSON object to a tcp server
|
# ckecking if the line should be sent as JSON object to a tcp
|
||||||
if (len(self.json_regs)) and self.factory and self.factory.myproto:
|
# server
|
||||||
|
if (len(self.json_regs)) and self.factory and \
|
||||||
|
self.factory.myproto:
|
||||||
for j in self.json_regs:
|
for j in self.json_regs:
|
||||||
m = self.json_regs[j].search(line)
|
m = self.json_regs[j].search(line)
|
||||||
if m:
|
if m:
|
||||||
@ -446,9 +479,11 @@ class SerCmd(cmd.Cmd):
|
|||||||
json_obj += '"date":%s, ' % int(time.time()*1000)
|
json_obj += '"date":%s, ' % int(time.time()*1000)
|
||||||
for g in m.groupdict():
|
for g in m.groupdict():
|
||||||
try:
|
try:
|
||||||
json_obj += '"%s":%d, ' % (g, int(m.groupdict()[g]))
|
json_obj += '"%s":%d, ' \
|
||||||
|
% (g, int(m.groupdict()[g]))
|
||||||
except ValueError:
|
except ValueError:
|
||||||
json_obj += '"%s":"%s", ' % (g, m.groupdict()[g])
|
json_obj += '"%s":"%s", ' \
|
||||||
|
% (g, m.groupdict()[g])
|
||||||
|
|
||||||
# eliminate the superfluous last ", "
|
# eliminate the superfluous last ", "
|
||||||
json_obj = json_obj[:-2]
|
json_obj = json_obj[:-2]
|
||||||
@ -457,7 +492,8 @@ class SerCmd(cmd.Cmd):
|
|||||||
self.factory.myproto.sendMessage(json_obj)
|
self.factory.myproto.sendMessage(json_obj)
|
||||||
|
|
||||||
def handle_line(self, line):
|
def handle_line(self, line):
|
||||||
"""Handle line from node and check for further processing requirements.
|
"""Handle line from node and check for further processing
|
||||||
|
requirements.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
line (str): input line from node.
|
line (str): input line from node.
|
||||||
@ -494,15 +530,18 @@ class SerCmd(cmd.Cmd):
|
|||||||
while (1):
|
while (1):
|
||||||
# check if serial port can be accessed.
|
# check if serial port can be accessed.
|
||||||
try:
|
try:
|
||||||
sr = codecs.getreader("UTF-8")(self.ser, errors='replace')
|
sr = codecs.getreader("UTF-8")(self.ser,
|
||||||
|
errors='replace')
|
||||||
c = sr.read(1)
|
c = sr.read(1)
|
||||||
# try to re-open it with a timeout of 1s otherwise
|
# try to re-open it with a timeout of 1s otherwise
|
||||||
except (serial.SerialException, ValueError) as se:
|
except (serial.SerialException, ValueError) as se:
|
||||||
self.logger.warn("Serial port disconnected, waiting to get reconnected...")
|
self.logger.warn("Serial port disconnected, waiting to "
|
||||||
|
"get reconnected...")
|
||||||
self.ser.close()
|
self.ser.close()
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
if os.path.exists(self.port):
|
if os.path.exists(self.port):
|
||||||
self.logger.warn("Try to reconnect to %s again..." % (self.port))
|
self.logger.warn("Try to reconnect to %s again..."
|
||||||
|
% (self.port))
|
||||||
self.serial_connect()
|
self.serial_connect()
|
||||||
continue
|
continue
|
||||||
if c == '\n' or c == '\r':
|
if c == '\n' or c == '\r':
|
||||||
@ -534,11 +573,13 @@ class PytermClientFactory(ReconnectingClientFactory):
|
|||||||
def clientConnectionLost(self, connector, reason):
|
def clientConnectionLost(self, connector, reason):
|
||||||
if reactor.running:
|
if reactor.running:
|
||||||
print('Lost connection. Reason:', reason)
|
print('Lost connection. Reason:', reason)
|
||||||
ReconnectingClientFactory.clientConnectionLost(self, connector, reason)
|
ReconnectingClientFactory.clientConnectionLost(self, connector,
|
||||||
|
reason)
|
||||||
|
|
||||||
def clientConnectionFailed(self, connector, reason):
|
def clientConnectionFailed(self, connector, reason):
|
||||||
print('Connection failed. Reason:', reason)
|
print('Connection failed. Reason:', reason)
|
||||||
ReconnectingClientFactory.clientConnectionFailed(self, connector,
|
ReconnectingClientFactory.clientConnectionFailed(self,
|
||||||
|
connector,
|
||||||
reason)
|
reason)
|
||||||
|
|
||||||
def __stop_reactor(signum, stackframe):
|
def __stop_reactor(signum, stackframe):
|
||||||
@ -552,29 +593,36 @@ class fdsocket(socket.socket):
|
|||||||
try:
|
try:
|
||||||
return self.sendall(string)
|
return self.sendall(string)
|
||||||
except socket.error as e:
|
except socket.error as e:
|
||||||
logging.getLogger("").warn("Error in TCP connection (%s), closing down" % str(e))
|
logging.getLogger("").warn("Error in TCP connection (%s), "
|
||||||
|
"closing down" % str(e))
|
||||||
self.close()
|
self.close()
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(description="Pyterm - The Python terminal program")
|
parser = argparse.ArgumentParser(description="Pyterm - The Python "
|
||||||
|
"terminal program")
|
||||||
parser.add_argument("-p", "--port",
|
parser.add_argument("-p", "--port",
|
||||||
help="Specifies the serial port to use, default is %s" % defaultport,
|
help="Specifies the serial port to use, default is %s"
|
||||||
|
% defaultport,
|
||||||
default=defaultport)
|
default=defaultport)
|
||||||
parser.add_argument("-ts", "--tcp-serial",
|
parser.add_argument("-ts", "--tcp-serial",
|
||||||
help="Connect to a TCP port instead of a serial port")
|
help="Connect to a TCP port instead of a serial port")
|
||||||
parser.add_argument("-b", "--baudrate",
|
parser.add_argument("-b", "--baudrate",
|
||||||
help="Specifies baudrate for the serial port, default is %s" % defaultbaud,
|
help="Specifies baudrate for the serial port, default is %s"
|
||||||
|
% defaultbaud,
|
||||||
default=defaultbaud)
|
default=defaultbaud)
|
||||||
parser.add_argument('-d', '--directory',
|
parser.add_argument('-d', '--directory',
|
||||||
help="Specify the Pyterm directory, default is %s" % defaultdir,
|
help="Specify the Pyterm directory, default is %s"
|
||||||
|
% defaultdir,
|
||||||
default=defaultdir)
|
default=defaultdir)
|
||||||
parser.add_argument("-c", "--config",
|
parser.add_argument("-c", "--config",
|
||||||
help="Specify the config filename, default is %s" % defaultfile,
|
help="Specify the config filename, default is %s"
|
||||||
|
% defaultfile,
|
||||||
default=defaultfile)
|
default=defaultfile)
|
||||||
parser.add_argument("-s", "--server",
|
parser.add_argument("-s", "--server",
|
||||||
help="Connect via TCP to this server to send output as JSON")
|
help="Connect via TCP to this server to send output as "
|
||||||
|
"JSON")
|
||||||
parser.add_argument("-P", "--tcp_port", type=int,
|
parser.add_argument("-P", "--tcp_port", type=int,
|
||||||
help="Port at the JSON server")
|
help="Port at the JSON server")
|
||||||
parser.add_argument("-H", "--host",
|
parser.add_argument("-H", "--host",
|
||||||
@ -583,15 +631,17 @@ if __name__ == "__main__":
|
|||||||
help="Run name, used for logfile")
|
help="Run name, used for logfile")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
myshell = SerCmd(args.port, args.baudrate, args.tcp_serial, args.directory, args.config, args.host, args.run_name)
|
myshell = SerCmd(args.port, args.baudrate, args.tcp_serial,
|
||||||
|
args.directory, args.config, args.host, args.run_name)
|
||||||
myshell.prompt = ''
|
myshell.prompt = ''
|
||||||
|
|
||||||
if args.server and args.tcp_port:
|
if args.server and args.tcp_port:
|
||||||
myfactory = PytermClientFactory()
|
myfactory = PytermClientFactory()
|
||||||
reactor.connectTCP(args.server, args.tcp_port, myfactory)
|
reactor.connectTCP(args.server, args.tcp_port, myfactory)
|
||||||
myshell.factory = myfactory
|
myshell.factory = myfactory
|
||||||
reactor.callInThread(myshell.cmdloop, "Welcome to pyterm!\nType '/exit' to exit.")
|
reactor.callInThread(myshell.cmdloop, "Welcome to pyterm!\n"
|
||||||
|
"Type '/exit' to exit.")
|
||||||
signal.signal(signal.SIGINT, __stop_reactor)
|
signal.signal(signal.SIGINT, __stop_reactor)
|
||||||
reactor.run()
|
reactor.run()
|
||||||
else:
|
else:
|
||||||
myshell.cmdloop("Welcome to pyterm!\nType 'exit' to exit.")
|
myshell.cmdloop("Welcome to pyterm!\nType '/exit' to exit.")
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user