From ae4b5a79e5863ee6440b2070361f3229285a9380 Mon Sep 17 00:00:00 2001 From: Jonas Suhr Christensen Date: Tue, 22 May 2012 12:09:08 +0200 Subject: Working cli client. --- src/muniacli.cc | 257 +++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 245 insertions(+), 12 deletions(-) (limited to 'src/muniacli.cc') diff --git a/src/muniacli.cc b/src/muniacli.cc index a84de65..30e0ecf 100644 --- a/src/muniacli.cc +++ b/src/muniacli.cc @@ -30,13 +30,94 @@ #include #include #include +#include +#include +#include + +#include "message.h" +#include "messageparser.h" #include + enum demo_protocols { PROTOCOL_TASK }; +enum cmd_t { + DEFAULT, + CREATE, + LIST, + REMOVE, + UPDATE +}; + +static bool run; +static bool interactive; +static std::string msgs; +static int taskid; + +static std::map > structuremap; +static std::map titlemap; + +static std::string indent; + + +static void rec_pretty_print(int node) { + // printf("pretty printing %d\n", node); + // for(std::map>::iterator it = structuremap.begin(); + // it != structuremap.end(); it++) { + // std::list childlist = *it; + + printf("%s%d - %s\n", indent.c_str(), node, titlemap[node].c_str()); + std::list childlist = structuremap[node]; + if(!childlist.empty()) { + for(std::list::iterator it = childlist.begin(); + it != childlist.end(); it++) { + int child = *it; + indent += " "; + rec_pretty_print(child); + } + } + + indent = indent.substr(0, indent.length()-2); +} + +static void pretty_print(std::string msgs) { + // printf("%s\n", msgs.c_str()); + MessageList list = parse_msg_client(msgs); + + std::string indent; + int prevtask = -1; + + std::list childlist; + + for(MessageList::iterator it = list.begin(); + it != list.end(); it++) { + message_t msg = *it; + + switch(msg.cmd) { + case cmd::create: + // printf("Parent %d, id %d\n", msg.create.parentid, msg.create.id); + childlist = structuremap[msg.create.parentid]; + childlist.push_back(msg.create.id); + structuremap[msg.create.parentid] = childlist; + // printf("Childlist size of %d = %d\n", msg.create.parentid, childlist.size()); + break; + case cmd::update: + // char buf[256]; + // sprintf(buf, "%s", msg.update.title); + titlemap[msg.update.id] = msg.update.title; + // printf("%s\n", buf); + break; + default: + break; + } + } + + rec_pretty_print(taskid); +} + static int callback_task(struct libwebsocket_context *me, struct libwebsocket *wsi, enum libwebsocket_callback_reasons reason, @@ -46,6 +127,7 @@ static int callback_task(struct libwebsocket_context *me, LWS_SEND_BUFFER_POST_PADDING]; int l; char msg[4096]; + std::string r; switch (reason) { @@ -59,21 +141,34 @@ static int callback_task(struct libwebsocket_context *me, break; case LWS_CALLBACK_CLIENT_RECEIVE: - fprintf(stderr, "rx %d '", (int)len); - fwrite(in, len, 1, stderr); - fprintf(stderr, "'\n"); + // fprintf(stderr, "rx %d '", (int)len); + // fwrite(in, len, 1, stderr); + // fprintf(stderr, "\n"); + pretty_print((char*)in); libwebsocket_callback_on_writable(me, wsi); + + if(!interactive) run = false; break; case LWS_CALLBACK_CLIENT_WRITEABLE: - fgets(msg, sizeof(msg), stdin); - printf("send...\n"); - l = sprintf((char *)&buf[LWS_SEND_BUFFER_PRE_PADDING], "%s", msg); + + if(interactive) { + fgets(msg, sizeof(msg), stdin); + msgs += msg; + printf("send...\n"); + } - libwebsocket_write(wsi, &buf[LWS_SEND_BUFFER_PRE_PADDING], - l, LWS_WRITE_TEXT); + if(!msgs.empty()) { + // printf("Sending %s\n", msgs.c_str()); + l = sprintf((char *)&buf[LWS_SEND_BUFFER_PRE_PADDING], "%s", msgs.c_str()); + + libwebsocket_write(wsi, &buf[LWS_SEND_BUFFER_PRE_PADDING], + l, LWS_WRITE_TEXT); + + msgs.clear(); + } break; - + default: break; } @@ -92,6 +187,7 @@ int client(const char *address, int port) struct libwebsocket *wsi_task = NULL; int ietf_version = -1; // latest + context = libwebsocket_create_context(CONTEXT_PORT_NO_LISTEN, NULL, protocols, libwebsocket_internal_extensions, @@ -108,6 +204,7 @@ int client(const char *address, int port) */ int n = 1; while(n >= 0) { + n = libwebsocket_service(context, 1000); if (wsi_task == NULL) { @@ -129,17 +226,153 @@ int client(const char *address, int port) wsi_mirror, LWS_CLOSE_STATUS_GOINGAWAY); */ } + + if(!run) break; } - fprintf(stderr, "Exiting\n"); + // fprintf(stderr, "Exiting\n"); libwebsocket_context_destroy(context); return 0; } -int main() +static struct option options[] = { + { "create", no_argument, NULL, 'C'}, + { "help", no_argument, NULL, 'h' }, + { "host", required_argument, NULL, 'H'}, + { "interactive", no_argument, NULL, 'i'}, + { "id", required_argument, NULL, 'I'}, + { "list", no_argument, NULL, 'L'}, + { "name", required_argument, NULL, 'n'}, + { "port", required_argument, NULL, 'p' }, + { "remove", no_argument, NULL, 'R'}, + { "update", required_argument, NULL, 'U'}, + { NULL, 0, 0, 0 } +}; + +static char* USAGE= + "Usage: muniacli [OPTION]... TASK COMMAND\n" + "Commandline client to munia." + "Options:\n" + " -p, --port Port on host\n" + " -H, --host Host\n" + " -i, --interactive Run in interactive/shell mode\n" + "Task:\n" + " -N, --name Select task by name\n" + " -I, --id Select task by id\n" + "Commands:\n" + " -C, --create Create new subtask in TASK\n" + " -L, --list List subtasks in TASK\n" + " -R, --remove Remove subtask from TASK\n" + " -U, --update Update data in TASK"; + + +int main(int argc, char** argv) { - client("localhost", 10001); + int port = 7681; + struct libwebsocket_context *context; + int opts = 0; + std::string host = "localhost"; + int optionscount = 0; + std::string taskbyid; + std::string taskbyname; + cmd_t cmd = DEFAULT; + std::string cmd_opts; + + interactive = false; + run = true; + + int n = 0; + while(n >= 0) { + n = getopt_long(argc, argv, "p:iN:I:CLR:U:hH:", options, NULL); + if(n < 0) continue; + switch(n) { + case 'i': + interactive = true; + break; + case 'p': + port = atoi(optarg); + break; + case 'H': + host = optarg; + break; + case 'h': + fprintf(stderr, "%s\n", USAGE); + exit(1); + case 'N': + taskbyname = optarg; + break; + case 'I': + taskbyid = optarg; + break; + case 'C': + cmd = CREATE; + break; + case 'L': + cmd = LIST; + break; + case 'R': + cmd = REMOVE; + break; + case 'U': + cmd = UPDATE; + cmd_opts = optarg; + break; + } + } + + if(cmd == DEFAULT) { + fprintf(stderr, "%s\n", USAGE); + exit(1); + } + + if(!taskbyname.empty()) { + taskbyid = -1; + fprintf(stderr, "Option '-N, --name' is not yet supported\n"); + fprintf(stderr, "%s\n", USAGE); + exit(1); + } + + if(taskbyid.empty()) { + fprintf(stderr, "%s\n", USAGE); + exit(1); + } + + taskid = atoi(taskbyid.c_str()); + + switch(cmd) { + case CREATE: + msgs = "create " + taskbyid + ";"; + break; + case LIST: + msgs = "observe " + taskbyid; //+ + // "; unobserve " + task + ";"; + break; + case REMOVE: + msgs = "remove " + taskbyid + ";"; + break; + case UPDATE: + msgs = "update " + taskbyid + " " + cmd_opts; + break; + } + + /* + if(!interactive && argc - optionscount < 3) { + fprintf(stderr, "%s", USAGE); + exit(1); + } + else if (interactive && argc - optionscount < 2){ + fprintf(stderr, "%s", USAGE); + exit(1); + } + + if(!interactive) { + // printf("cmd: %s\n", argv[3]); + msgs = argv[3]; + } + */ + + client("localhost", port); return 0; } -- cgit v1.2.3