[or-cvs] r22616: {arm} Additional prep for release (updated change notes, spelling (in arm/trunk: . init interface/graphing util)

Damian Johnson atagar1 at gmail.com
Wed Jul 7 16:44:55 UTC 2010


Author: atagar
Date: 2010-07-07 16:44:54 +0000 (Wed, 07 Jul 2010)
New Revision: 22616

Modified:
   arm/trunk/ChangeLog
   arm/trunk/README
   arm/trunk/TODO
   arm/trunk/init/starter.py
   arm/trunk/interface/graphing/bandwidthStats.py
   arm/trunk/interface/graphing/psStats.py
   arm/trunk/util/conf.py
   arm/trunk/util/connections.py
   arm/trunk/util/log.py
   arm/trunk/util/panel.py
   arm/trunk/util/sysTools.py
   arm/trunk/util/torTools.py
   arm/trunk/util/uiTools.py
Log:
Additional prep for release (updated change notes, spelling corrections, and a few fixes thanks to pylint).



Modified: arm/trunk/ChangeLog
===================================================================
--- arm/trunk/ChangeLog	2010-07-07 15:11:54 UTC (rev 22615)
+++ arm/trunk/ChangeLog	2010-07-07 16:44:54 UTC (rev 22616)
@@ -1,5 +1,37 @@
 CHANGE LOG
 
+6/7/10 - version 1.3.6
+Rewrite of the first third of the interface, providing vastly improved performance, maintainability, and a few very nice features.
+
+    * added: settings are fetched from an optional armrc (update rates, controller password, caching, runlevels, etc)
+    * added: system tools util providing simplified usage, suppression of leaks to stdout, logging, and optional caching
+    * added: wrapper for accessing TorCtl providing:
+          o client side caching for commonly fetched relay information (fingerprint, descriptor, etc)
+          o singleton accessor and convenience functions, simplifying interface code
+          o wrapper allowing reattachment to new controllers (ie, arm still works if tor's stopped then restarted - still in the works)
+    * change: full rewrite of the header panel, providing:
+          o notice for when tor's disconnected (with time-stamp)
+          o lightweight redrawing (smarter caching and moved updating into a daemon thread)
+          o more graceful handling of tiny displays
+    * change: rewrite of graph panel and related stats, providing:
+          o prepopulation of bandwidth information from the state file if possible
+          o observed and measured bandwidth stats (requested by arma)
+          o graph can be configured to display any numeric ps stat
+          o third option for graphing bounds (restricting to both local minima and maxima)
+          o substantially reduced redraw rate and making use of cached ps parameters (reducing call volume)
+    * fix: preventing 'command unavailable' error messages from going to stdout, which disrupts the display (caught by sid77)
+    * fix: removed -p option due to being a gaping security problem (caught by ioerror and nickm)
+    * fix: crashing issue if TorCtl reports TorCtlClosed before the first refresh (caught by Tas)
+    * fix: preventing the connection panel from initiating or resetting while in blind mode (caught by micah)
+    * fix: ss resolution wasn't specifying the use of numeric ports (caught by data)
+    * fix: parsing error when ExitPolicy is undefined (caught by Paul Menzel)
+    * fix: revised sleep pattern used for threads, greatly reducing the time it takes to quit
+    * fix: bug in defaulting the connection resolver to something predetermined to be available
+    * fix: stopping connection resolution (and related failover message) when tor's stopped
+    * fix: crashing issue when trying to resolve addresses without network connectivity
+    * fix: forgot to join on connection resolver when quitting
+    * fix: revised calculation for effective bandwidth rate to take MaxAdvertisedBandwidth into account
+
 4/8/10 - version 1.3.5 (r22148)
 Utility and service rewrite (refactored roughly a third of the codebase, including revised APIs and much better documentation).
 

Modified: arm/trunk/README
===================================================================
--- arm/trunk/README	2010-07-07 15:11:54 UTC (rev 22615)
+++ arm/trunk/README	2010-07-07 16:44:54 UTC (rev 22616)
@@ -88,10 +88,11 @@
 ./
   arm       - startup script
   
-  ChangeLog - revision history
-  LICENSE   - copy of the gpl v3
-  README    - um... guess you figured this one out
-  TODO      - known issues, future plans, etc
+  armrc.sample - example arm configuration file with defaults
+  ChangeLog    - revision history
+  LICENSE      - copy of the gpl v3
+  README       - um... guess you figured this one out
+  TODO         - known issues, future plans, etc
   
   screenshot_page1.png
   screenshot_page2.png
@@ -102,16 +103,18 @@
     prereq.py  - checks python version and for required packages
   
   interface/
+    graphing/
+      __init__.py
+      graphPanel.py     - (page 1) presents graphs for data instances
+      bandwidthStats.py - tracks tor bandwidth usage
+      psStats.py        - tracks system information (by default cpu and memory usage)
+      connStats.py      - tracks number of tor connections
+    
     __init__.py
     controller.py          - main display loop, handling input and layout
     headerPanel.py         - top of all pages, providing general information
     
-    
-    graphPanel.py          - (page 1) presents graphs for data instances
-    bandwidthMonitor.py    - (graph data) tracks tor bandwidth usage
-    cpuMemMonitor.py       - (graph data) tracks tor cpu and memory usage
-    connCountMonitor.py    - (graph data) tracks number of tor connections
-    logPanel.py            - displays tor, arm, and torctl events
+    logPanel.py            - (page 1) displays tor, arm, and torctl events
     fileDescriptorPopup.py - (popup) displays file descriptors used by tor
     
     connPanel.py           - (page 2) displays information on tor connections
@@ -121,9 +124,12 @@
   
   util/
     __init__.py
+    conf.py        - loading and persistence for user configuration
     connections.py - service providing periodic connection lookups
     hostnames.py   - service providing nonblocking reverse dns lookups
     log.py         - aggregator for application events
     panel.py       - wrapper for safely working with curses subwindows
-    uiTools.py     - helper functions for interface
+    sysTools.py    - helper for system calls, providing client side caching
+    torTools.py    - wrapper for TorCtl, providing caching and derived information
+    uiTools.py     - helper functions for presenting the user interface
 

Modified: arm/trunk/TODO
===================================================================
--- arm/trunk/TODO	2010-07-07 15:11:54 UTC (rev 22615)
+++ arm/trunk/TODO	2010-07-07 16:44:54 UTC (rev 22616)
@@ -1,15 +1,13 @@
 TODO
 
-- Roadmap for next release (1.3.6)
+- Roadmap for next release (1.3.7)
   [ ] refactor panels
       Currently the interface is a bit of a rat's nest (especially the
       controller). The goal is to use better modularization to both simplify
       the codebase and make it possible to use smarter caching to improve
       performance (far too much is done in the ui logic). This work is in
-      progress - /init and /util are done and /interface is in progress. Known
+      progress - /init and /util are done and /interface is partly done. Known
       bugs are being fixed while refactoring.
-        [X] header panel
-        [X] graph panel
         [ ] log panel
           - option to clear log
           - allow home/end keys to jump to start/end
@@ -22,7 +20,7 @@
               Ie, make default "TOR/ARM NOTICE - ERR"
           - fetch text via getinfo rather than reading directly?
               conn.get_info("config-text")
-        [-] conn panel (for version 1.3.7)
+        [-] conn panel (for version 1.3.8)
           - check family connections to see if they're alive (VERSION cell
               handshake?)
           - fallback when pid or connection querying via pid is unavailable
@@ -32,11 +30,10 @@
           - connection uptime to associate inbound/outbound connections?
           - Identify controller connections (if it's arm, vidalia, etc) with
               special detail page for them
-        [-] controller (for version 1.3.7)
+        [-] controller (for version 1.3.8)
   [ ] provide performance ARM-DEBUG events
       Help with diagnosing performance bottlenecks. This is pending the
       codebase revisions to figure out the low hanging fruit for caching.
-  [X] user customizable armrc
   [ ] tor util
         [X] wrapper for accessing torctl
         [ ] allow arm to resume after restarting tor (attaching to a new torctl
@@ -114,8 +111,7 @@
       country, ISP, latency, exit policy for the circuit, traffic, etc
   * attempt to clear controller password from memory
       http://www.codexon.com/posts/clearing-passwords-in-memory-with-python
-  * try/catch check when starting for curses support?
-  * excaping function for uiTools' formatted strings
+  * escaping function for uiTools' formatted strings
   * tor-weather like functionality (email notices)
   * provide bridge / client country statistics
       - Include bridge related data via GETINFO option (feature request by
@@ -131,11 +127,11 @@
   * audit tor connections
       Provide warnings if tor misbehaves, checks possibly including:
         - ensuring ExitPolicyRejectPrivate is being obeyed
-        - check that ExitPolicy violations don't occure (not possible yet since
+        - check that ExitPolicy violations don't occur (not possible yet since
           not all relays aren't identified)
         - check that all connections are properly related to a circuit, for
           instance no outbound connections without a corresponding inbound (not
-          possible yet due to being unable to correlate connections to circuts)
+          possible yet due to being unable to correlate connections to circuits)
   * check file descriptors being accessed by tor to see if they're outside the
       known pattern
   * allow killing of circuits? Probably not useful...
@@ -173,7 +169,7 @@
     * vnstat, nload, mrtg, and traceroute
 
 - Ideas (low priority)
-  * python 3 compatability
+  * python 3 compatibility
       Currently blocked on TorCtl support.
   * bundle script that dumps relay stats to stdout
       Django has a small terminal coloring module that could be nice for

Modified: arm/trunk/init/starter.py
===================================================================
--- arm/trunk/init/starter.py	2010-07-07 15:11:54 UTC (rev 22615)
+++ arm/trunk/init/starter.py	2010-07-07 16:44:54 UTC (rev 22616)
@@ -25,8 +25,8 @@
 import util.uiTools
 import TorCtl.TorUtil
 
-VERSION = "1.3.5_dev"
-LAST_MODIFIED = "Apr 8, 2010"
+VERSION = "1.3.6_dev"
+LAST_MODIFIED = "July 7, 2010"
 
 DEFAULT_CONFIG = os.path.expanduser("~/.armrc")
 DEFAULTS = {"startup.controlPassword": None,

Modified: arm/trunk/interface/graphing/bandwidthStats.py
===================================================================
--- arm/trunk/interface/graphing/bandwidthStats.py	2010-07-07 15:11:54 UTC (rev 22615)
+++ arm/trunk/interface/graphing/bandwidthStats.py	2010-07-07 16:44:54 UTC (rev 22616)
@@ -4,7 +4,6 @@
 """
 
 import time
-from TorCtl import TorCtl
 
 import graphPanel
 from util import log, sysTools, torTools, uiTools
@@ -23,14 +22,13 @@
 
 DEFAULT_CONFIG = {"features.graph.bw.accounting.show": True, "features.graph.bw.accounting.rate": 10, "features.graph.bw.accounting.isTimeLong": False, "log.graph.bw.prepopulateSuccess": log.NOTICE, "log.graph.bw.prepopulateFailure": log.NOTICE}
 
-class BandwidthStats(graphPanel.GraphStats, TorCtl.PostEventListener):
+class BandwidthStats(graphPanel.GraphStats):
   """
   Uses tor BW events to generate bandwidth usage graph.
   """
   
   def __init__(self, config=None):
     graphPanel.GraphStats.__init__(self)
-    TorCtl.PostEventListener.__init__(self)
     
     self._config = dict(DEFAULT_CONFIG)
     if config:
@@ -271,16 +269,16 @@
       bwMeasured = conn.getMyBandwidthMeasured()
       
       if bwRate and bwBurst:
-        bwRate = uiTools.getSizeLabel(bwRate, 1)
-        bwBurst = uiTools.getSizeLabel(bwBurst, 1)
+        bwRateLabel = uiTools.getSizeLabel(bwRate, 1)
+        bwBurstLabel = uiTools.getSizeLabel(bwBurst, 1)
         
         # if both are using rounded values then strip off the ".0" decimal
-        if ".0" in bwRate and ".0" in bwBurst:
-          bwRate = bwRate.replace(".0", "")
-          bwBurst = bwBurst.replace(".0", "")
+        if ".0" in bwRateLabel and ".0" in bwBurstLabel:
+          bwRateLabel = bwRateLabel.replace(".0", "")
+          bwBurstLabel = bwBurstLabel.replace(".0", "")
         
-        stats.append("limit: %s" % bwRate)
-        stats.append("burst: %s" % bwBurst)
+        stats.append("limit: %s" % bwRateLabel)
+        stats.append("burst: %s" % bwBurstLabel)
       
       # Provide the observed bandwidth either if the measured bandwidth isn't
       # available or if the measured bandwidth is the observed (this happens

Modified: arm/trunk/interface/graphing/psStats.py
===================================================================
--- arm/trunk/interface/graphing/psStats.py	2010-07-07 15:11:54 UTC (rev 22615)
+++ arm/trunk/interface/graphing/psStats.py	2010-07-07 16:44:54 UTC (rev 22616)
@@ -6,7 +6,7 @@
 import graphPanel
 from util import log, sysTools, torTools, uiTools
 
-# number of subsiquent failed queries before giving up
+# number of subsequent failed queries before giving up
 FAILURE_THRESHOLD = 5
 
 # attempts to use cached results from the header panel's ps calls
@@ -21,7 +21,7 @@
   
   def __init__(self, config=None):
     graphPanel.GraphStats.__init__(self)
-    self.failedCount = 0      # number of subsiquent failed queries
+    self.failedCount = 0      # number of subsequent failed queries
     
     self._config = dict(DEFAULT_CONFIG)
     if config: config.update(self._config)
@@ -113,7 +113,7 @@
           result = float(psResults[statName])
           
           # The 'rss' and 'size' parameters provide memory usage in KB. This is
-          # scaled up to MB so the graph's y-high is a resonable value.
+          # scaled up to MB so the graph's y-high is a reasonable value.
           if statName in ("rss", "size"): result /= 1024.0
           
           if isPrimary: primary = result

Modified: arm/trunk/util/conf.py
===================================================================
--- arm/trunk/util/conf.py	2010-07-07 15:11:54 UTC (rev 22615)
+++ arm/trunk/util/conf.py	2010-07-07 16:44:54 UTC (rev 22616)
@@ -40,7 +40,7 @@
 
 class Config():
   """
-  Handler for easily working with custom configurations, providing persistance
+  Handler for easily working with custom configurations, providing persistence
   to and from files. All operations are thread safe.
   
   Parameters:
@@ -54,7 +54,7 @@
     Creates a new configuration instance.
     """
     
-    self.path = None        # path to the associated configuation file
+    self.path = None        # path to the associated configuration file
     self.contents = {}      # configuration key/value pairs
     self.contentsLock = threading.RLock()
     self.requestedKeys = set()
@@ -146,7 +146,7 @@
     Undefined values are left with their current values.
     
     Arguments:
-      confMappings - configuration key/value mappints to be revised
+      confMappings - configuration key/value mappings to be revised
     """
     
     for entry in confMappings.keys():
@@ -229,12 +229,12 @@
     already exists then merges as follows:
     - comments and file contents not in this config are left unchanged
     - lines with duplicate keys are stripped (first instance is kept)
-    - existing enries are overwritten with their new values, preserving the
-      positioning of inline comments if able
+    - existing entries are overwritten with their new values, preserving the
+      positioning of in-line comments if able
     - config entries not in the file are appended to the end in alphabetical
       order
     
-    If problems arise in writting (such as an unset path or insufficient
+    If problems arise in writing (such as an unset path or insufficient
     permissions) result in an IOError.
     
     Arguments:

Modified: arm/trunk/util/connections.py
===================================================================
--- arm/trunk/util/connections.py	2010-07-07 15:11:54 UTC (rev 22615)
+++ arm/trunk/util/connections.py	2010-07-07 16:44:54 UTC (rev 22616)
@@ -303,7 +303,7 @@
         # this logs in a couple of cases:
         # - special failures noted by getConnections (most cases are already
         # logged via sysTools)
-        # - note failovers for default resolution methods
+        # - note fail-overs for default resolution methods
         if str(exc).startswith("No results found using:"):
           log.log(CONFIG["log.connLookupFailed"], str(exc))
         
@@ -323,7 +323,7 @@
                 break
             
             if newResolver:
-              # provide notice that failures have occured and resolver is changing
+              # provide notice that failures have occurred and resolver is changing
               msg = RESOLVER_SERIAL_FAILURE_MSG % (CMD_STR[resolver], CMD_STR[newResolver])
               log.log(CONFIG["log.connLookupFailover"], msg)
             else:

Modified: arm/trunk/util/log.py
===================================================================
--- arm/trunk/util/log.py	2010-07-07 15:11:54 UTC (rev 22615)
+++ arm/trunk/util/log.py	2010-07-07 16:44:54 UTC (rev 22616)
@@ -69,9 +69,9 @@
   the backlog. If the level is None then this is a no-op.
   
   Arguments:
-    level     - runlevel coresponding to the message severity
+    level     - runlevel corresponding to the message severity
     msg       - string associated with the message
-    eventTime - unix time at which the event occured, current time if undefined
+    eventTime - unix time at which the event occurred, current time if undefined
   """
   
   if not level: return
@@ -96,7 +96,7 @@
           eventBacklog.insert(i + 1, newEvent)
           break
     
-    # turncates backlog if too long
+    # truncates backlog if too long
     toDelete = len(eventBacklog) - CONFIG["cache.armLog.size"]
     if toDelete >= 0: del eventBacklog[: toDelete + CONFIG["cache.armLog.trimSize"]]
     

Modified: arm/trunk/util/panel.py
===================================================================
--- arm/trunk/util/panel.py	2010-07-07 15:11:54 UTC (rev 22615)
+++ arm/trunk/util/panel.py	2010-07-07 16:44:54 UTC (rev 22616)
@@ -12,7 +12,7 @@
 CURSES_LOCK = RLock()
 
 # tags used by addfstr - this maps to functor/argument combinations since the
-# actual values (color attributes - grr...) might not yet be initialized
+# actual values (in the case of color attributes) might not yet be initialized
 def _noOp(arg): return arg
 FORMAT_TAGS = {"<b>": (_noOp, curses.A_BOLD),
                "<u>": (_noOp, curses.A_UNDERLINE),
@@ -31,7 +31,7 @@
     - locking when concurrently drawing to multiple windows
     - gracefully handle terminal resizing
     - clip text that falls outside the panel
-    - convenience methods for word wrap, inline formatting, etc
+    - convenience methods for word wrap, in-line formatting, etc
   
   This uses a design akin to Swing where panel instances provide their display
   implementation by overwriting the draw() method, and are redrawn with

Modified: arm/trunk/util/sysTools.py
===================================================================
--- arm/trunk/util/sysTools.py	2010-07-07 15:11:54 UTC (rev 22615)
+++ arm/trunk/util/sysTools.py	2010-07-07 16:44:54 UTC (rev 22616)
@@ -54,7 +54,7 @@
   """
   Convenience function for performing system calls, providing:
   - suppression of any writing to stdout, both directing stderr to /dev/null
-    and checking for the existance of commands before executing them
+    and checking for the existence of commands before executing them
   - logging of results (command issued, runtime, success/failure, etc)
   - optional exception suppression and caching (the max age for cached results
     is a minute)
@@ -73,7 +73,7 @@
   if cacheAge > 0:
     global CALL_CACHE, CONFIG
     
-    # keeps consistancy that we never use entries over a minute old (these
+    # keeps consistency that we never use entries over a minute old (these
     # results are 'dirty' and might be trimmed at any time)
     cacheAge = min(cacheAge, 60)
     cacheSize = CONFIG["cache.sysCalls.size"]

Modified: arm/trunk/util/torTools.py
===================================================================
--- arm/trunk/util/torTools.py	2010-07-07 15:11:54 UTC (rev 22615)
+++ arm/trunk/util/torTools.py	2010-07-07 16:44:54 UTC (rev 22616)
@@ -54,7 +54,7 @@
 def makeCtlConn(controlAddr="127.0.0.1", controlPort=9051):
   """
   Opens a socket to the tor controller and queries its authentication type,
-  raising an IOError if problems occure. The result of this function is a tuple
+  raising an IOError if problems occur. The result of this function is a tuple
   of the TorCtl connection and the authentication type, where the later is one
   of the following:
   "NONE"          - no authentication required
@@ -89,7 +89,7 @@
     # password authentication
     return (conn, "PASSWORD")
   elif authInfo.startswith("AUTH METHODS=COOKIE"):
-    # cookie authtication, parses authentication cookie path
+    # cookie authentication, parses authentication cookie path
     start = authInfo.find("COOKIEFILE=\"") + 12
     end = authInfo.find("\"", start)
     return (conn, "COOKIE=%s" % authInfo[start:end])
@@ -183,10 +183,10 @@
     return conn
   except Exception, exc:
     if passphrase and str(exc) == "Unable to authenticate: password incorrect":
-      # provide a warining that the provided password didn't work, then try
+      # provide a warning that the provided password didn't work, then try
       # again prompting for the user to enter it
       print INCORRECT_PASSWORD_MSG
-      return makeConn(controlAddr, controlPort)
+      return connect(controlAddr, controlPort)
     else:
       print exc
       return None
@@ -199,9 +199,9 @@
   2. "netstat -npl | grep 127.0.0.1:%s" % <tor control port>
   3. "ps -o pid -C tor"
   
-  If pidof or ps promide multiple tor instances then their results are discared
-  (since only netstat can differentiate using the control port). This provdes
-  None if either no running process exists or it can't be determined.
+  If pidof or ps provide multiple tor instances then their results are
+  discarded (since only netstat can differentiate using the control port). This
+  provides None if either no running process exists or it can't be determined.
   
   Arguments:
     controlPort - control port of the tor process if multiple exist
@@ -266,7 +266,7 @@
     self.controllerEvents = {}          # mapping of successfully set controller events to their failure level/msg
     self._isReset = False               # internal flag for tracking resets
     self._status = TOR_CLOSED           # current status of the attached control port
-    self._statusTime = 0                # unix timestamp for the duration of the status
+    self._statusTime = 0                # unix time-stamp for the duration of the status
     
     # cached getInfo parameters (None if unset or possibly changed)
     self._cachedParam = dict([(arg, "") for arg in CACHE_ARGS])
@@ -294,7 +294,7 @@
       self.conn.add_event_listener(self)
       for listener in self.eventListeners: self.conn.add_event_listener(listener)
       
-      # sets the events listened for by the new controller (incompatable events
+      # sets the events listened for by the new controller (incompatible events
       # are dropped with a logged warning)
       self.setControllerEvents(self.controllerEvents)
       
@@ -357,13 +357,13 @@
     """
     Queries the control port for the given GETINFO option, providing the
     default if the response fails for any reason (error response, control port
-    closed, ininitiated, etc).
+    closed, initiated, etc).
     
     Arguments:
       param       - GETINFO option to be queried
       default     - result if the query fails and exception's suppressed
       suppressExc - suppresses lookup errors (returning the default) if true,
-                    otherwises this raises the original exception
+                    otherwise this raises the original exception
     """
     
     self.connLock.acquire()
@@ -397,7 +397,7 @@
       multiple    - provides a list of results if true, otherwise this just
                     returns the first value
       suppressExc - suppresses lookup errors (returning the default) if true,
-                    otherwises this raises the original exception
+                    otherwise this raises the original exception
     """
     
     self.connLock.acquire()
@@ -441,7 +441,7 @@
   
   def getMyDescriptor(self, default = None):
     """
-    Provides the descrptor entry for this relay if available.
+    Provides the descriptor entry for this relay if available.
     
     Arguments:
       default - result if the query fails
@@ -529,7 +529,7 @@
   def getStatus(self):
     """
     Provides a tuple consisting of the control port's current status and unix
-    timestamp for when it became this way (zero if no status has yet to be
+    time-stamp for when it became this way (zero if no status has yet to be
     set).
     """
     
@@ -604,7 +604,7 @@
         unavailableEvents.update(events.intersection(FAILED_EVENTS))
         events.difference_update(FAILED_EVENTS)
       
-      # inital check for event availability
+      # initial check for event availability
       validEvents = self.getInfo("events/names")
       
       if validEvents:
@@ -863,7 +863,7 @@
   def _notifyStatusListeners(self, eventType):
     """
     Sends a notice to all current listeners that a given change in tor's
-    controller status has occured.
+    controller status has occurred.
     
     Arguments:
       eventType - enum representing tor's new status

Modified: arm/trunk/util/uiTools.py
===================================================================
--- arm/trunk/util/uiTools.py	2010-07-07 15:11:54 UTC (rev 22615)
+++ arm/trunk/util/uiTools.py	2010-07-07 16:44:54 UTC (rev 22616)
@@ -55,7 +55,7 @@
   Provides the msg constrained to the given length, truncating on word breaks.
   If the last words is long this truncates mid-word with an ellipse. If there
   isn't room for even a truncated single word (or one word plus the ellipse if
-  inlcuding those) then this provides an empty string. Examples:
+  including those) then this provides an empty string. Examples:
   
   cropStr("This is a looooong message", 17)
   "This is a looo..."
@@ -107,7 +107,7 @@
   """
   Converts byte count into label in its most significant units, for instance
   7500 bytes would return "7 KB". If the isLong option is used this expands
-  unit labels to be the properly pluralised full word (for instance 'Kilobytes'
+  unit labels to be the properly pluralized full word (for instance 'Kilobytes'
   rather than 'KB'). Units go up through PB.
   
   Example Usage:
@@ -130,7 +130,7 @@
   
   This defaults to presenting single character labels, but if the isLong option
   is used this expands labels to be the full word (space included and properly
-  pluralised). For instance, "4h" would be "4 hours" and "1m" would become
+  pluralized). For instance, "4h" would be "4 hours" and "1m" would become
   "1 minute".
   
   Example Usage:
@@ -196,7 +196,7 @@
       else:
         # unfortunately the %f formatting has no method of rounding down, so
         # reducing value to only concern the digits that are visible - note
-        # that this doesn't work with miniscule values (starts breaking down at
+        # that this doesn't work with minuscule values (starts breaking down at
         # around eight decimal places) or edge cases when working with powers
         # of two
         croppedCount = count - (count % (countPerUnit / (10 ** decimal)))



More information about the tor-commits mailing list