|
- """Command line client functionality, broken into a separate file
- so it can be more easily tested."""
-
- from __future__ import absolute_import
- from nilmdb.printf import *
- import nilmdb.client
-
- import time
- import sys
- import re
- import os
- import urlparse
- import argparse
- import fnmatch
-
- version = "0.1"
-
- class Cmdline(object):
-
- def __init__(self, argv):
- self.argv = argv
-
- def parse_opts(self):
- version_string = sprintf("nilmtool %s, client library %s",
- version, nilmdb.Client.client_version)
-
- formatter = argparse.ArgumentDefaultsHelpFormatter
- parser = argparse.ArgumentParser(add_help = False,
- formatter_class = formatter)
-
- group = parser.add_argument_group("General options")
- group.add_argument("-h", "--help", action='help',
- help='show this help message and exit')
- group.add_argument("-V", "--version", action="version",
- version=version_string)
-
- group = parser.add_argument_group("Server")
- group.add_argument("-u", "--url", action="store",
- default="http://localhost:12380/",
- help="NilmDB server URL (default: %(default)s)")
-
- sub = parser.add_subparsers(title="Commands",
- dest="command",
- description="Specify --help after the "
- "command for command-specific options.")
-
- # info
- cmd = sub.add_parser("info", help="Server information",
- formatter_class = formatter,
- description="""
- List information about the server, like
- version.
- """)
- cmd.set_defaults(handler = self.cmd_info)
-
- # list
- cmd = sub.add_parser("list", help="List streams",
- formatter_class = formatter,
- description="""
- List streams available in the database,
- optionally filtering by type or path. Wildcards
- are accepted.
- """)
- cmd.set_defaults(handler = self.cmd_list)
- group = cmd.add_argument_group("Stream filtering")
- group.add_argument("-t", "--type", default="*",
- help="Match only this stream type")
- group.add_argument("-p", "--path", default="*",
- help="Match only this path")
-
- # create
- cmd = sub.add_parser("create", help="Create a new stream",
- formatter_class = formatter,
- description="""
- Create a new empty stream at the
- specified path and with the specifed
- layout type.
- """)
- cmd.set_defaults(handler = self.cmd_create)
- group = cmd.add_argument_group("Required arguments")
- group.add_argument("path",
- help="Path of new stream, e.g. /foo/bar")
- group.add_argument("type",
- help="Layout type for new stream, e.g. RawData")
-
- # metadata
- cmd = sub.add_parser("metadata", help="Get or set stream metadata",
- description="""
- Get or set key=value metadata associated with
- a stream.
- """,
- usage="%(prog)s path [-g [key ...] | "
- "-s key=value [...] | -u key=value [...]]")
- cmd.set_defaults(handler = self.cmd_metadata)
-
- group = cmd.add_argument_group("Required arguments")
- group.add_argument("path",
- help="Path of stream, e.g. /foo/bar")
-
- group = cmd.add_argument_group("Actions")
- exc = group.add_mutually_exclusive_group()
- exc.add_argument("-g", "--get", nargs="*", metavar="key",
- help="Get metadata for specified keys (default all)")
- exc.add_argument("-s", "--set", nargs="+", metavar="key=value",
- help="Replace all metadata with provided "
- "key=value pairs")
- exc.add_argument("-u", "--update", nargs="+", metavar="key=value",
- help="Update metadata using provided "
- "key=value pairs")
-
- # parse it
- self.args = parser.parse_args(self.argv)
-
- def die(self, formatstr, *args):
- fprintf(sys.stderr, formatstr, *args)
- sys.exit(-1)
-
- def run(self):
- self.parse_opts()
-
- self.client = nilmdb.Client(self.args.url)
-
- # Make a test connection to make sure things work
- try:
- server_version = self.client.version()
- except nilmdb.client.NilmCommError as e:
- self.die("Error connecting to server: %s\n", str(e))
-
- # Now dispatch client request to appropriate function. Parser
- # should have ensured that we don't have any unknown commands
- # here.
- self.args.handler()
-
- def cmd_info(self):
- """Print info about the server"""
- printf("Client library version: %s\n", self.client.client_version)
- printf("Server version: %s\n", self.client.version())
- printf("Server URL: %s\n", self.client.geturl())
- printf("Server database: %s\n", self.client.dbpath())
-
- def cmd_list(self):
- """List available streams"""
- streams = self.client.stream_list()
- for (path, type) in streams:
- if (fnmatch.fnmatch(path, self.args.path) and
- fnmatch.fnmatch(type, self.args.type)):
- printf("%s %s\n", path, type)
-
- def cmd_create(self):
- """Create new stream"""
- try:
- self.client.stream_create(self.args.path, self.args.type)
- except nilmdb.client.ClientError as e:
- self.die("Error creating stream: %s\n", str(e))
-
- def cmd_metadata(self):
- """Manipulate metadata"""
- if self.args.set is not None or self.args.update is not None:
- # Either a set or an update
- if self.args.set is not None:
- keyvals = self.args.set
- handler = self.client.stream_set_metadata
- else:
- keyvals = self.args.update
- handler = self.client.stream_update_metadata
-
- # Extract key=value pairs
- data = {}
- for keyval in keyvals:
- kv = keyval.split('=', 1)
- if len(kv) != 2 or kv[0] == "":
- self.die("Error parsing key=value argument '%s'\n", keyval)
- data[kv[0]] = kv[1]
-
- # Make the call
- try:
- handler(self.args.path, data)
- except nilmdb.client.ClientError as e:
- self.die("Error setting/updating metadata: %s\n", str(e))
- else:
- # Get (or unspecified)
- keys = self.args.get or None
- try:
- data = self.client.stream_get_metadata(self.args.path, keys)
- except nilmdb.client.ClientError as e:
- self.die("Error getting metadata: %s\n", str(e))
- for key, value in sorted(data.items()):
- if value is None:
- value = ""
- printf("%s=%s\n", key, value)
|