mirror of https://github.com/nucypher/nucypher.git
Ursula command protocol contains fleet state, uses comon utilities.
parent
92d71a5531
commit
04c0db0b49
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue