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.
 
 
 

105 lines
3.6 KiB

  1. """Command line client functionality"""
  2. import nilmdb.client
  3. from nilmdb.utils.printf import *
  4. from nilmdb.utils import datetime_tz
  5. import nilmdb.utils.time
  6. import sys
  7. import os
  8. import argparse
  9. from argparse import ArgumentDefaultsHelpFormatter as def_form
  10. # Valid subcommands. Defined in separate files just to break
  11. # things up -- they're still called with Cmdline as self.
  12. subcommands = [ "help", "info", "create", "list", "metadata",
  13. "insert", "extract", "remove", "destroy" ]
  14. # Import the subcommand modules
  15. subcmd_mods = {}
  16. for cmd in subcommands:
  17. subcmd_mods[cmd] = __import__("nilmdb.cmdline." + cmd, fromlist = [ cmd ])
  18. class JimArgumentParser(argparse.ArgumentParser):
  19. def error(self, message):
  20. self.print_usage(sys.stderr)
  21. self.exit(2, sprintf("error: %s\n", message))
  22. class Cmdline(object):
  23. def __init__(self, argv = None):
  24. self.argv = argv or sys.argv[1:]
  25. self.client = None
  26. self.def_url = os.environ.get("NILMDB_URL", "http://localhost:12380")
  27. self.subcmd = {}
  28. def arg_time(self, toparse):
  29. """Parse a time string argument"""
  30. try:
  31. return nilmdb.utils.time.parse_time(toparse).totimestamp()
  32. except ValueError as e:
  33. raise argparse.ArgumentTypeError(sprintf("%s \"%s\"",
  34. str(e), toparse))
  35. def parser_setup(self):
  36. self.parser = JimArgumentParser(add_help = False,
  37. formatter_class = def_form)
  38. group = self.parser.add_argument_group("General options")
  39. group.add_argument("-h", "--help", action='help',
  40. help='show this help message and exit')
  41. group.add_argument("-V", "--version", action="version",
  42. version = nilmdb.__version__)
  43. group = self.parser.add_argument_group("Server")
  44. group.add_argument("-u", "--url", action="store",
  45. default=self.def_url,
  46. help="NilmDB server URL (default: %(default)s)")
  47. sub = self.parser.add_subparsers(
  48. title="Commands", dest="command",
  49. description="Use 'help command' or 'command --help' for more "
  50. "details on a particular command.")
  51. # Set up subcommands (defined in separate files)
  52. for cmd in subcommands:
  53. self.subcmd[cmd] = subcmd_mods[cmd].setup(self, sub)
  54. def die(self, formatstr, *args):
  55. fprintf(sys.stderr, formatstr + "\n", *args)
  56. if self.client:
  57. self.client.close()
  58. sys.exit(-1)
  59. def run(self):
  60. # Clear cached timezone, so that we can pick up timezone changes
  61. # while running this from the test suite.
  62. datetime_tz._localtz = None
  63. # Run parser
  64. self.parser_setup()
  65. self.args = self.parser.parse_args(self.argv)
  66. # Run arg verify handler if there is one
  67. if "verify" in self.args:
  68. self.args.verify(self)
  69. self.client = nilmdb.client.Client(self.args.url)
  70. # Make a test connection to make sure things work,
  71. # unless the particular command requests that we don't.
  72. if "no_test_connect" not in self.args:
  73. try:
  74. server_version = self.client.version()
  75. except nilmdb.client.Error as e:
  76. self.die("error connecting to server: %s", str(e))
  77. # Now dispatch client request to appropriate function. Parser
  78. # should have ensured that we don't have any unknown commands
  79. # here.
  80. retval = self.args.handler(self) or 0
  81. self.client.close()
  82. sys.exit(retval)