[tor-commits] [stem/master] Initial parts for an interpretor prompt
atagar at torproject.org
atagar at torproject.org
Tue May 6 01:21:12 UTC 2014
commit 95c1711c7982dd38689c3ffcb1ede2b32a4c13d9
Author: Damian Johnson <atagar at torproject.org>
Date: Sun Apr 6 11:29:18 2014 -0700
Initial parts for an interpretor prompt
Argument handling, connection, and authentication to tor. This presently
doesn't allow you to *do* anything. It's just a 'hello world' demo that prints
tor's version.
---
prompt | 23 +++-------
prompt_old | 19 ++++++++
stem/interpretor/__init__.py | 39 ++++++++++++++++
stem/interpretor/arguments.py | 100 +++++++++++++++++++++++++++++++++++++++++
4 files changed, 164 insertions(+), 17 deletions(-)
diff --git a/prompt b/prompt
index c1ba961..fc115a3 100755
--- a/prompt
+++ b/prompt
@@ -1,19 +1,8 @@
-#!/bin/sh
-#
-# Provides a quick method of getting a controller that we can use to test stem
-# with. This starts tor if it isn't already running and provides us with a
-# controller instance. When done it gives us the option to stop the tor.
-#
-# atagar at morrigan:~/Desktop/stem$ ./prompt
-# Welcome to stem's testing prompt. You currently have a controller available
-# via the 'controller' variable.
-#
-# >>> controller.get_info("version")
-# '0.2.1.30'
-# >>> quit()
-#
-# Would you like to stop the tor instance we made? (y/n, default: n): y
+#!/usr/bin/env python
+# Copyright 2014, Damian Johnson and The Tor Project
+# See LICENSE for licensing information
-python -i -c "import test.prompt; test.prompt.print_usage(); controller = test.prompt.controller()"
-python -c "import test.prompt; test.prompt.stop(True)"
+import stem.interpretor
+if __name__ == '__main__':
+ stem.interpretor.main()
diff --git a/prompt_old b/prompt_old
new file mode 100755
index 0000000..c1ba961
--- /dev/null
+++ b/prompt_old
@@ -0,0 +1,19 @@
+#!/bin/sh
+#
+# Provides a quick method of getting a controller that we can use to test stem
+# with. This starts tor if it isn't already running and provides us with a
+# controller instance. When done it gives us the option to stop the tor.
+#
+# atagar at morrigan:~/Desktop/stem$ ./prompt
+# Welcome to stem's testing prompt. You currently have a controller available
+# via the 'controller' variable.
+#
+# >>> controller.get_info("version")
+# '0.2.1.30'
+# >>> quit()
+#
+# Would you like to stop the tor instance we made? (y/n, default: n): y
+
+python -i -c "import test.prompt; test.prompt.print_usage(); controller = test.prompt.controller()"
+python -c "import test.prompt; test.prompt.stop(True)"
+
diff --git a/stem/interpretor/__init__.py b/stem/interpretor/__init__.py
new file mode 100644
index 0000000..ffe0012
--- /dev/null
+++ b/stem/interpretor/__init__.py
@@ -0,0 +1,39 @@
+# Copyright 2014, Damian Johnson and The Tor Project
+# See LICENSE for licensing information
+
+"""
+Interactive interpretor for interacting with Tor directly. This adds usability
+features such as tab completion, history, and IRC-style functions (like /help).
+"""
+
+__all__ = ['arguments']
+
+import sys
+
+import stem.connection
+import stem.interpretor.arguments
+
+def main():
+ try:
+ args = stem.interpretor.arguments.parse(sys.argv[1:])
+ except ValueError as exc:
+ print exc
+ sys.exit(1)
+
+ if args.print_help:
+ print stem.interpretor.arguments.get_help()
+ sys.exit()
+
+ control_port = None if args.user_provided_socket else (args.control_address, args.control_port)
+ control_socket = None if args.user_provided_port else args.control_socket
+
+ controller = stem.connection.connect(
+ control_port = control_port,
+ control_socket = control_socket,
+ )
+
+ if controller is None:
+ sys.exit(1)
+
+ with controller:
+ print controller.get_version()
diff --git a/stem/interpretor/arguments.py b/stem/interpretor/arguments.py
new file mode 100644
index 0000000..f7feac4
--- /dev/null
+++ b/stem/interpretor/arguments.py
@@ -0,0 +1,100 @@
+# Copyright 2014, Damian Johnson and The Tor Project
+# See LICENSE for licensing information
+
+"""
+Commandline argument parsing for arm.
+"""
+
+import collections
+import getopt
+
+DEFAULT_ARGS = {
+ 'control_address': '127.0.0.1',
+ 'control_port': 9051,
+ 'user_provided_port': False,
+ 'control_socket': '/var/run/tor/control',
+ 'user_provided_socket': False,
+ 'print_help': False,
+}
+
+OPT = 'i:s:h'
+
+OPT_EXPANDED = [
+ 'interface=',
+ 'socket=',
+ 'help',
+]
+
+HELP_OUTPUT = """
+Usage prompt [OPTION]
+Interactive interpretor for Tor.
+
+ -i, --interface [ADDRESS:]PORT change control interface from {address}:{port}
+ -s, --socket SOCKET_PATH attach using unix domain socket if present,
+ SOCKET_PATH defaults to: {socket}
+ -h, --help presents this help
+
+Example:
+prompt -i 1643 attach to control port 1643
+prompt -s ~/.tor/socket attach to a control socket in your home directory
+"""
+
+def parse(argv):
+ """
+ Parses our arguments, providing a named tuple with their values.
+
+ :param list argv: input arguments to be parsed
+
+ :returns: a **named tuple** with our parsed arguments
+
+ :raises: **ValueError** if we got an invalid argument
+ """
+
+ args = dict(DEFAULT_ARGS)
+
+ try:
+ getopt_results = getopt.getopt(argv, OPT, OPT_EXPANDED)[0]
+ except getopt.GetoptError as exc:
+ raise ValueError(msg('usage.invalid_arguments', error = exc))
+
+ for opt, arg in getopt_results:
+ if opt in ('-i', '--interface'):
+ if ':' in arg:
+ address, port = arg.split(':', 1)
+ else:
+ address, port = None, arg
+
+ if address is not None:
+ if not stem.util.connection.is_valid_ipv4_address(address):
+ raise ValueError(msg('usage.not_a_valid_address', address_input = address))
+
+ args['control_address'] = address
+
+ if not stem.util.connection.is_valid_port(port):
+ raise ValueError(msg('usage.not_a_valid_port', port_input = port))
+
+ args['control_port'] = int(port)
+ args['user_provided_port'] = True
+ elif opt in ('-s', '--socket'):
+ args['control_socket'] = arg
+ args['user_provided_socket'] = True
+ elif opt in ('-h', '--help'):
+ args['print_help'] = True
+
+ # translates our args dict into a named tuple
+
+ Args = collections.namedtuple('Args', args.keys())
+ return Args(**args)
+
+def get_help():
+ """
+ Provides our --help usage information.
+
+ :returns: **str** with our usage information
+ """
+
+ return HELP_OUTPUT.format(
+ address = DEFAULT_ARGS['control_address'],
+ port = DEFAULT_ARGS['control_port'],
+ socket = DEFAULT_ARGS['control_socket'],
+ ).strip()
More information about the tor-commits
mailing list