From 4d46a232b30be99bc34e581cbc636345f77c6bc4 Mon Sep 17 00:00:00 2001
From: David Robillard <d@drobilla.net>
Date: Wed, 9 May 2012 00:00:48 +0000
Subject: Persistent socket interface and interactive shell.

git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@4322 a436a847-0d15-0410-975c-d299462d15a1
---
 scripts/ingenish | 82 +++++++++++++++++++++++++++++++++-----------------------
 1 file changed, 48 insertions(+), 34 deletions(-)

(limited to 'scripts')

diff --git a/scripts/ingenish b/scripts/ingenish
index b88424ca..9e49c271 100755
--- a/scripts/ingenish
+++ b/scripts/ingenish
@@ -1,5 +1,5 @@
 #!/usr/bin/env python
-# Ingen Command-Line Interface
+# Ingen Interactive Shell
 # Copyright 2011-2012 David Robillard <http://drobilla.net>
 #
 # Permission to use, copy, modify, and/or distribute this software for any
@@ -15,13 +15,23 @@
 # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
 import os.path
+import shlex
 import socket
 import sys
 import time
 
+try:
+    import readline
+except:
+    pass
+
 class Client:
     def __init__(self, path='/tmp/ingen.sock'):
-        self.path = path
+        self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+        self.sock.connect(path)
+
+    def __del__(self):
+        self.sock.close()
 
     def msgencode(self, msg):
         if sys.version_info[0] == 3:
@@ -30,11 +40,8 @@ class Client:
             return msg
 
     def send(self, msg):
-        self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
-        self.sock.connect(self.path)
         self.sock.send(self.msgencode(msg))
         response = self.sock.recv(1024)
-        self.sock.close()
         if response != self.msgencode('OK'):
             print('Error: %s' % response)
             return False
@@ -93,7 +100,11 @@ class Client:
 
 def print_usage():
     print('''Usage: ingenish COMMAND [ARGUMENT]...
-A command line interface to an Ingen server.
+       ingenish
+
+A command line interface to an Ingen server.  A command can be given directly
+on the command line, or when run with no arguments an interactive shell is
+launched.
 
 Commands:
     put PATH TURTLE_FRAGMENT
@@ -101,6 +112,8 @@ Commands:
     connect TAIL_PATH HEAD_PATH
     disconnect TAIL_PATH HEAD_PATH
     delete PATH
+    help
+    exit
 
 Paths are UNIX-style paths with strict LV2 symbol components, e.g. /foo/bar_2.
 Turtle fragments are used verbatim as the body of blank nodes, the syntax is
@@ -117,36 +130,37 @@ Example:
     ingenish set /tone/output 'ingen:value 0.7'
 ''')
 
-def abort_if_num_args_less_than(num):
-    if len(sys.argv) < num:
-        print_usage()
-        sys.exit(1)
-
-abort_if_num_args_less_than(3)
 ingen = Client()
 
-cmd     = sys.argv[1]
-success = 0
-if cmd == 'put':
-    abort_if_num_args_less_than(3)
-    success = ingen.put(sys.argv[2], sys.argv[3])
-elif cmd == 'set':
-    abort_if_num_args_less_than(3)
-    success = ingen.set(sys.argv[2], sys.argv[3])
-elif cmd == 'connect':
-    abort_if_num_args_less_than(4)
-    success = ingen.connect(sys.argv[2], sys.argv[3])
-elif cmd == 'disconnect':
-    abort_if_num_args_less_than(4)
-    success = ingen.disconnect(sys.argv[2], sys.argv[3])
-elif cmd == 'delete':
-    success = ingen.delete(sys.argv[2])
-else:
-    print("error: Unknown command `%s'" % cmd)
-    print_usage()
-    sys.exit(1)
-
-if success:
+def run(cmd):
+    if cmd[0] == 'help':
+        print_usage()
+    elif cmd[0] == 'exit':
+        sys.exit(0)
+    elif cmd[0] == 'put' and len(cmd) == 3:
+        return ingen.put(cmd[1], cmd[2])
+    elif cmd[0] == 'set' and len(cmd) == 3:
+        return ingen.set(cmd[1], cmd[2])
+    elif cmd[0] == 'connect' and len(cmd) == 3:
+        return ingen.connect(cmd[1], cmd[2])
+    elif cmd[0] == 'disconnect' and len(cmd) == 3:
+        return ingen.disconnect(cmd[1], cmd[2])
+    elif cmd[0] == 'delete' and len(cmd) == 2:
+        return ingen.delete(cmd[1])
+    else:
+        return False
+
+if len(sys.argv) == 1:
+    while True:
+        try:
+            run(shlex.split(raw_input('> ')))
+        except (EOFError, KeyboardInterrupt, SystemExit):
+            print('')
+            break
+        except:
+            print('error: %s' % sys.exc_info()[0])
+elif run(sys.argv[1:]):
     sys.exit(0)
 else:
+    print_usage()
     sys.exit(1)
-- 
cgit v1.2.1