openmedialibrary_platform/Shared/lib/python3.7/site-packages/stem/interpreter/help.py

147 lines
3.7 KiB
Python
Raw Permalink Normal View History

2018-12-15 00:08:54 +00:00
# Copyright 2014-2018, Damian Johnson and The Tor Project
2015-11-23 21:13:53 +00:00
# See LICENSE for licensing information
"""
Provides our /help responses.
"""
2018-12-15 00:08:54 +00:00
import stem.prereq
2015-11-23 21:13:53 +00:00
from stem.interpreter import (
STANDARD_OUTPUT,
BOLD_OUTPUT,
ERROR_OUTPUT,
msg,
uses_settings,
)
from stem.util.term import format
2018-12-15 00:08:54 +00:00
if stem.prereq._is_lru_cache_available():
2015-11-23 21:13:53 +00:00
from functools import lru_cache
2018-12-15 00:08:54 +00:00
else:
2015-11-23 21:13:53 +00:00
from stem.util.lru_cache import lru_cache
def response(controller, arg):
"""
Provides our /help response.
:param stem.control.Controller controller: tor control connection
:param str arg: controller or interpreter command to provide help output for
:returns: **str** with our help response
"""
# Normalizing inputs first so we can better cache responses.
return _response(controller, _normalize(arg))
def _normalize(arg):
arg = arg.upper()
# If there's multiple arguments then just take the first. This is
# particularly likely if they're trying to query a full command (for
# instance "/help GETINFO version")
arg = arg.split(' ')[0]
# strip slash if someone enters an interpreter command (ex. "/help /help")
if arg.startswith('/'):
arg = arg[1:]
return arg
@lru_cache()
@uses_settings
def _response(controller, arg, config):
if not arg:
return _general_help()
usage_info = config.get('help.usage', {})
if arg not in usage_info:
return format("No help information available for '%s'..." % arg, *ERROR_OUTPUT)
output = format(usage_info[arg] + '\n', *BOLD_OUTPUT)
description = config.get('help.description.%s' % arg.lower(), '')
for line in description.splitlines():
output += format(' ' + line, *STANDARD_OUTPUT) + '\n'
output += '\n'
if arg == 'GETINFO':
results = controller.get_info('info/names', None)
if results:
for line in results.splitlines():
if ' -- ' in line:
opt, summary = line.split(' -- ', 1)
output += format('%-33s' % opt, *BOLD_OUTPUT)
output += format(' - %s' % summary, *STANDARD_OUTPUT) + '\n'
elif arg == 'GETCONF':
results = controller.get_info('config/names', None)
if results:
options = [opt.split(' ', 1)[0] for opt in results.splitlines()]
for i in range(0, len(options), 2):
line = ''
for entry in options[i:i + 2]:
line += '%-42s' % entry
output += format(line.rstrip(), *STANDARD_OUTPUT) + '\n'
elif arg == 'SIGNAL':
signal_options = config.get('help.signal.options', {})
for signal, summary in signal_options.items():
output += format('%-15s' % signal, *BOLD_OUTPUT)
output += format(' - %s' % summary, *STANDARD_OUTPUT) + '\n'
elif arg == 'SETEVENTS':
results = controller.get_info('events/names', None)
if results:
entries = results.split()
# displays four columns of 20 characters
for i in range(0, len(entries), 4):
line = ''
for entry in entries[i:i + 4]:
line += '%-20s' % entry
output += format(line.rstrip(), *STANDARD_OUTPUT) + '\n'
elif arg == 'USEFEATURE':
results = controller.get_info('features/names', None)
if results:
output += format(results, *STANDARD_OUTPUT) + '\n'
elif arg in ('LOADCONF', 'POSTDESCRIPTOR'):
# gives a warning that this option isn't yet implemented
output += format(msg('msg.multiline_unimplemented_notice'), *ERROR_OUTPUT) + '\n'
return output.rstrip()
def _general_help():
lines = []
for line in msg('help.general').splitlines():
div = line.find(' - ')
if div != -1:
cmd, description = line[:div], line[div:]
lines.append(format(cmd, *BOLD_OUTPUT) + format(description, *STANDARD_OUTPUT))
else:
lines.append(format(line, *BOLD_OUTPUT))
return '\n'.join(lines)