added some debug logging
[OpenSRF.git] / src / python / srfsh.py
index 3c9cff9..82daee2 100755 (executable)
@@ -1,11 +1,33 @@
-#!/usr/bin/python2.4
-import os, sys, time, readline, atexit, re
-from string import *
-from osrf.system import osrfConnect
-from osrf.json import *
-from osrf.ses import osrfClientSession
-from osrf.conf import osrfConfigValue
+#!/usr/bin/python
+# vim:et:ts=4
+"""
+srfsh.py - provides a basic shell for issuing OpenSRF requests
+
+  help
+    - show this menu
+
+  math_bench <count>
+    - runs <count> opensrf.math requests and reports the average time
+
+  request <service> <method> [<param1>, <param2>, ...]
+    - performs an opensrf request
+
+  set VAR=<value>
+    - sets an environment variable
 
+  Environment variables:
+    SRFSH_OUTPUT = pretty - print pretty JSON and key/value pairs for network objects
+                 = raw - print formatted JSON 
+
+    SRFSH_LOCALE = <locale> - request responses to be returned in locale <locale> if available
+"""
+
+import os, sys, time, readline, atexit, re
+import osrf.json
+import osrf.system
+import osrf.ses
+import osrf.conf
+import osrf.log
 
 # -------------------------------------------------------------------
 # main listen loop
@@ -18,9 +40,9 @@ def do_loop():
             line = raw_input("\033[01;32msrfsh\033[01;34m% \033[00m")
             if not len(line): 
                 continue
-            if lower(line) == 'exit' or lower(line) == 'quit': 
+            if str.lower(line) == 'exit' or str.lower(line) == 'quit': 
                 break
-            parts = split(line)
+            parts = str.split(line)
 
             command = parts[0]
         
@@ -60,9 +82,10 @@ def do_loop():
 # Set env variables to control behavior
 # -------------------------------------------------------------------
 def handle_set(parts):
-    m = re.compile('(.*)=(.*)').match(parts[0])
-    key = m.group(1)
-    val = m.group(2)
+    cmd = "".join(parts)
+    pattern = re.compile('(.*)=(.*)').match(cmd)
+    key = pattern.group(1)
+    val = pattern.group(2)
     set_var(key, val)
     print "%s = %s" % (key, val)
 
@@ -77,45 +100,26 @@ def handle_get(parts):
 # Prints help info
 # -------------------------------------------------------------------
 def handle_help():
-    print """
-  help
-    - show this menu
-
-  math_bench <count>
-    - runs <count> opensrf.math requests and reports the average time
-
-  request <service> <method> [<param1>, <param2>, ...]
-    - performs an opensrf request
-
-  set VAR=<value>
-    - sets an environment variable
-
-  Environment variables:
-    SRFSH_OUTPUT = pretty - print pretty JSON and key/value pairs for network objects
-                 = raw - print formatted JSON 
-    """
-
-        
-
+    print __doc__
 
 # -------------------------------------------------------------------
-# performs an opesnrf request
+# performs an opensrf request
 # -------------------------------------------------------------------
 def handle_request(parts):
     service = parts.pop(0)
     method = parts.pop(0)
-    jstr = '[%s]' % join(parts)
+    locale = __get_locale()
+    jstr = '[%s]' % "".join(parts)
     params = None
 
     try:
-        params = osrfJSONToObject(jstr)
+        params = osrf.json.to_object(jstr)
     except:
         print "Error parsing JSON: %s" % jstr
         return
 
-    ses = osrfClientSession(service)
+    ses = osrf.ses.ClientSession(service, locale=locale)
 
-    end = None
     start = time.time()
 
     req = ses.request2(method, tuple(params))
@@ -123,15 +127,16 @@ def handle_request(parts):
 
     while True:
         resp = req.recv(timeout=120)
-        if not end:
-            total = time.time() - start
-        if not resp: break
+        osrf.log.log_internal("Looping through receive request")
+        if not resp:
+            break
+        total = time.time() - start
 
         otp = get_var('SRFSH_OUTPUT')
         if otp == 'pretty':
-            print "\n" + osrfDebugNetworkObject(resp.content())
+            print "\n" + osrf.json.debug_net_object(resp.content())
         else:
-            print osrfFormatJSON(osrfObjectToJSON(resp.content()))
+            print osrf.json.pprint(osrf.json.to_json(resp.content()))
 
     req.cleanup()
     ses.cleanup()
@@ -144,16 +149,18 @@ def handle_request(parts):
 def handle_math_bench(parts):
 
     count = int(parts.pop(0))
-    ses = osrfClientSession('opensrf.math')
+    ses = osrf.ses.ClientSession('opensrf.math')
     times = []
 
-    for i in range(100):
-        if i % 10: sys.stdout.write('.')
-        else: sys.stdout.write( str( i / 10 ) )
-    print "";
+    for cnt in range(100):
+        if cnt % 10:
+            sys.stdout.write('.')
+        else:
+            sys.stdout.write( str( cnt / 10 ) )
+    print ""
 
 
-    for i in range(count):
+    for cnt in range(count):
     
         starttime = time.time()
         req = ses.request('add', 1, 2)
@@ -168,12 +175,13 @@ def handle_math_bench(parts):
             print "What happened? %s" % str(resp.content())
     
         req.cleanup()
-        if not ( (i+1) % 100):
-            print ' [%d]' % (i+1)
+        if not ( (cnt + 1) % 100):
+            print ' [%d]' % (cnt + 1)
     
     ses.cleanup()
     total = 0
-    for i in times: total += i
+    for cnt in times:
+        total += cnt 
     print "\naverage time %f" % (total / len(times))
 
 
@@ -215,14 +223,21 @@ def setup_readline():
 def do_connect():
     file = os.path.join(get_var('HOME'), ".srfsh.xml")
     print_green("Connecting to opensrf...")
-    osrfConnect(file, 'srfsh')
+    osrf.system.System.connect(config_file=file, config_context='srfsh')
     print_red('OK\n')
 
 def load_plugins():
     # Load the user defined external plugins
     # XXX Make this a real module interface, with tab-complete words, commands, etc.
-    plugins = osrfConfigValue('plugins')
-    plugins = osrfConfigValue('plugins.plugin')
+    try:
+        plugins = osrf.conf.get('plugins')
+
+    except:
+        # XXX standard srfsh.xml does not yet define <plugins> element
+        print_red("No plugins defined in /srfsh/plugins/plugin\n")
+        return
+
+    plugins = osrf.conf.get('plugins.plugin')
     if not isinstance(plugins, list):
         plugins = [plugins]
 
@@ -232,8 +247,8 @@ def load_plugins():
         print_green("Loading module %s..." % name)
 
         try:
-            str = 'from %s import %s\n%s()' % (name, init, init)
-            exec(str)
+            string = 'import %s\n%s.%s()' % (name, name, init)
+            exec(string)
             print_red('OK\n')
 
         except Exception, e:
@@ -243,37 +258,63 @@ def set_vars():
     if not get_var('SRFSH_OUTPUT'):
         set_var('SRFSH_OUTPUT', 'pretty')
 
+    # XXX Do we need to differ between LANG and LC_MESSAGES?
+    if not get_var('SRFSH_LOCALE'):
+        set_var('SRFSH_LOCALE', get_var('LC_ALL'))
 
 def set_var(key, val):
     os.environ[key] = val
 
-
 def get_var(key):
-    try: return os.environ[key]
-    except: return ''
+    return os.environ.get(key, '')
     
+def __get_locale():
+    """
+    Return the defined locale for this srfsh session.
+
+    A locale in OpenSRF is currently defined as a [a-z]{2}-[A-Z]{2} pattern.
+    This function munges the LC_ALL setting to conform to that pattern; for
+    example, trimming en_CA.UTF-8 to en-CA.
+
+    >>> import srfsh
+    >>> srfsh.set_var('SRFSH_LOCALE', 'zz-ZZ')
+    >>> print __get_locale()
+    zz-ZZ
+    >>> srfsh.set_var('SRFSH_LOCALE', 'en_CA.UTF-8')
+    >>> print __get_locale()
+    en-CA
+    """
+
+    env_locale = get_var('SRFSH_LOCALE')
+    if env_locale:
+        pattern = re.compile(r'^\s*([a-z]+)[^a-zA-Z]([A-Z]+)').search(env_locale)
+        lang = pattern.group(1)
+        region = pattern.group(2)
+        locale = "%s-%s" % (lang, region)
+    else:
+        locale = 'en-US'
+
+    return locale
     
-def print_green(str):
+def print_green(string):
     sys.stdout.write("\033[01;32m")
-    sys.stdout.write(str)
+    sys.stdout.write(string)
     sys.stdout.write("\033[00m")
     sys.stdout.flush()
 
-def print_red(str):
+def print_red(string):
     sys.stdout.write("\033[01;31m")
-    sys.stdout.write(str)
+    sys.stdout.write(string)
     sys.stdout.write("\033[00m")
     sys.stdout.flush()
 
 
+if __name__ == '__main__':
 
-
-# Kick it off
-set_vars()
-setup_readline()
-do_connect()
-load_plugins()
-do_loop()
-
-
+    # Kick it off
+    set_vars()
+    setup_readline()
+    do_connect()
+    load_plugins()
+    do_loop()