Mercurial > irccd
view irccdctl/cli.cpp @ 527:a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
author | David Demelier <markand@malikania.fr> |
---|---|
date | Thu, 16 Nov 2017 22:45:12 +0100 |
parents | e03521cf207b |
children | 9daccaeedcce |
line wrap: on
line source
/* * cli.cpp -- command line for irccdctl * * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr> * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include <boost/system/system_error.hpp> #include <irccd/errors.hpp> #include <irccd/json_util.hpp> #include <irccd/options.hpp> #include <irccd/string_util.hpp> #include <irccd/ctl/controller.hpp> #include "cli.hpp" namespace irccd { namespace ctl { void cli::recv_response(ctl::controller& ctl, nlohmann::json req, handler_t handler) { ctl.recv([&ctl, req, handler, this] (auto code, auto message) { if (code) throw boost::system::system_error(code); auto c = json_util::to_string(message["command"]); if (c != req["command"].get<std::string>()) { recv_response(ctl, std::move(req), std::move(handler)); return; } if (message["error"].is_number_integer()) throw boost::system::system_error(static_cast<network_error>(message["error"].template get<int>())); if (message["error"].is_string()) throw std::runtime_error(message["error"].template get<std::string>()); if (handler) handler(std::move(message)); }); } void cli::request(ctl::controller& ctl, nlohmann::json req, handler_t handler) { ctl.send(req, [&ctl, req, handler, this] (auto code, auto) { if (code) throw boost::system::system_error(code); recv_response(ctl, std::move(req), std::move(handler)); }); } /* * plugin_info_cli. * ------------------------------------------------------------------ */ void plugin_config_cli::set(ctl::controller& ctl, const std::vector<std::string>&args) { request(ctl, { { "plugin", args[0] }, { "variable", args[1] }, { "value", args[2] } }); } void plugin_config_cli::get(ctl::controller& ctl, const std::vector<std::string>& args) { auto json = nlohmann::json::object({ { "plugin", args[0] }, { "variable", args[1] } }); request(ctl, std::move(json), [args] (auto result) { if (result["variables"].is_object()) std::cout << json_util::pretty(result["variables"][args[1]]) << std::endl; }); } void plugin_config_cli::getall(ctl::controller& ctl, const std::vector<std::string> &args) { request(ctl, {{ "plugin", args[0] }}, [] (auto result) { auto variables = result["variables"]; for (auto v = variables.begin(); v != variables.end(); ++v) std::cout << std::setw(16) << std::left << v.key() << " : " << json_util::pretty(v.value()) << std::endl; }); } std::string plugin_config_cli::name() const { return "plugin-config"; } void plugin_config_cli::exec(ctl::controller& ctl, const std::vector<std::string> &args) { switch (args.size()) { case 3: set(ctl, args); break; case 2: get(ctl, args); break; case 1: getall(ctl, args); break; default: throw std::invalid_argument("plugin-config requires at least 1 argument"); } } /* * plugin_info_cli. * ------------------------------------------------------------------ */ std::string plugin_info_cli::name() const { return "plugin-info"; } void plugin_info_cli::exec(ctl::controller& ctl, const std::vector<std::string>& args) { if (args.size() < 1) throw std::invalid_argument("plugin-info requires 1 argument"); request(ctl, {{ "plugin", args[0] }}, [] (auto result) { std::cout << std::boolalpha; std::cout << "Author : " << json_util::get_string(result, "author") << std::endl; std::cout << "License : " << json_util::get_string(result, "license") << std::endl; std::cout << "Summary : " << json_util::get_string(result, "summary") << std::endl; std::cout << "Version : " << json_util::get_string(result, "version") << std::endl; }); } /* * plugin_list_cli. * ------------------------------------------------------------------ */ std::string plugin_list_cli::name() const { return "plugin-list"; } void plugin_list_cli::exec(ctl::controller& ctl, const std::vector<std::string>&) { request(ctl, {{ "command", "plugin-list" }}, [] (auto result) { for (const auto &value : result["list"]) if (value.is_string()) std::cout << value.template get<std::string>() << std::endl; }); } /* * plugin_load_cli. * ------------------------------------------------------------------ */ std::string plugin_load_cli::name() const { return "plugin-load"; } void plugin_load_cli::exec(ctl::controller& ctl, const std::vector<std::string> &args) { if (args.size() < 1) throw std::invalid_argument("plugin-load requires 1 argument"); request(ctl, {{ "plugin", args[0] }}); } /* * plugin_reload_cli. * ------------------------------------------------------------------ */ std::string plugin_reload_cli::name() const { return "plugin-reload"; } void plugin_reload_cli::exec(ctl::controller& ctl, const std::vector<std::string>& args) { if (args.size() < 1) throw std::invalid_argument("plugin-reload requires 1 argument"); request(ctl, {{ "plugin", args[0] }}); } /* * plugin_unload_cli. * ------------------------------------------------------------------ */ std::string plugin_unload_cli::name() const { return "plugin-unload"; } void plugin_unload_cli::exec(ctl::controller& ctl, const std::vector<std::string>& args) { if (args.size() < 1) throw std::invalid_argument("plugin-unload requires 1 argument"); request(ctl, {{ "plugin", args[0] }}); } /* * server_channel_cli. * ------------------------------------------------------------------ */ std::string server_channel_mode_cli::name() const { return "server-cmode"; } void server_channel_mode_cli::exec(ctl::controller& ctl, const std::vector<std::string> &args) { if (args.size() < 3) throw std::invalid_argument("server-cmode requires 3 arguments"); request(ctl, { { "command", "server-cmode" }, { "server", args[0] }, { "channel", args[1] }, { "mode", args[2] } }); } /* * server_channel_notice_cli. * ------------------------------------------------------------------ */ std::string server_channel_notice_cli::name() const { return "server-cnotice"; } void server_channel_notice_cli::exec(ctl::controller& ctl, const std::vector<std::string>& args) { if (args.size() < 3) throw std::invalid_argument("server-cnotice requires 3 arguments"); request(ctl, { { "command", "server-cnotice" }, { "server", args[0] }, { "channel", args[1] }, { "message", args[2] } }); } /* * server_connect_cli. * ------------------------------------------------------------------ */ namespace { option::result parse(std::vector<std::string> &args) { option::options options{ { "-c", true }, { "--command", true }, { "-n", true }, { "--nickname", true }, { "-r", true }, { "--realname", true }, { "-S", false }, { "--ssl-verify", false }, { "-s", false }, { "--ssl", false }, { "-u", true }, { "--username", true } }; return option::read(args, options); } } // !namespace std::string server_connect_cli::name() const { return "server-connect"; } void server_connect_cli::exec(ctl::controller& ctl, const std::vector<std::string>& args) { std::vector<std::string> copy(args); option::result result = parse(copy); option::result::const_iterator it; if (copy.size() < 2) throw std::invalid_argument("server-connect requires at least 2 arguments"); auto object = nlohmann::json::object({ { "name", copy[0] }, { "host", copy[1] } }); if (copy.size() == 3) { if (!string_util::is_int(copy[2])) throw std::invalid_argument("invalid port number"); object["port"] = std::stoi(copy[2]); } if (result.count("-S") > 0 || result.count("--ssl-verify") > 0) object["sslVerify"] = true; if (result.count("-s") > 0 || result.count("--ssl") > 0) object["ssl"] = true; if ((it = result.find("-n")) != result.end() || (it = result.find("--nickname")) != result.end()) object["nickname"] = it->second; if ((it = result.find("-r")) != result.end() || (it = result.find("--realname")) != result.end()) object["realname"] = it->second; if ((it = result.find("-u")) != result.end() || (it = result.find("--username")) != result.end()) object["username"] = it->second; request(ctl, object); } /* * server_disconnect_cli. * ------------------------------------------------------------------ */ std::string server_disconnect_cli::name() const { return "server-disconnect"; } void server_disconnect_cli::exec(ctl::controller& ctl, const std::vector<std::string>& args) { auto object = nlohmann::json::object({ { "command", "server-disconnect" } }); if (args.size() > 0) object["server"] = args[0]; request(ctl, object); } /* * server_info_cli. * ------------------------------------------------------------------ */ std::string server_info_cli::name() const { return "server-info"; } void server_info_cli::exec(ctl::controller& ctl, const std::vector<std::string>& args) { if (args.size() < 1) throw std::invalid_argument("server-info requires 1 argument"); auto json = nlohmann::json::object({ { "command", "server-info" }, { "server", args[0] } }); request(ctl, std::move(json), [] (auto result) { std::cout << std::boolalpha; std::cout << "Name : " << json_util::pretty(result["name"]) << std::endl; std::cout << "Host : " << json_util::pretty(result["host"]) << std::endl; std::cout << "Port : " << json_util::pretty(result["port"]) << std::endl; std::cout << "Ipv6 : " << json_util::pretty(result["ipv6"]) << std::endl; std::cout << "SSL : " << json_util::pretty(result["ssl"]) << std::endl; std::cout << "SSL verified : " << json_util::pretty(result["sslVerify"]) << std::endl; std::cout << "Channels : "; for (const auto &v : result["channels"]) if (v.is_string()) std::cout << v.template get<std::string>() << " "; std::cout << std::endl; std::cout << "Nickname : " << json_util::pretty(result["nickname"]) << std::endl; std::cout << "User name : " << json_util::pretty(result["username"]) << std::endl; std::cout << "Real name : " << json_util::pretty(result["realname"]) << std::endl; }); } /* * server_invite_cli. * ------------------------------------------------------------------ */ std::string server_invite_cli::name() const { return "server-invite"; } void server_invite_cli::exec(ctl::controller& ctl, const std::vector<std::string>& args) { if (args.size() < 3) throw std::invalid_argument("server-invite requires 3 arguments"); request(ctl, { { "command", "server-invite" }, { "server", args[0] }, { "target", args[1] }, { "channel", args[2] } }); } /* * server_join_cli. * ------------------------------------------------------------------ */ std::string server_join_cli::name() const { return "server-join"; } void server_join_cli::exec(ctl::controller& ctl, const std::vector<std::string>& args) { if (args.size() < 2) throw std::invalid_argument("server-join requires at least 2 arguments"); auto object = nlohmann::json::object({ { "server", args[0] }, { "channel", args[1] } }); if (args.size() == 3) object["password"] = args[2]; request(ctl, object); } /* * server_kick_cli. * ------------------------------------------------------------------ */ std::string server_kick_cli::name() const { return "server-kick"; } void server_kick_cli::exec(ctl::controller& ctl, const std::vector<std::string>& args) { if (args.size() < 3) throw std::invalid_argument("server-kick requires at least 3 arguments "); auto object = nlohmann::json::object({ { "server", args[0] }, { "target", args[1] }, { "channel", args[2] } }); if (args.size() == 4) object["reason"] = args[3]; request(ctl, object); } /* * server_list_cli. * ------------------------------------------------------------------ */ std::string server_list_cli::name() const { return "server-list"; } void server_list_cli::exec(ctl::controller& ctl, const std::vector<std::string>&) { request(ctl, {{ "command", "server-list" }}, [] (auto result) { for (const auto &n : result["list"]) if (n.is_string()) std::cout << n.template get<std::string>() << std::endl; }); } /* * server_me_cli. * ------------------------------------------------------------------ */ std::string server_me_cli::name() const { return "server-me"; } void server_me_cli::exec(ctl::controller& ctl, const std::vector<std::string>& args) { if (args.size() < 3) throw std::runtime_error("server-me requires 3 arguments"); request(ctl, { { "server", args[0] }, { "target", args[1] }, { "message", args[2] } }); } /* * server_message_cli. * ------------------------------------------------------------------ */ std::string server_message_cli::name() const { return "server-message"; } void server_message_cli::exec(ctl::controller& ctl, const std::vector<std::string>& args) { if (args.size() < 3) throw std::invalid_argument("server-message requires 3 arguments"); request(ctl, { { "server", args[0] }, { "target", args[1] }, { "message", args[2] } }); } /* * server_mode_cli. * ------------------------------------------------------------------ */ std::string server_mode_cli::name() const { return "server-mode"; } void server_mode_cli::exec(ctl::controller& ctl, const std::vector<std::string>& args) { if (args.size() < 2) throw std::invalid_argument("server-mode requires 2 arguments"); request(ctl, { { "server", args[0] }, { "mode", args[1] } }); } /* * server_nick_cli. * ------------------------------------------------------------------ */ std::string server_nick_cli::name() const { return "server-nick"; } void server_nick_cli::exec(ctl::controller& ctl, const std::vector<std::string>& args) { if (args.size() < 2) throw std::invalid_argument("server-nick requires 2 arguments"); request(ctl, { { "server", args[0] }, { "nickname", args[1] } }); } /* * server_notice_cli. * ------------------------------------------------------------------ */ std::string server_notice_cli::name() const { return "server-notice"; } void server_notice_cli::exec(ctl::controller& ctl, const std::vector<std::string>& args) { if (args.size() < 3) throw std::invalid_argument("server-notice requires 3 arguments"); request(ctl, { { "server", args[0] }, { "target", args[1] }, { "message", args[2] } }); } /* * server_part_cli. * ------------------------------------------------------------------ */ std::string server_part_cli::name() const { return "server-part"; } void server_part_cli::exec(ctl::controller& ctl, const std::vector<std::string>& args) { if (args.size() < 2) throw std::invalid_argument("server-part requires at least 2 arguments"); auto object = nlohmann::json::object({ { "server", args[0] }, { "channel", args[1] } }); if (args.size() >= 3) object["reason"] = args[2]; request(ctl, object); } /* * server_reconnect_cli. * ------------------------------------------------------------------ */ std::string server_reconnect_cli::name() const { return "server-reconnect"; } void server_reconnect_cli::exec(ctl::controller& ctl, const std::vector<std::string>& args) { auto object = nlohmann::json::object({ { "command", "server-reconnect" } }); if (args.size() >= 1) object["server"] = args[0]; request(ctl, object); } /* * server_topic_cli. * ------------------------------------------------------------------ */ std::string server_topic_cli::name() const { return "server-topic"; } void server_topic_cli::exec(ctl::controller& ctl, const std::vector<std::string>& args) { if (args.size() < 3) throw std::invalid_argument("server-topic requires 3 arguments"); request(ctl, { { "server", args[0] }, { "channel", args[1] }, { "topic", args[2] } }); } /* * rule_add_cli. * ------------------------------------------------------------------ */ std::string rule_add_cli::name() const { return "rule-add"; } void rule_add_cli::exec(ctl::controller& ctl, const std::vector<std::string>& args) { static const option::options options{ { "-c", true }, { "--add-channel", true }, { "-e", true }, { "--add-event", true }, { "-i", true }, { "--index", true }, { "-p", true }, { "--add-plugin", true }, { "-s", true }, { "--add-server", true } }; auto copy = args; auto result = option::read(copy, options); if (copy.size() < 1) throw std::invalid_argument("rule-add requires at least 1 argument"); auto json = nlohmann::json::object({ { "command", "rule-add" }, { "channels", nlohmann::json::array() }, { "events", nlohmann::json::array() }, { "plugins", nlohmann::json::array() }, { "servers", nlohmann::json::array() } }); // All sets. for (const auto& pair : result) { if (pair.first == "-c" || pair.first == "--add-channel") json["channels"].push_back(pair.second); if (pair.first == "-e" || pair.first == "--add-event") json["events"].push_back(pair.second); if (pair.first == "-p" || pair.first == "--add-plugin") json["plugins"].push_back(pair.second); if (pair.first == "-s" || pair.first == "--add-server") json["servers"].push_back(pair.second); } // Index. if (result.count("-i") > 0) json["index"] = string_util::to_number<unsigned>(result.find("-i")->second); if (result.count("--index") > 0) json["index"] = string_util::to_number<unsigned>(result.find("--index")->second); // And action. if (copy[0] != "accept" && copy[0] != "drop") throw std::runtime_error(string_util::sprintf("invalid action '%s'", copy[0])); json["action"] = copy[0]; request(ctl, json); } /* * rule_edit_cli. * ------------------------------------------------------------------ */ std::string rule_edit_cli::name() const { return "rule-edit"; } void rule_edit_cli::exec(ctl::controller& ctl, const std::vector<std::string>& args) { static const option::options options{ { "-a", true }, { "--action", true }, { "-c", true }, { "--add-channel", true }, { "-C", true }, { "--remove-channel", true }, { "-e", true }, { "--add-event", true }, { "-E", true }, { "--remove-event", true }, { "-p", true }, { "--add-plugin", true }, { "-P", true }, { "--remove-plugin", true }, { "-s", true }, { "--add-server", true }, { "-S", true }, { "--remove-server", true }, }; auto copy = args; auto result = option::read(copy, options); if (copy.size() < 1) throw std::invalid_argument("rule-edit requires at least 1 argument"); auto json = nlohmann::json::object({ { "command", "rule-edit" }, { "channels", nlohmann::json::array() }, { "events", nlohmann::json::array() }, { "plugins", nlohmann::json::array() }, { "servers", nlohmann::json::array() } }); for (const auto& pair : result) { // Action. if (pair.first == "-a" || pair.first == "--action") json["action"] = pair.second; // Additions. if (pair.first == "-c" || pair.first == "--add-channel") json["add-channels"].push_back(pair.second); if (pair.first == "-e" || pair.first == "--add-event") json["add-events"].push_back(pair.second); if (pair.first == "-p" || pair.first == "--add-plugin") json["add-plugins"].push_back(pair.second); if (pair.first == "-s" || pair.first == "--add-server") json["add-servers"].push_back(pair.second); // Removals. if (pair.first == "-C" || pair.first == "--remove-channel") json["remove-channels"].push_back(pair.second); if (pair.first == "-E" || pair.first == "--remove-event") json["remove-events"].push_back(pair.second); if (pair.first == "-P" || pair.first == "--remove-plugin") json["remove-plugins"].push_back(pair.second); if (pair.first == "-S" || pair.first == "--remove-server") json["remove-servers"].push_back(pair.second); } // Index. json["index"] = string_util::to_number<unsigned>(copy[0]); request(ctl, json); } /* * rule_list_cli. * ------------------------------------------------------------------ */ namespace { void show_rule(const nlohmann::json& json, int index) { assert(json.is_object()); auto unjoin = [] (auto array) { std::ostringstream oss; for (auto it = array.begin(); it != array.end(); ++it) { if (!it->is_string()) continue; oss << it->template get<std::string>() << " "; } return oss.str(); }; auto unstr = [] (auto action) { if (action.is_string() && action == "accept") return "accept"; else return "drop"; }; std::cout << "rule: " << index << std::endl; std::cout << "servers: " << unjoin(json["servers"]) << std::endl; std::cout << "channels: " << unjoin(json["channels"]) << std::endl; std::cout << "plugins: " << unjoin(json["plugins"]) << std::endl; std::cout << "events: " << unjoin(json["events"]) << std::endl; std::cout << "action: " << unstr(json["action"]) << std::endl; std::cout << std::endl; } } // !namespace std::string rule_list_cli::name() const { return "rule-list"; } void rule_list_cli::exec(ctl::controller& ctl, const std::vector<std::string>&) { request(ctl, {{ "command", "rule-list" }}, [] (auto result) { auto pos = 0; for (const auto& obj : result["list"]) { if (obj.is_object()) show_rule(obj, pos++); } }); } /* * rule_info_cli. * ------------------------------------------------------------------ */ std::string rule_info_cli::name() const { return "rule-info"; } void rule_info_cli::exec(ctl::controller& ctl, const std::vector<std::string>& args) { if (args.size() < 1) throw std::invalid_argument("rule-info requires 1 argument"); int index = 0; try { index = std::stoi(args[0]); } catch (...) { throw std::invalid_argument("invalid number '" + args[0] + "'"); } auto json = nlohmann::json::object({ { "command", "rule-info" }, { "index", index } }); request(ctl, std::move(json), [] (auto result) { show_rule(result, 0); }); } /* * rule_remove_cli. * ------------------------------------------------------------------ */ std::string rule_remove_cli::name() const { return "rule-remove"; } void rule_remove_cli::exec(ctl::controller& ctl, const std::vector<std::string>& args) { if (args.size() < 1) throw std::invalid_argument("rule-remove requires 1 argument"); int index = 0; try { index = std::stoi(args[0]); } catch (...) { throw std::invalid_argument("invalid number '" + args[0] + "'"); } request(ctl, { { "command", "rule-remove" }, { "index", index } }); } /* * rule_move_cli. * ------------------------------------------------------------------ */ std::string rule_move_cli::name() const { return "rule-move"; } void rule_move_cli::exec(ctl::controller& ctl, const std::vector<std::string>& args) { if (args.size() < 2) throw std::invalid_argument("rule-move requires 2 arguments"); int from = 0; int to = 0; try { from = std::stoi(args[0]); to = std::stoi(args[1]); } catch (...) { throw std::invalid_argument("invalid number"); } request(ctl, { { "command", "rule-move" }, { "from", from }, { "to", to } }); } /* * WatchCli. * ------------------------------------------------------------------ */ namespace { std::string format(std::vector<std::string> args) { auto result = option::read(args, { { "-f", true }, { "--format", true } }); if (result.count("-f") > 0) return result.find("-f")->second; if (result.count("--format") > 0) return result.find("--format")->second; return "native"; } void onChannelMode(const nlohmann::json &v) { std::cout << "event: onChannelMode\n"; std::cout << "server: " << json_util::pretty(v, "server") << "\n"; std::cout << "origin: " << json_util::pretty(v, "origin") << "\n"; std::cout << "mode: " << json_util::pretty(v, "mode") << "\n"; std::cout << "argument: " << json_util::pretty(v, "argument") << "\n"; } void onChannelNotice(const nlohmann::json &v) { std::cout << "event: onChannelNotice\n"; std::cout << "server: " << json_util::pretty(v, "server") << "\n"; std::cout << "origin: " << json_util::pretty(v, "origin") << "\n"; std::cout << "channel: " << json_util::pretty(v, "channel") << "\n"; std::cout << "message: " << json_util::pretty(v, "message") << "\n"; } void onConnect(const nlohmann::json &v) { std::cout << "event: onConnect\n"; std::cout << "server: " << json_util::pretty(v, "server") << "\n"; } void onInvite(const nlohmann::json &v) { std::cout << "event: onInvite\n"; std::cout << "server: " << json_util::pretty(v, "server") << "\n"; std::cout << "origin: " << json_util::pretty(v, "origin") << "\n"; std::cout << "channel: " << json_util::pretty(v, "channel") << "\n"; } void onJoin(const nlohmann::json &v) { std::cout << "event: onJoin\n"; std::cout << "server: " << json_util::pretty(v, "server") << "\n"; std::cout << "origin: " << json_util::pretty(v, "origin") << "\n"; std::cout << "channel: " << json_util::pretty(v, "channel") << "\n"; } void onKick(const nlohmann::json &v) { std::cout << "event: onKick\n"; std::cout << "server: " << json_util::pretty(v, "server") << "\n"; std::cout << "origin: " << json_util::pretty(v, "origin") << "\n"; std::cout << "channel: " << json_util::pretty(v, "channel") << "\n"; std::cout << "target: " << json_util::pretty(v, "target") << "\n"; std::cout << "reason: " << json_util::pretty(v, "reason") << "\n"; } void onMessage(const nlohmann::json &v) { std::cout << "event: onMessage\n"; std::cout << "server: " << json_util::pretty(v, "server") << "\n"; std::cout << "origin: " << json_util::pretty(v, "origin") << "\n"; std::cout << "channel: " << json_util::pretty(v, "channel") << "\n"; std::cout << "message: " << json_util::pretty(v, "message") << "\n"; } void onMe(const nlohmann::json &v) { std::cout << "event: onMe\n"; std::cout << "server: " << json_util::pretty(v, "server") << "\n"; std::cout << "origin: " << json_util::pretty(v, "origin") << "\n"; std::cout << "target: " << json_util::pretty(v, "target") << "\n"; std::cout << "message: " << json_util::pretty(v, "message") << "\n"; } void onMode(const nlohmann::json &v) { std::cout << "event: onMode\n"; std::cout << "server: " << json_util::pretty(v, "server") << "\n"; std::cout << "origin: " << json_util::pretty(v, "origin") << "\n"; std::cout << "mode: " << json_util::pretty(v, "mode") << "\n"; } void onNames(const nlohmann::json &v) { std::cout << "event: onNames\n"; std::cout << "server: " << json_util::pretty(v, "server") << "\n"; std::cout << "channel: " << json_util::pretty(v, "channel") << "\n"; std::cout << "names: " << json_util::pretty(v, "names") << "\n"; } void onNick(const nlohmann::json &v) { std::cout << "event: onNick\n"; std::cout << "server: " << json_util::pretty(v, "server") << "\n"; std::cout << "origin: " << json_util::pretty(v, "origin") << "\n"; std::cout << "nickname: " << json_util::pretty(v, "nickname") << "\n"; } void onNotice(const nlohmann::json &v) { std::cout << "event: onNotice\n"; std::cout << "server: " << json_util::pretty(v, "server") << "\n"; std::cout << "origin: " << json_util::pretty(v, "origin") << "\n"; std::cout << "message: " << json_util::pretty(v, "message") << "\n"; } void onPart(const nlohmann::json &v) { std::cout << "event: onPart\n"; std::cout << "server: " << json_util::pretty(v, "server") << "\n"; std::cout << "origin: " << json_util::pretty(v, "origin") << "\n"; std::cout << "channel: " << json_util::pretty(v, "channel") << "\n"; std::cout << "reason: " << json_util::pretty(v, "reason") << "\n"; } void onQuery(const nlohmann::json &v) { std::cout << "event: onQuery\n"; std::cout << "server: " << json_util::pretty(v, "server") << "\n"; std::cout << "origin: " << json_util::pretty(v, "origin") << "\n"; std::cout << "message: " << json_util::pretty(v, "message") << "\n"; } void onTopic(const nlohmann::json &v) { std::cout << "event: onTopic\n"; std::cout << "server: " << json_util::pretty(v, "server") << "\n"; std::cout << "origin: " << json_util::pretty(v, "origin") << "\n"; std::cout << "channel: " << json_util::pretty(v, "channel") << "\n"; std::cout << "topic: " << json_util::pretty(v, "topic") << "\n"; } void onWhois(const nlohmann::json &v) { std::cout << "event: onWhois\n"; std::cout << "server: " << json_util::pretty(v, "server") << "\n"; std::cout << "nickname: " << json_util::pretty(v, "nickname") << "\n"; std::cout << "username: " << json_util::pretty(v, "username") << "\n"; std::cout << "host: " << json_util::pretty(v, "host") << "\n"; std::cout << "realname: " << json_util::pretty(v, "realname") << "\n"; } const std::unordered_map<std::string, std::function<void (const nlohmann::json&)>> events{ { "onChannelMode", onChannelMode }, { "onChannelNotice", onChannelNotice }, { "onConnect", onConnect }, { "onInvite", onInvite }, { "onJoin", onJoin }, { "onKick", onKick }, { "onMessage", onMessage }, { "onMe", onMe }, { "onMode", onMode }, { "onNames", onNames }, { "onNick", onNick }, { "onNotice", onNotice }, { "onPart", onPart }, { "onQuery", onQuery }, { "onTopic", onTopic }, { "onWhois", onWhois } }; void get_event(ctl::controller& ctl, std::string fmt) { ctl.recv([&ctl, fmt] (auto code, auto message) { if (code) throw boost::system::system_error(code); auto it = events.find(json_util::to_string(message["event"])); if (it != events.end()) { if (fmt == "json") std::cout << message.dump(4) << std::endl; else { it->second(message); std::cout << std::endl; } } get_event(ctl, std::move(fmt)); }); } } // !namespace std::string watch_cli::name() const { return "watch"; } void watch_cli::exec(ctl::controller& ctl, const std::vector<std::string>& args) { auto fmt = format(args); if (fmt != "native" && fmt != "json") throw std::invalid_argument("invalid format given: " + fmt); get_event(ctl, fmt); } } // !cli } // !irccd