def parse_input(cmd): # Split line into parts using shell-like syntax. try: parts = shlex.split(cmd, comments=True) except Exception as err: printout('Error parsing command: ', err) return None if len(parts) == 0: return None parser = None varname = None synchronous = False failOnError = False if parts[0] == ".use": parser = argparse.ArgumentParser(prog=parts[0], description='Set default user or topic') parser.add_argument('--user', default="unchanged", help='ID of default (on_behalf_of) user') parser.add_argument('--topic', default="unchanged", help='Name of default topic') elif parts[0] == ".await" or parts[0] == ".must": # .await|.must [<$variable_name>] <waitable_command> <params> if len(parts) > 1: synchronous = True failOnError = parts[0] == ".must" if len(parts) > 2 and parts[1][0] == '$': # Varname is given varname = parts[1] parts = parts[2:] parser = parse_cmd(parts) else: # No varname parts = parts[1:] parser = parse_cmd(parts) elif parts[0] == ".log": parser = argparse.ArgumentParser(prog=parts[0], description='Write value of a variable to stdout') parser.add_argument('varname', help='name of the variable to print') elif parts[0] == ".sleep": parser = argparse.ArgumentParser(prog=parts[0], description='Pause execution') parser.add_argument('millis', type=int, help='milliseconds to wait') elif parts[0] == ".verbose": parser = argparse.ArgumentParser(prog=parts[0], description='Toggle logging verbosity') else: parser = parse_cmd(parts) if not parser: printout("Unrecognized:", parts[0]) printout("Possible commands:") printout("\t.await\t\t- wait for completion of an operation") printout("\t.exit\t\t- exit the program (also .quit)") printout("\t.log\t\t- write value of a variable to stdout") printout("\t.must\t\t- wait for completion of an operation, terminate on failure") printout("\t.sleep\t\t- pause execution") printout("\t.use\t\t- set default user (on_behalf_of) or topic") printout("\t.verbose\t- toggle logging verbosity on/off") printout("\tacc\t\t- create or alter an account") printout("\tdel\t\t- delete message(s), topic, subscription, or user") printout("\tget\t\t- query topic for metadata or messages") printout("\tleave\t\t- detach or unsubscribe from topic") printout("\tlogin\t\t- authenticate current session") printout("\tnote\t\t- send a notification") printout("\tpub\t\t- post message to topic") printout("\tset\t\t- update topic metadata") printout("\tsub\t\t- subscribe to topic") printout("\tupload\t\t- upload file out of band") printout("\tusermod\t\t- modify user account") printout("\n\tType <command> -h for help") if macros: printout("\nMacro commands:") for key in sorted(macros.Macros): macro = macros.Macros[key] printout("\t%s\t\t- %s" % (macro.name(), macro.description())) return None try: args = parser.parse_args(parts[1:]) args.cmd = parts[0] args.synchronous = synchronous args.failOnError = failOnError if varname: args.varname = varname return args except SystemExit: return None
def run(args, schema, secret): try: if tn_globals.IsInteractive: tn_globals.Prompt = PromptSession() # Create secure channel with default credentials. channel = None if args.ssl: opts = (('grpc.ssl_target_name_override', args.ssl_host),) if args.ssl_host else None channel = grpc.secure_channel(args.host, grpc.ssl_channel_credentials(), opts) else: channel = grpc.insecure_channel(args.host) # Call the server stream = pbx.NodeStub(channel).MessageLoop(gen_message(schema, secret, args)) # Read server responses for msg in stream: if tn_globals.Verbose: stdoutln("\r<= " + to_json(msg)) if msg.HasField("ctrl"): handle_ctrl(msg.ctrl) elif msg.HasField("meta"): what = [] if len(msg.meta.sub) > 0: what.append("sub") if msg.meta.HasField("desc"): what.append("desc") if msg.meta.HasField("del"): what.append("del") if len(msg.meta.tags) > 0: what.append("tags") stdoutln("\r<= meta " + ",".join(what) + " " + msg.meta.topic) if tn_globals.WaitingFor and tn_globals.WaitingFor.await_id == msg.meta.id: if 'varname' in tn_globals.WaitingFor: tn_globals.Variables[tn_globals.WaitingFor.varname] = msg.meta tn_globals.WaitingFor = None elif msg.HasField("data"): stdoutln("\n\rFrom: " + msg.data.from_user_id) stdoutln("Topic: " + msg.data.topic) stdoutln("Seq: " + str(msg.data.seq_id)) if msg.data.head: stdoutln("Headers:") for key in msg.data.head: stdoutln("\t" + key + ": "+str(msg.data.head[key])) stdoutln(json.loads(msg.data.content)) elif msg.HasField("pres"): # 'ON', 'OFF', 'UA', 'UPD', 'GONE', 'ACS', 'TERM', 'MSG', 'READ', 'RECV', 'DEL', 'TAGS' what = pb.ServerPres.What.Name(msg.pres.what) stdoutln("\r<= pres " + what + " " + msg.pres.topic) elif msg.HasField("info"): switcher = { pb.READ: 'READ', pb.RECV: 'RECV', pb.KP: 'KP' } stdoutln("\rMessage #" + str(msg.info.seq_id) + " " + switcher.get(msg.info.what, "unknown") + " by " + msg.info.from_user_id + "; topic=" + msg.info.topic + " (" + msg.topic + ")") else: stdoutln("\rMessage type not handled" + str(msg)) except grpc.RpcError as err: # print(err) printerr("gRPC failed with {0}: {1}".format(err.code(), err.details())) except Exception as ex: printerr("Request failed: {0}".format(ex)) # print(traceback.format_exc()) finally: printout('Shutting down...') channel.close() if tn_globals.InputThread != None: tn_globals.InputThread.join(0.3)
parser.add_argument('--ssl-host', help='SSL host name to use instead of default (useful for connecting to localhost)') parser.add_argument('--login-basic', help='login using basic authentication username:password') parser.add_argument('--login-token', help='login using token authentication') parser.add_argument('--login-cookie', action='store_true', help='read token from cookie file and use it for authentication') parser.add_argument('--no-login', action='store_true', help='do not login even if cookie file is present; default in non-interactive (scripted) mode') parser.add_argument('--no-cookie', action='store_true', help='do not save login cookie; default in non-interactive (scripted) mode') parser.add_argument('--api-key', default='AQEAAAABAAD_rAp4DJh05a1HAwFT3A6K', help='API key for file uploads') parser.add_argument('--load-macros', default='./macros.py', help='path to macro module to load') parser.add_argument('--version', action='store_true', help='print version') parser.add_argument('--verbose', action='store_true', help='log full JSON representation of all messages') parser.add_argument('--background', action='store_const', const=True, help='start interactive sessionin background (non-intractive is always in background)') args = parser.parse_args() if args.version: printout(version) exit() if args.verbose: tn_globals.Verbose = True printout(purpose) printout("Secure server" if args.ssl else "Server", "at '"+args.host+"'", "SNI="+args.ssl_host if args.ssl_host else "") schema = None secret = None if not args.no_login: if args.login_token: """Use token to login"""