commit 17d536657c43984665138ee131e77a6a291176d5 Author: Ravi Chandra Padmala neenaoffline@gmail.com Date: Wed Aug 22 23:45:49 2012 +0530
Add Controller.is_feature_enabled
Also made some minor modifications based on CR in #6417 --- stem/control.py | 41 +++++++++++++++++++++++++++---------- stem/version.py | 3 +- test/integ/control/controller.py | 8 +++++- 3 files changed, 38 insertions(+), 14 deletions(-)
diff --git a/stem/control.py b/stem/control.py index f2eb47a..8d59682 100644 --- a/stem/control.py +++ b/stem/control.py @@ -24,6 +24,7 @@ interacting at a higher level. |- set_options - sets or resets the values of multiple configuration options |- load_conf - loads configuration information as if it was in the torrc |- save_conf - saves configuration information to the torrc + |- is_feature_enabled - returns true if a given control connection feature is enabled |- enable_feature - enables control protocol features that have been disabled by default |- get_version - convenience method to get tor version |- authenticate - convenience method to authenticate the controller @@ -489,6 +490,7 @@ class Controller(BaseController):
# number of sequental 'GETINFO ip-to-country/*' lookups that have failed self._geoip_failure_count = 0 + self.enabled_features = []
def connect(self): super(Controller, self).connect() @@ -964,6 +966,28 @@ class Controller(BaseController): else: raise stem.socket.ProtocolError("SAVECONF returned unexpected response code")
+ def is_feature_enabled(self, feature): + """ + Checks if a control connection feature is enabled. These features can be + enabled using :func:`stem.control.Controller.enable_feature`. + + :param str feature: feature to be checked + + :returns: True if feature is enabled, False otherwise + """ + + defaulted_version = None + + if feature == "EXTENDED_EVENTS": + defaulted_version = stem.version.Requirement.EXTENDED_EVENTS_DEFAULTED + elif feature == "VERBOSE_NAMES": + defaulted_version = stem.version.Requirement.VERBOSE_NAMES_DEFAULTED + + if defaulted_version and self.get_version().meets_requirements(defaulted_version): + return True + else: + return feature in self.enabled_features + def enable_feature(self, features): """ Enables features that are disabled by default to maintain backward @@ -972,21 +996,14 @@ class Controller(BaseController): disabled. Feature names are case-insensitive.
The following features are currently accepted: - * EXTENDED_EVENTS - Requests the extended event syntax. Has the same - effect as calling SETEVENTS with EXTENDED. Introduced in - 0.1.2.3-alpha, always-on since Tor 0.2.2.1-alpha - * VERBOSE_NAMES - Replaces ServerID with LongName in events and GETINFO - results. LongName provides a Fingerprint for all routers, an indication - of Named status, and a Nickname if one is known. LongName is strictly - more informative than ServerID, which only provides either a Fingerprint - or a Nickname. Introduced in 0.1.2.2-alpha, always-on since Tor - 0.2.2.1-alpha. + * EXTENDED_EVENTS - Requests the extended event syntax + * VERBOSE_NAMES - Replaces ServerID with LongName in events and GETINFO results
:param str,list features: a single feature or a list of features to be enabled
:raises: - :class:`stem.socket.ControllerError` if the call fails - :class:`stem.socket.InvalidArguments` if features passed were invalid + * :class:`stem.socket.ControllerError` if the call fails + * :class:`stem.socket.InvalidArguments` if features passed were invalid """
if type(features) == str: features = [features] @@ -1000,6 +1017,8 @@ class Controller(BaseController): invalid_feature = [response.message[22:response.message.find(""", 22)]] raise stem.socket.InvalidArguments(response.code, response.message, invalid_feature) raise stem.socket.ProtocolError("USEFEATURE returned invalid response code") + + self.enabled_features = list(set(self.enabled_features).union(features))
def _case_insensitive_lookup(entries, key, default = UNDEFINED): """ diff --git a/stem/version.py b/stem/version.py index e17d63b..90cc997 100644 --- a/stem/version.py +++ b/stem/version.py @@ -249,6 +249,7 @@ Requirement = stem.util.enum.Enum( ("LOADCONF", Version("0.2.1.1")), ("TORRC_CONTROL_SOCKET", Version("0.2.0.30")), ("TORRC_DISABLE_DEBUGGER_ATTACHMENT", Version("0.2.3.9")), - ("FEATURE_VERBOSENAMES", Version("0.1.2.2-alpha")), + ("VERBOSE_NAMES_DEFAULTED", Version("0.2.2.1-alpha")), + ("EXTENDED_EVENTS_DEFAULTED", Version("0.2.2.1-alpha")), )
diff --git a/test/integ/control/controller.py b/test/integ/control/controller.py index 88ef642..ea91c8c 100644 --- a/test/integ/control/controller.py +++ b/test/integ/control/controller.py @@ -4,9 +4,10 @@ Integration tests for the stem.control.Controller class.
from __future__ import with_statement
+import re +import shutil import unittest import tempfile -import shutil
import stem.control import stem.socket @@ -327,8 +328,11 @@ class TestController(unittest.TestCase): runner = test.runner.get_runner()
with runner.get_tor_controller() as controller: - if test.runner.require_version(self, stem.version.Requirement.FEATURE_VERBOSENAMES): + if not test.runner.require_version(self, stem.version.Version("0.1.2.2-alpha")): controller.enable_feature("VERBOSE_NAMES") + self.assertTrue(re.match("$[0-9a-fA-F]{40}[~=].*", controller.get_info('orconn-status').split()[0])) + self.assertTrue(controller.is_feature_enabled("VERBOSE_NAMES")) + self.assertTrue("VERBOSE_NAMES" in controller.enabled_features) self.assertRaises(stem.socket.InvalidArguments, controller.enable_feature, ["NOT", "A", "FEATURE"]) try: controller.enable_feature(["NOT", "A", "FEATURE"])
tor-commits@lists.torproject.org