You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

191 lines
7.4 KiB

  1. """Command line client functionality, broken into a separate file
  2. so it can be more easily tested."""
  3. from __future__ import absolute_import
  4. from nilmdb.printf import *
  5. import nilmdb.client
  6. import time
  7. import sys
  8. import re
  9. import os
  10. import urlparse
  11. import argparse
  12. import fnmatch
  13. version = "0.1"
  14. class Cmdline(object):
  15. def __init__(self, argv):
  16. self.argv = argv
  17. def parse_opts(self):
  18. version_string = sprintf("nilmtool %s, client library %s",
  19. version, nilmdb.Client.client_version)
  20. formatter = argparse.ArgumentDefaultsHelpFormatter
  21. parser = argparse.ArgumentParser(add_help = False,
  22. formatter_class = formatter)
  23. group = parser.add_argument_group("General options")
  24. group.add_argument("-h", "--help", action='help',
  25. help='show this help message and exit')
  26. group.add_argument("-V", "--version", action="version",
  27. version=version_string)
  28. group = parser.add_argument_group("Server")
  29. group.add_argument("-u", "--url", action="store",
  30. default="http://localhost:12380/",
  31. help="NilmDB server URL (default: %(default)s)")
  32. sub = parser.add_subparsers(title="Commands",
  33. dest="command",
  34. description="Specify --help after the "
  35. "command for command-specific options.")
  36. # info
  37. cmd = sub.add_parser("info", help="Server information",
  38. formatter_class = formatter,
  39. description="""
  40. List information about the server, like
  41. version.
  42. """)
  43. cmd.set_defaults(handler = self.cmd_info)
  44. # list
  45. cmd = sub.add_parser("list", help="List streams",
  46. formatter_class = formatter,
  47. description="""
  48. List streams available in the database,
  49. optionally filtering by type or path. Wildcards
  50. are accepted.
  51. """)
  52. cmd.set_defaults(handler = self.cmd_list)
  53. group = cmd.add_argument_group("Stream filtering")
  54. group.add_argument("-t", "--type", default="*",
  55. help="Match only this stream type")
  56. group.add_argument("-p", "--path", default="*",
  57. help="Match only this path")
  58. # create
  59. cmd = sub.add_parser("create", help="Create a new stream",
  60. formatter_class = formatter,
  61. description="""
  62. Create a new empty stream at the
  63. specified path and with the specifed
  64. layout type.
  65. """)
  66. cmd.set_defaults(handler = self.cmd_create)
  67. group = cmd.add_argument_group("Required arguments")
  68. group.add_argument("path",
  69. help="Path of new stream, e.g. /foo/bar")
  70. group.add_argument("type",
  71. help="Layout type for new stream, e.g. RawData")
  72. # metadata
  73. cmd = sub.add_parser("metadata", help="Get or set stream metadata",
  74. description="""
  75. Get or set key=value metadata associated with
  76. a stream.
  77. """,
  78. usage="%(prog)s path [-g [key ...] | "
  79. "-s key=value [...] | -u key=value [...]]")
  80. cmd.set_defaults(handler = self.cmd_metadata)
  81. group = cmd.add_argument_group("Required arguments")
  82. group.add_argument("path",
  83. help="Path of stream, e.g. /foo/bar")
  84. group = cmd.add_argument_group("Actions")
  85. exc = group.add_mutually_exclusive_group()
  86. exc.add_argument("-g", "--get", nargs="*", metavar="key",
  87. help="Get metadata for specified keys (default all)")
  88. exc.add_argument("-s", "--set", nargs="+", metavar="key=value",
  89. help="Replace all metadata with provided "
  90. "key=value pairs")
  91. exc.add_argument("-u", "--update", nargs="+", metavar="key=value",
  92. help="Update metadata using provided "
  93. "key=value pairs")
  94. # parse it
  95. self.args = parser.parse_args(self.argv)
  96. def die(self, formatstr, *args):
  97. fprintf(sys.stderr, formatstr, *args)
  98. sys.exit(-1)
  99. def run(self):
  100. self.parse_opts()
  101. self.client = nilmdb.Client(self.args.url)
  102. # Make a test connection to make sure things work
  103. try:
  104. server_version = self.client.version()
  105. except nilmdb.client.NilmCommError as e:
  106. self.die("Error connecting to server: %s\n", str(e))
  107. # Now dispatch client request to appropriate function. Parser
  108. # should have ensured that we don't have any unknown commands
  109. # here.
  110. self.args.handler()
  111. def cmd_info(self):
  112. """Print info about the server"""
  113. printf("Client library version: %s\n", self.client.client_version)
  114. printf("Server version: %s\n", self.client.version())
  115. printf("Server URL: %s\n", self.client.geturl())
  116. printf("Server database: %s\n", self.client.dbpath())
  117. def cmd_list(self):
  118. """List available streams"""
  119. streams = self.client.stream_list()
  120. for (path, type) in streams:
  121. if (fnmatch.fnmatch(path, self.args.path) and
  122. fnmatch.fnmatch(type, self.args.type)):
  123. printf("%s %s\n", path, type)
  124. def cmd_create(self):
  125. """Create new stream"""
  126. try:
  127. self.client.stream_create(self.args.path, self.args.type)
  128. except nilmdb.client.ClientError as e:
  129. self.die("Error creating stream: %s\n", str(e))
  130. def cmd_metadata(self):
  131. """Manipulate metadata"""
  132. if self.args.set is not None or self.args.update is not None:
  133. # Either a set or an update
  134. if self.args.set is not None:
  135. keyvals = self.args.set
  136. handler = self.client.stream_set_metadata
  137. else:
  138. keyvals = self.args.update
  139. handler = self.client.stream_update_metadata
  140. # Extract key=value pairs
  141. data = {}
  142. for keyval in keyvals:
  143. kv = keyval.split('=', 1)
  144. if len(kv) != 2 or kv[0] == "":
  145. self.die("Error parsing key=value argument '%s'\n", keyval)
  146. data[kv[0]] = kv[1]
  147. # Make the call
  148. try:
  149. handler(self.args.path, data)
  150. except nilmdb.client.ClientError as e:
  151. self.die("Error setting/updating metadata: %s\n", str(e))
  152. else:
  153. # Get (or unspecified)
  154. keys = self.args.get or None
  155. try:
  156. data = self.client.stream_get_metadata(self.args.path, keys)
  157. except nilmdb.client.ClientError as e:
  158. self.die("Error getting metadata: %s\n", str(e))
  159. for key, value in sorted(data.items()):
  160. if value is None:
  161. value = ""
  162. printf("%s=%s\n", key, value)