Example #1
0
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)
Example #2
0
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)
Example #3
0
  def run_command(self, command, config):
    """
    Runs the given command. Requests starting with a '/' are special commands
    to the interpreter, and anything else is sent to the control port.

    :param stem.control.Controller controller: tor control connection
    :param str command: command to be processed

    :returns: **list** out output lines, each line being a list of
      (msg, format) tuples

    :raises: **stem.SocketClosed** if the control connection has been severed
    """

    if not self._controller.is_alive():
      raise stem.SocketClosed()

    # Commands fall into three categories:
    #
    # * Interpretor commands. These start with a '/'.
    #
    # * Controller commands stem knows how to handle. We use our Controller's
    #   methods for these to take advantage of caching and present nicer
    #   output.
    #
    # * Other tor commands. We pass these directly on to the control port.

    cmd, arg = command.strip(), ''

    if ' ' in cmd:
      cmd, arg = cmd.split(' ', 1)

    output = ''

    if cmd.startswith('/'):
      cmd = cmd.lower()

      if cmd == '/quit':
        raise stem.SocketClosed()
      elif cmd == '/events':
        output = self.do_events(arg)
      elif cmd == '/info':
        output = self.do_info(arg)
      elif cmd == '/python':
        output = self.do_python(arg)
      elif cmd == '/help':
        output = self.do_help(arg)
      else:
        output = format("'%s' isn't a recognized command" % command, *ERROR_OUTPUT)
    else:
      cmd = cmd.upper()  # makes commands uppercase to match the spec

      if cmd.replace('+', '') in ('LOADCONF', 'POSTDESCRIPTOR'):
        # provides a notice that multi-line controller input isn't yet implemented
        output = format(msg('msg.multiline_unimplemented_notice'), *ERROR_OUTPUT)
      elif cmd == 'QUIT':
        self._controller.msg(command)
        raise stem.SocketClosed()
      else:
        is_tor_command = cmd in config.get('help.usage', {}) and cmd.lower() != 'events'

        if self._run_python_commands and not is_tor_command:
          self.is_multiline_context = code.InteractiveConsole.push(self, command)
          return
        else:
          try:
            output = format(self._controller.msg(command).raw_content().strip(), *STANDARD_OUTPUT)
          except stem.ControllerError as exc:
            if isinstance(exc, stem.SocketClosed):
              raise exc
            else:
              output = format(str(exc), *ERROR_OUTPUT)

    output += '\n'  # give ourselves an extra line before the next prompt

    return output
  def run_command(self, command, config):
    """
    Runs the given command. Requests starting with a '/' are special commands
    to the interpreter, and anything else is sent to the control port.

    :param stem.control.Controller controller: tor control connection
    :param str command: command to be processed

    :returns: **list** out output lines, each line being a list of
      (msg, format) tuples

    :raises: **stem.SocketClosed** if the control connection has been severed
    """

    if not self._controller.is_alive():
      raise stem.SocketClosed()

    # Commands fall into three categories:
    #
    # * Interpretor commands. These start with a '/'.
    #
    # * Controller commands stem knows how to handle. We use our Controller's
    #   methods for these to take advantage of caching and present nicer
    #   output.
    #
    # * Other tor commands. We pass these directly on to the control port.

    cmd, arg = command.strip(), ''

    if ' ' in cmd:
      cmd, arg = cmd.split(' ', 1)

    output = ''

    if cmd.startswith('/'):
      cmd = cmd.lower()

      if cmd == '/quit':
        raise stem.SocketClosed()
      elif cmd == '/events':
        output = self.do_events(arg)
      elif cmd == '/info':
        output = self.do_info(arg)
      elif cmd == '/python':
        output = self.do_python(arg)
      elif cmd == '/help':
        output = self.do_help(arg)
      else:
        output = format("'%s' isn't a recognized command" % command, *ERROR_OUTPUT)
    else:
      cmd = cmd.upper()  # makes commands uppercase to match the spec

      if cmd.replace('+', '') in ('LOADCONF', 'POSTDESCRIPTOR'):
        # provides a notice that multi-line controller input isn't yet implemented
        output = format(msg('msg.multiline_unimplemented_notice'), *ERROR_OUTPUT)
      elif cmd == 'QUIT':
        self._controller.msg(command)
        raise stem.SocketClosed()
      else:
        is_tor_command = cmd in config.get('help.usage', {}) and cmd.lower() != 'events'

        if self._run_python_commands and not is_tor_command:
          self.is_multiline_context = code.InteractiveConsole.push(self, command)
          return
        else:
          try:
            output = format(self._controller.msg(command).raw_content().strip(), *STANDARD_OUTPUT)
          except stem.ControllerError as exc:
            if isinstance(exc, stem.SocketClosed):
              raise exc
            else:
              output = format(str(exc), *ERROR_OUTPUT)

    output += '\n'  # give ourselves an extra line before the next prompt

    return output
Example #5
0
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()
Example #6
0
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()