refactor(script): Better handling of tail scripts

This commit is contained in:
Michael Carlberg
2016-06-14 12:14:29 +02:00
parent c959d2c7c6
commit 6cae06c4dc
6 changed files with 92 additions and 43 deletions

View File

@ -13,7 +13,9 @@ ScriptModule::ScriptModule(const std::string& name_)
this->exec = config::get<std::string>(name(), "exec");
this->tail = config::get<bool>(name(), "tail", this->tail);
if (!this->tail)
if (this->tail)
this->interval = 0s;
else
this->interval = std::chrono::duration<double>(config::get<float>(name(), "interval", 1));
this->click_left = config::get<std::string>(name(), "click-left", "");
@ -27,38 +29,67 @@ ScriptModule::ScriptModule(const std::string& name_)
// Add formats and elements {{{
this->formatter->add(DEFAULT_FORMAT, TAG_OUTPUT, { TAG_OUTPUT });
// }}}
this->counter = 0;
}
void ScriptModule::start()
{
this->TimerModule::start();
if (!this->tail)
return;
// Start the tail script in a separate thread {{{
this->threads.push_back(std::thread([&]{
while (this->enabled() && (!this->command || !this->command->is_running())) {
log_debug("Executing command: "+ this->exec);
this->counter++;
this->command = std::make_unique<Command>("/usr/bin/env\nsh\n-c\n"
+ string::replace_all(this->exec, "%counter%", std::to_string(this->counter)));
this->command->exec(true);
}
}));
// }}}
}
bool ScriptModule::update()
{
this->counter++;
this->output.clear();
int bytes_read;
if (this->tail) {
if (!this->command)
return false;
if (!io::poll_read(this->command->get_stdout(PIPE_READ), 100))
return false;
this->output = io::readline(this->command->get_stdout(PIPE_READ), bytes_read);
return bytes_read > 0;
}
try {
std::string buf;
this->counter++;
this->output.clear();
auto execline = string::replace_all(this->exec, "%counter%", std::to_string(this->counter));
auto command = std::make_unique<Command>("/usr/bin/env\nsh\n-c\n"+ execline);
this->command = std::make_unique<Command>("/usr/bin/env\nsh\n-c\n"
+ string::replace_all(this->exec, "%counter%", std::to_string(this->counter)));
this->command->exec(false);
command->exec(false);
while (!(buf = io::readline(command->get_stdout(PIPE_READ))).empty() || (this->tail && this->enabled())) {
this->output.append(buf + "\n");
if (this->tail) {
this->broadcast();
this->output.clear();
}
while (true) {
auto buf = io::readline(this->command->get_stdout(PIPE_READ), bytes_read);
if (bytes_read <= 0)
break;
this->output.append(buf +"\n");
}
command->wait();
if (this->command)
this->command->wait();
} catch (CommandException &e) {
log_error(e.what());
} catch (proc::ExecFailure &e) {
log_error(e.what());
}
return !this->output.empty();
return true;
}
std::string ScriptModule::get_output()
@ -66,17 +97,19 @@ std::string ScriptModule::get_output()
if (this->output.empty())
return "";
auto counter_str = std::to_string(this->counter);
if (!this->click_left.empty())
this->builder->cmd(Cmd::LEFT_CLICK, string::replace_all(this->click_left, "%counter%", std::to_string(this->counter)));
this->builder->cmd(Cmd::LEFT_CLICK, string::replace_all(this->click_left, "%counter%", counter_str));
if (!this->click_middle.empty())
this->builder->cmd(Cmd::MIDDLE_CLICK, string::replace_all(this->click_middle, "%counter%", std::to_string(this->counter)));
this->builder->cmd(Cmd::MIDDLE_CLICK, string::replace_all(this->click_middle, "%counter%", counter_str));
if (!this->click_right.empty())
this->builder->cmd(Cmd::RIGHT_CLICK, string::replace_all(this->click_right, "%counter%", std::to_string(this->counter)));
this->builder->cmd(Cmd::RIGHT_CLICK, string::replace_all(this->click_right, "%counter%", counter_str));
if (!this->scroll_up.empty())
this->builder->cmd(Cmd::SCROLL_UP, string::replace_all(this->scroll_up, "%counter%", std::to_string(this->counter)));
this->builder->cmd(Cmd::SCROLL_UP, string::replace_all(this->scroll_up, "%counter%", counter_str));
if (!scroll_down.empty())
this->builder->cmd(Cmd::SCROLL_DOWN, string::replace_all(this->scroll_down, "%counter%", std::to_string(this->counter)));
this->builder->cmd(Cmd::SCROLL_DOWN, string::replace_all(this->scroll_down, "%counter%", counter_str));
this->builder->node(this->Module::get_output());