commit b8e08ce69d30d10cfa6879b7205f62e988fea0e1 Author: Damian Johnson atagar@torproject.org Date: Tue May 8 09:53:13 2012 -0700
Helper function for parsing timestamp/intervals
Several extra-info descriptor lines are of the form... 'YYYY-MM-DD HH:MM:SS (NSEC s) *'
So making a helper function to parse it. Using it for the server descriptor's read/write-history entries and it improves code readability quite a bit... --- stem/descriptor/extrainfo_descriptor.py | 35 +++++++++++++++++++ stem/descriptor/server_descriptor.py | 57 ++++++++++++------------------ 2 files changed, 58 insertions(+), 34 deletions(-)
diff --git a/stem/descriptor/extrainfo_descriptor.py b/stem/descriptor/extrainfo_descriptor.py index e13787f..ca34ca1 100644 --- a/stem/descriptor/extrainfo_descriptor.py +++ b/stem/descriptor/extrainfo_descriptor.py @@ -21,6 +21,7 @@ ExtraInfoDescriptor - Tor extra-info descriptor. +- get_unrecognized_lines - lines with unrecognized content """
+import re import datetime
import stem.descriptor @@ -99,6 +100,40 @@ def parse_file(descriptor_file, validate = True): yield ExtraInfoDescriptor("".join(extrainfo_content), validate) else: break # done parsing file
+def _parse_timestamp_and_interval(keyword, content): + """ + Parses a 'YYYY-MM-DD HH:MM:SS (NSEC s) *' entry. + + Arguments: + keyword (str) - line's keyword + content (str) - line content to be parsed + + Returns: + tuple of the form... + (timestamp (datetime), interval (int), remaining content (str)) + + Raises: + ValueError if the content is malformed + """ + + line = "%s %s" % (keyword, content) + content_match = re.match("^(.*) (([0-9]+) s)( .*)?$", content) + + if not content_match: + raise ValueError("Malformed %s line: %s" % (keyword, line)) + + timestamp_str, interval, remainder = content_match.groups() + if remainder: remainder = remainder[1:] # remove leading space + + if not interval.isdigit(): + raise ValueError("%s line's interval wasn't a number: %s" % (keyword, line)) + + try: + timestamp = datetime.datetime.strptime(timestamp_str, "%Y-%m-%d %H:%M:%S") + return timestamp, int(interval), remainder + except ValueError: + raise ValueError("%s line's timestamp wasn't parseable: %s" % (keyword, line)) + class ExtraInfoDescriptor(stem.descriptor.Descriptor): """ Extra-info descriptor document. diff --git a/stem/descriptor/server_descriptor.py b/stem/descriptor/server_descriptor.py index 8513b86..2a9d72f 100644 --- a/stem/descriptor/server_descriptor.py +++ b/stem/descriptor/server_descriptor.py @@ -29,6 +29,7 @@ import hashlib import datetime
import stem.descriptor +import stem.descriptor.extrainfo_descriptor import stem.version import stem.util.connection import stem.util.tor_tools @@ -467,43 +468,31 @@ class ServerDescriptor(stem.descriptor.Descriptor): elif keyword == "eventdns": self.eventdns = value == "1" elif keyword in ("read-history", "write-history"): - is_read = keyword == "read-history" - - if is_read: self.read_history = value - else: self.write_history = value - - value_match = re.match("^(.*) (([0-9]+) s) (.*)$", value) - - if not value_match: - if not validate: continue - raise ValueError("Malformed %s line: %s" % (keyword, line)) - - end_value, interval_value, history_values = value_match.groups() - try: - end_datetime = datetime.datetime.strptime(end_value, "%Y-%m-%d %H:%M:%S") + timestamp, interval, remainder = \ + stem.descriptor.extrainfo_descriptor._parse_timestamp_and_interval(keyword, value)
- if is_read: self.read_history_end = end_datetime - else: self.write_history_end = end_datetime - except ValueError: - if validate: - raise ValueError("%s line's time wasn't parseable: %s" % (keyword, line)) - - if interval_value.isdigit(): - if is_read: self.read_history_interval = int(interval_value) - else: self.write_history_interval = int(interval_value) - elif validate: - raise ValueError("%s line's interval wasn't a number: %s" % (keyword, line)) - - if history_values != '': - for sampling in history_values.split(","): - if sampling.isdigit(): - if is_read: self.read_history_values.append(int(sampling)) - else: self.write_history_values.append(int(sampling)) + try: + if remainder: + history_values = [int(entry) for entry in remainder.split(",")] else: - if validate: - raise ValueError("%s line has non-numeric values: %s" % (keyword, line)) - else: break + history_values = [] + except ValueError: + raise ValueError("%s line has non-numeric values: %s" % (keyword, line)) + + if keyword == "read-history": + self.read_history = value + self.read_history_end = timestamp + self.read_history_interval = interval + self.read_history_values = history_values + else: + self.write_history = value + self.write_history_end = timestamp + self.write_history_interval = interval + self.write_history_values = history_values + except ValueError, exc: + if not validate: continue + else: raise exc else: self._unrecognized_lines.append(line)
tor-commits@lists.torproject.org