Comparison

plugins/mod_admin_shell.lua @ 10859:8de0057b4279

mod_admin_shell, mod_admin_telnet, util.prosodyctl.shell: Separate output from final result Fixes the client pausing for input after output from commands.
author Matthew Wild <mwild1@gmail.com>
date Mon, 01 Jun 2020 16:14:06 +0100
parent 10856:c99711eda0d1
child 10860:934dca972f2c
comparison
equal deleted inserted replaced
10858:efa49d484560 10859:8de0057b4279
59 59
60 self.data.print("Fatal error while running command, it did not complete"); 60 self.data.print("Fatal error while running command, it did not complete");
61 self.data.print("Error: "..tostring(err)); 61 self.data.print("Error: "..tostring(err));
62 end 62 end
63 63
64 local function send_repl_result(session, line) 64 local function send_repl_output(session, line)
65 return session.send(st.stanza("repl-result"):text(tostring(line))); 65 return session.send(st.stanza("repl-output"):text(tostring(line)));
66 end 66 end
67 67
68 function console:new_session(admin_session) 68 function console:new_session(admin_session)
69 local session = { 69 local session = {
70 send = function (t) 70 send = function (t)
71 return send_repl_result(admin_session, t); 71 return send_repl_output(admin_session, t);
72 end; 72 end;
73 print = function (...) 73 print = function (...)
74 local t = {}; 74 local t = {};
75 for i=1,select("#", ...) do 75 for i=1,select("#", ...) do
76 t[i] = tostring(select(i, ...)); 76 t[i] = tostring(select(i, ...));
77 end 77 end
78 return send_repl_result(admin_session, table.concat(t, "\t")); 78 return send_repl_output(admin_session, table.concat(t, "\t"));
79 end; 79 end;
80 serialize = tostring; 80 serialize = tostring;
81 disconnect = function () admin_session:close(); end; 81 disconnect = function () admin_session:close(); end;
82 }; 82 };
83 session.env = setmetatable({}, default_env_mt); 83 session.env = setmetatable({}, default_env_mt);
105 event.origin.shell_session = session; 105 event.origin.shell_session = session;
106 end 106 end
107 local line = event.stanza:get_text(); 107 local line = event.stanza:get_text();
108 local useglobalenv; 108 local useglobalenv;
109 109
110 110 local result = st.stanza("repl-result");
111 module:log("debug", "HELLO: %s", line) 111
112 if line:match("^>") then 112 if line:match("^>") then
113 line = line:gsub("^>", ""); 113 line = line:gsub("^>", "");
114 useglobalenv = true; 114 useglobalenv = true;
115 else 115 else
116 local command = line:match("^%w+") or line:match("%p"); 116 local command = line:match("^%w+") or line:match("%p");
117 if commands[command] then 117 if commands[command] then
118 commands[command](session, line); 118 commands[command](session, line);
119 event.origin.send(result);
119 return; 120 return;
120 end 121 end
121 end 122 end
122 123
123 session.env._ = line; 124 session.env._ = line;
124 125
125 if not useglobalenv and commands[line:lower()] then 126 if not useglobalenv and commands[line:lower()] then
126 commands[line:lower()](session, line); 127 commands[line:lower()](session, line);
128 event.origin.send(result);
127 return; 129 return;
128 end 130 end
129 131
130 local chunkname = "=console"; 132 local chunkname = "=console";
131 local env = (useglobalenv and redirect_output(_G, session)) or session.env or nil 133 local env = (useglobalenv and redirect_output(_G, session)) or session.env or nil
135 chunk, err = envload(line, chunkname, env); 137 chunk, err = envload(line, chunkname, env);
136 if not chunk then 138 if not chunk then
137 err = err:gsub("^%[string .-%]:%d+: ", ""); 139 err = err:gsub("^%[string .-%]:%d+: ", "");
138 err = err:gsub("^:%d+: ", ""); 140 err = err:gsub("^:%d+: ", "");
139 err = err:gsub("'<eof>'", "the end of the line"); 141 err = err:gsub("'<eof>'", "the end of the line");
140 session.print("Sorry, I couldn't understand that... "..err); 142 result.attr.type = "error";
143 result:text("Sorry, I couldn't understand that... "..err);
144 event.origin.send(result);
141 return; 145 return;
142 end 146 end
143 end 147 end
144 148
145 local taskok, message = chunk(); 149 local taskok, message = chunk();
150
151 local result = st.stanza("repl-result");
146 152
147 if not message then 153 if not message then
148 if type(taskok) ~= "string" and useglobalenv then 154 if type(taskok) ~= "string" and useglobalenv then
149 taskok = session.serialize(taskok); 155 taskok = session.serialize(taskok);
150 end 156 end
151 session.print("Result: "..tostring(taskok)); 157 result:text("Result: "..tostring(taskok));
152 return;
153 elseif (not taskok) and message then 158 elseif (not taskok) and message then
154 session.print("Command completed with a problem"); 159 result.attr.type = "error";
155 session.print("Message: "..tostring(message)); 160 result:text("Error: "..tostring(message));
156 return; 161 else
157 end 162 result:text("OK: "..tostring(message));
158 163 end
159 session.print("OK: "..tostring(message)); 164
160 end 165 event.origin.send(result);
161 166 end
162 module:hook("admin/repl-line", function (event) 167
168 module:hook("admin/repl-input", function (event)
163 local ok, err = pcall(handle_line, event); 169 local ok, err = pcall(handle_line, event);
164 if not ok then 170 if not ok then
165 event.origin.send(st.stanza("repl-result", { type = "error" }):text(err)); 171 event.origin.send(st.stanza("repl-result", { type = "error" }):text(err));
166 end 172 end
167 end); 173 end);