[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [arm/master] Support for rendering unicode characters if able
commit f27c4c97a2abd0d89a235969ecee8ce77148ad9b
Author: Damian Johnson <atagar@xxxxxxxxxxxxxx>
Date: Fri May 20 19:52:11 2011 -0700
Support for rendering unicode characters if able
Checks for the multi-byte rendering type and curses wide character support,
providing a util for checking if unicode rendering will work and enabling it
if so.
---
armrc.sample | 3 ++
src/cli/controller.py | 8 +++++-
src/util/uiTools.py | 71 +++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 81 insertions(+), 1 deletions(-)
diff --git a/armrc.sample b/armrc.sample
index 9f75ccc..ecfe45a 100644
--- a/armrc.sample
+++ b/armrc.sample
@@ -19,6 +19,9 @@ queries.useProc true
# Renders the interface with color if set and the terminal supports it
features.colorInterface true
+# Includes unicode characters in the interface.
+features.printUnicode true
+
# Checks the torrc for issues, warning and hilighting problems if true
features.torrc.validate true
diff --git a/src/cli/controller.py b/src/cli/controller.py
index a1ec58a..8222da8 100644
--- a/src/cli/controller.py
+++ b/src/cli/controller.py
@@ -4,6 +4,7 @@ user input to the proper panels.
"""
import time
+import locale
import curses
import threading
@@ -18,7 +19,7 @@ import cli.graphing.connStats
import cli.graphing.resourceStats
import cli.connections.connPanel
-from util import connections, conf, enum, log, panel, sysTools, torConfig, torTools
+from util import connections, conf, enum, log, panel, sysTools, torConfig, torTools, uiTools
ARM_CONTROLLER = None
@@ -459,6 +460,11 @@ def drawTorMonitor(stdscr, startTime):
try: curses.curs_set(0)
except curses.error: pass
+ # If using our LANG variable for rendering multi-byte characters lets us
+ # get unicode support then then use it.
+ if uiTools.isUnicodeAvailable():
+ locale.setlocale(locale.LC_ALL, "")
+
# logs the initialization time
msg = "arm started (initialization took %0.3f seconds)" % (time.time() - startTime)
log.log(CONFIG["log.startTime"], msg)
diff --git a/src/util/uiTools.py b/src/util/uiTools.py
index b3b919a..0ff680e 100644
--- a/src/util/uiTools.py
+++ b/src/util/uiTools.py
@@ -5,6 +5,7 @@ easy method of providing the following interface components:
- unit conversion for labels
"""
+import os
import sys
import curses
@@ -35,8 +36,13 @@ TIME_UNITS = [(86400.0, "d", " day"), (3600.0, "h", " hour"),
Ending = enum.Enum("ELLIPSE", "HYPHEN")
SCROLL_KEYS = (curses.KEY_UP, curses.KEY_DOWN, curses.KEY_PPAGE, curses.KEY_NPAGE, curses.KEY_HOME, curses.KEY_END)
CONFIG = {"features.colorInterface": True,
+ "features.printUnicode": True,
"log.cursesColorSupport": log.INFO}
+# Flag indicating if unicode is supported by curses. If None then this has yet
+# to be determined.
+IS_UNICODE_SUPPORTED = None
+
def loadConfig(config):
config.update(CONFIG)
@@ -87,6 +93,29 @@ def _showGlyphs(stdscr):
stdscr.getch() # quit on keyboard input
+def isUnicodeAvailable():
+ """
+ True if curses has wide character support, false otherwise or if it can't be
+ determined.
+ """
+
+ global IS_UNICODE_SUPPORTED
+ if IS_UNICODE_SUPPORTED == None:
+ import sysTools
+
+ if CONFIG["features.printUnicode"]:
+ # Checks if our LANG variable is unicode. This is what will be respected
+ # when printing multi-byte characters after calling...
+ # locale.setlocale(locale.LC_ALL, '')
+ #
+ # so if the LANG isn't unicode then setting this would be pointless.
+
+ isLangUnicode = "utf-" in os.environ.get("LANG", "").lower()
+ IS_UNICODE_SUPPORTED = isLangUnicode and _isWideCharactersAvailable()
+ else: IS_UNICODE_SUPPORTED = False
+
+ return IS_UNICODE_SUPPORTED
+
def getPrintable(line, keepNewlines = True):
"""
Provides the line back with non-printable characters stripped.
@@ -606,6 +635,48 @@ def _getLabel(units, count, decimal, isLong):
return countLabel + longLabel + ("s" if isPlural else "")
else: return countLabel + shortLabel
+def _isWideCharactersAvailable():
+ """
+ True if curses has wide character support (which is required to print
+ unicode). False otherwise.
+ """
+
+ try:
+ # gets the dynamic library used by the interpretor for curses
+
+ import _curses
+ cursesLib = _curses.__file__
+
+ # Uses 'ldd' (Linux) or 'otool -L' (Mac) to determine the curses
+ # library dependencies.
+ #
+ # atagar@fenrir:~/Desktop$ ldd /usr/lib/python2.6/lib-dynload/_curses.so
+ # linux-gate.so.1 => (0x00a51000)
+ # libncursesw.so.5 => /lib/libncursesw.so.5 (0x00faa000)
+ # libpthread.so.0 => /lib/tls/i686/cmov/libpthread.so.0 (0x002f1000)
+ # libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0x00158000)
+ # libdl.so.2 => /lib/tls/i686/cmov/libdl.so.2 (0x00398000)
+ # /lib/ld-linux.so.2 (0x00ca8000)
+ #
+ # atagar$ otool -L /System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/lib-dynload/_curses.so
+ # /System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/lib-dynload/_curses.so:
+ # /usr/lib/libncurses.5.4.dylib (compatibility version 5.4.0, current version 5.4.0)
+ # /usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)
+ # /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 111.1.6)
+
+ libDependencyLines = None
+ if sysTools.isAvailable("ldd"):
+ libDependencyLines = sysTools.call("ldd %s" % cursesLib)
+ elif sysTools.isAvailable("otool"):
+ libDependencyLines = sysTools.call("otool -L %s" % cursesLib)
+
+ if libDependencyLines:
+ for line in libDependencyLines:
+ if "libncursesw" in line: return True
+ except: pass
+
+ return False
+
def _initColors():
"""
Initializes color mappings usable by curses. This can only be done after
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits