s4/net: Support parsing arguments in Python commands.
authorJelmer Vernooij <jelmer@samba.org>
Mon, 28 Dec 2009 12:53:18 +0000 (13:53 +0100)
committerJelmer Vernooij <jelmer@ganieda.vernstok.nl>
Tue, 29 Dec 2009 15:26:19 +0000 (16:26 +0100)
source4/scripting/python/samba/netcmd/__init__.py
source4/utils/net/net.c

index f644febba604f1096e3256ad159e27a659197dc2..16f19f8b24913e5c23f3585f56d0ef24eada8f31 100644 (file)
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #
 
+import optparse
+from samba import getopt as options, Ldb
+
+
+class Option(optparse.Option):
+    pass
+
+
 class Command(object):
     """A net command."""
 
     def _get_description(self):
-        return self.__doc__
+        return self.__doc__.splitlines()[-1].rstrip("\n")
+
+    def _get_name(self):
+        name = self.__class__.__name__
+        if name.startswith("cmd_"):
+            return name[4:]
+        return name
+
+    name = property(_get_name)
 
     def usage(self):
-        raise NotImplementedError
+        self.parser.print_usage()
 
     description = property(_get_description)
 
+    takes_args = []
+    takes_options = []
+
+    def __init__(self):
+        synopsis = self.name
+        if self.takes_args:
+            synopsis += " " + " ".join(self.takes_args)
+        self.parser = optparse.OptionParser(synopsis)
+        self.parser.add_options(self.takes_options)
+
+    def _run(self, *argv):
+        opts, args = self.parser.parse_args(list(argv))
+        return self.run(*args, **opts.__dict__)
+
     def run(self):
         """Run the command. This should be overriden by all subclasses."""
         raise NotImplementedError(self.run)
 
 
+class SuperCommand(Command):
+    """A command with subcommands."""
+
+    subcommands = {}
+
+    def run(self, subcommand, *args, **kwargs):
+        if not subcommand in subcommands:
+            print >>sys.stderr, "No such subcommand '%s'" % subcommand
+        return subcommands[subcommand].run(*args, **kwargs)
+
+    def usage(self, subcommand=None, *args, **kwargs):
+        if subcommand is None:
+            print "Available subcommands"
+            for subcommand in subcommands:
+                print "\t%s" % subcommand
+            return 0
+        else:
+            if not subcommand in subcommands:
+                print >>sys.stderr, "No such subcommand '%s'" % subcommand
+            return subcommands[subcommand].usage(*args, **kwargs)
+
+
+class FooCommand(Command):
+
+    def run(self, bar):
+        print "LALALA" + bar
+        return 0
+
 commands = {}
-commands["foo"] = Command()
+commands["foo"] = FooCommand()
index 298204b01f01bae0b514680032a96076a87bf630..31bade32a51f7d8172de7e89835efbb184c56a2b 100644 (file)
 #include <Python.h>
 #include "scripting/python/modules.h"
 
+static PyObject *py_tuple_from_argv(int argc, const char *argv[])
+{
+       PyObject *l;
+       Py_ssize_t i;
+
+       l = PyTuple_New(argc);
+       if (l == NULL) {
+               return NULL;
+       }
+
+       for (i = 0; i < argc; i++) {
+               PyTuple_SetItem(l, i, PyString_FromString(argv[i]));
+       }
+
+       return l;
+}
+
+static int py_call_with_string_args(PyObject *self, const char *method, int argc, const char *argv[])
+{
+       PyObject *ret, *args, *py_method;
+
+       args = py_tuple_from_argv(argc, argv);
+       if (args == NULL) {
+               PyErr_Print();
+               return 1;
+       }
+
+       py_method = PyObject_GetAttrString(self, method);
+       if (py_method == NULL) {
+               PyErr_Print();
+               return 1;
+       }       
+
+       ret = PyObject_CallObject(py_method, args);
+
+       Py_DECREF(args);
+
+       if (ret == NULL) {
+               PyErr_Print();
+               return 1;
+       }
+
+       return PyInt_AsLong(ret);
+}
+
 static PyObject *py_commands(void)
 {
        PyObject *netcmd_module, *py_cmds;
@@ -106,12 +151,8 @@ int net_run_function(struct net_context *ctx,
 
        py_cmd = PyDict_GetItemString(py_cmds, argv[0]);
        if (py_cmd != NULL) {
-               PyObject *ret = PyObject_CallMethod(py_cmd, "run", "");
-               if (ret == NULL) {
-                       PyErr_Print();
-                       return 1;
-               }
-               return PyInt_AsLong(ret);
+               return py_call_with_string_args(py_cmd, "_run", 
+                       argc-1, argv+1);
        }
 
        d_printf("No command: %s\n", argv[0]);
@@ -142,12 +183,8 @@ int net_run_usage(struct net_context *ctx,
 
        py_cmd = PyDict_GetItemString(py_cmds, argv[0]);
        if (py_cmd != NULL) {
-               PyObject *ret = PyObject_CallMethod(py_cmd, "usage", "");
-               if (ret == NULL) {
-                       PyErr_Print();
-                       return 1;
-               }
-               return PyInt_AsLong(ret);
+               return py_call_with_string_args(py_cmd, "usage", argc-1, 
+                                                argv+1);
        }
 
        d_printf("No usage information for command: %s\n", argv[0]);
@@ -218,9 +255,9 @@ static int net_help_python(void)
                }
                desc = PyString_AsString(py_desc);
                if (strlen(name) > 7) {
-                       d_printf("\t%s\t%s", name, desc);
+                       d_printf("\t%s\t%s\n", name, desc);
                } else {
-                       d_printf("\t%s\t\t%s", name, desc);
+                       d_printf("\t%s\t\t%s\n", name, desc);
                }
        }
        return 0;