Ursula command protocol contains fleet state, uses comon utilities.

pull/562/head
Kieran Prasch 2018-11-22 10:16:10 -08:00
parent 92d71a5531
commit 04c0db0b49
No known key found for this signature in database
GPG Key ID: 199AB839D4125A62
1 changed files with 28 additions and 87 deletions

View File

@ -33,82 +33,29 @@ class UrsulaCommandProtocol(LineReceiver):
def __init__(self, ursula):
self.ursula = ursula
self.start_time = maya.now()
self.__history = deque(maxlen=10)
self.prompt = bytes('Ursula({}) >>> '.format(self.ursula.checksum_public_address[:9]), encoding='utf-8')
# Expose Ursula functional entry points
self.__commands = {
'stop': reactor.stop,
'known_nodes': self.paintKnownNodes,
'status': self.paintStatus,
'cycle_teacher': self.ursula.cycle_teacher_node,
'start_learning': self.ursula.start_learning_loop,
'stop_learning': self.ursula.stop_learning_loop
}
super().__init__()
def _paint_known_nodes(self):
# Gather Data
known_nodes = self.ursula.known_nodes
number_of_known_nodes = len(self.ursula.node_storage.all(federated_only=self.ursula.federated_only))
seen_nodes = len(self.ursula.node_storage.all(federated_only=self.ursula.federated_only, certificates_only=True))
# Operating Mode
federated_only = self.ursula.federated_only
if federated_only:
click.secho("Configured in Federated Only mode", fg='green')
# Heading
label = "Known Nodes (connected {} / seen {})".format(number_of_known_nodes, seen_nodes)
heading = '\n' + label + " " * (45 - len(label)) + "Last Seen "
click.secho(heading, bold=True, nl=False)
# Legend
color_index = {
'self': 'yellow',
'known': 'white',
'seednode': 'blue'
}
for node_type, color in color_index.items():
click.secho('{0:<6} | '.format(node_type), fg=color, nl=False)
click.echo('\n')
seednode_addresses = list(bn.checksum_address for bn in SEEDNODES)
for node in known_nodes:
row_template = "{} | {} | {} | {} | {}"
node_type = 'known'
if node.checksum_public_address == self.ursula.checksum_public_address:
node_type = 'self'
row_template += ' ({})'.format(node_type)
elif node.checksum_public_address in seednode_addresses:
node_type = 'seednode'
row_template += ' ({})'.format(node_type)
click.secho(row_template.format(node.checksum_public_address,
node.rest_url().ljust(20),
node.nickname.ljust(50),
node.timestamp,
node.last_seen,
), fg=color_index[node_type])
def paintKnownNodes(self):
from nucypher.cli.painting import paint_known_nodes
paint_known_nodes(ursula=self.ursula)
def paintStatus(self):
if self.ursula._learning_task.running:
learning_status = "Learning at {}s Intervals".format(self.ursula._learning_task.interval)
elif not self.ursula._learning_task.running:
learning_status = "Not Learning"
else:
learning_status = "Unknown"
if self.ursula._current_teacher_node:
teacher = 'Current Teacher ..... {}'.format(self.ursula._current_teacher_node)
else:
teacher = 'Current Teacher ..... No Teacher Connection'
stats = ['⇀URSULA {}'.format(self.ursula.nickname_icon),
'{}'.format(self.ursula),
'Uptime .............. {}'.format(maya.now() - self.start_time),
'Start Time .......... {}'.format(self.start_time.slang_time()),
'Fleet State ......... {2} {1} ({0})'.format(self.ursula.known_nodes.checksum[:7], self.ursula.known_nodes.nickname, self.ursula.known_nodes.icon),
'Learning Status ..... {}'.format(learning_status),
'Learning Round ...... Round #{}'.format(self.ursula._learning_round),
'Operating Mode ...... {}'.format('Federated' if self.ursula.federated_only else 'Decentralized'),
'Rest Interface ...... {}'.format(self.ursula.rest_url()),
'Node Storage Type ... {}'.format(self.ursula.node_storage._name.capitalize()),
'Known Nodes ......... {}'.format(len(self.ursula.known_nodes)),
'Work Orders ......... {}'.format(len(self.ursula._work_orders)),
teacher]
click.echo('\n' + '\n'.join(stats) + '\n')
from nucypher.cli.painting import paint_node_status
paint_node_status(ursula=self.ursula, start_time=self.start_time)
def connectionMade(self):
@ -123,29 +70,23 @@ class UrsulaCommandProtocol(LineReceiver):
self.transport.write(self.prompt)
def lineReceived(self, line):
"""Ursula REPL"""
"""Ursula Console REPL"""
# Read
line = line.decode(encoding=self.encoding).strip().lower()
commands = {
'known_nodes': self._paint_known_nodes,
'status': self.paintStatus,
'stop': reactor.stop,
'cycle_teacher': self.ursula.cycle_teacher_node,
'update_snapshot': self.ursula.update_snapshot,
'start_learning': self.ursula.start_learning_loop,
'stop_learning': self.ursula.stop_learning_loop
}
raw_line = line.decode(encoding=self.encoding)
line = raw_line.strip().lower()
# Evaluate
try:
commands[line]()
self.__commands[line]()
# Print
except KeyError:
if line:
click.secho("Invalid input. Options are {}".format(', '.join(commands)))
if line: # allow for empty string
click.secho("Invalid input. Options are {}".format(', '.join(self.__commands.keys())))
else:
self.__history.append(raw_line)
# Loop
self.transport.write(self.prompt)
self.transport.__write(self.prompt)