def main(): # build the args we support. start = datetime.datetime.now() all_args = {} for n, v in globals().iteritems(): # explicit check for functions so twisted classes don't match.. if type(v) == type(main) and getattr(v, "__doc__", None): all_args[n.replace("_", "-")] = v all_arg_names = sorted(all_args.keys()) description = ( __doc__ + "\nCommands\n help\n " + "\n ".join(all_args.keys()) + "\nUse '%prog help command-name' for help on a specific command.\n" ) parser = optparse.OptionParser("%prog [options]", description=description, formatter=HelpFormatter()) for opt in opts.get_program_options(): parser.add_option(opt) for opt in opts.get_request_options(): parser.add_option(opt) options, args = parser.parse_args() opts.setup_logging(options) init_config(options.config) proto.init_protocols() # patch up keys. if options.keys: def _fix_unicode(result): if isinstance(result, list): for i, v in enumerate(result): result[i] = _fix_unicode(result[i]) elif isinstance(result, unicode): result = result.encode("utf-8") return result for i, val in enumerate(options.keys): try: # help windows - replace single quote with double... val = val.replace("'", '"') options.keys[i] = _fix_unicode(json.loads(val)) except ValueError, why: parser.error("Invalid key value %r: %s" % (val, why))
def main(): descs = [] for n, v in globals().iteritems(): if callable(v) and getattr(v, '__doc__', None) and v.__module__==__name__: all_commands[n.replace('_', '-')] = v descs.append("%s:" % n) descs.append(" %s" % v.__doc__) description = '\n'.join([__doc__, 'Commands:', '']+descs) + '\n' + \ get_request_opts_help() parser = optparse.OptionParser("%prog [options]", description=description, formatter=HelpFormatter()) for opt in opts.get_program_options(): parser.add_option(opt) # For testing... parser.add_option("", "--one", action="store_true", help="Only process one request and exit; accepts multi-line " "input and emits multi-line, pretty-printed output.") options, args = parser.parse_args() if args: # later may accept input filenames for testing? parser.error("this program accepts no args") opts.setup_logging(options) config.init_config() proto.init_protocols() logger.info("raindrops keep falling on my couch...") # create an initial deferred to perform tasks which must occur before we # can start. The final callback added will fire up the real servers. d = defer.Deferred() # XXX - this is suspect - we need to better rationilize 'options' handling d.addCallback(lambda _: _init({'query': {}})) def start_stdio(whateva): # using twisted's stdio is just way too hard on windows - just use a # dedicated thread... if options.one: target = stdio_one else: target = stdio_interact t = threading.Thread(target=target) t.start() d.addCallback(start_stdio) def done(whateva): pass def error(failure): # XXX - this is wrong - couch wants a "better" response with some # real errors - but at least this "works" in so far as couch reports # the incorrect output and continues on correctly... log_twisted_failure(failure, "unhandled top-level error") resp = {"error": failure.getErrorMessage() + "\n" + failure.getTraceback()} sys.stdout.write(json.dumps(resp) + "\n") sys.stdout.flush() d.addCallbacks(done, error) reactor.callWhenRunning(d.callback, None) reactor.run()