From 287dde63d8f67c56b08c67b7a93ef7e58a157be1 Mon Sep 17 00:00:00 2001 From: Cifrado Date: Wed, 22 Nov 2017 13:53:18 +0100 Subject: [PATCH] Added command descriptions --- contrib/epee/include/console_handler.h | 24 +- src/cryptonote_core/cryptonote_core.cpp | 1 + src/daemon/command_server.cpp | 136 ++++++---- src/daemon/command_server.h | 1 + src/simplewallet/simplewallet.cpp | 327 +++++++++++++++++++----- src/simplewallet/simplewallet.h | 1 + 6 files changed, 376 insertions(+), 114 deletions(-) diff --git a/contrib/epee/include/console_handler.h b/contrib/epee/include/console_handler.h index b8336b270..6d369d4d8 100644 --- a/contrib/epee/include/console_handler.h +++ b/contrib/epee/include/console_handler.h @@ -456,29 +456,35 @@ eof: class command_handler { public: typedef boost::function &)> callback; - typedef std::map > lookup; + typedef std::map>> lookup; std::string get_usage() { std::stringstream ss; - size_t max_command_len = 0; - for(auto& x:m_command_handlers) - if(x.first.size() > max_command_len) - max_command_len = x.first.size(); for(auto& x:m_command_handlers) { - ss.width(max_command_len + 3); - ss << std::left << x.first << x.second.second << ENDL; + ss << x.second.second.first << ENDL; } return ss.str(); } - void set_handler(const std::string& cmd, const callback& hndlr, const std::string& usage = "") + std::pair get_documentation(const std::vector& cmd) + { + if(cmd.empty()) + return std::make_pair("", ""); + auto it = m_command_handlers.find(cmd.front()); + if(it == m_command_handlers.end()) + return std::make_pair("", ""); + return it->second.second; + } + + void set_handler(const std::string& cmd, const callback& hndlr, const std::string& usage = "", const std::string& description = "") { lookup::mapped_type & vt = m_command_handlers[cmd]; vt.first = hndlr; - vt.second = usage; + vt.second.first = description.empty() ? cmd : usage; + vt.second.second = description.empty() ? usage : description; #ifdef HAVE_READLINE rdln::readline_buffer::add_completion(cmd); #endif diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp index 5c181208f..edc2dfdaa 100644 --- a/src/cryptonote_core/cryptonote_core.cpp +++ b/src/cryptonote_core/cryptonote_core.cpp @@ -1329,6 +1329,7 @@ namespace cryptonote << "where is between 0 (no details) and 4 (very verbose), or custom category based levels (eg, *:WARNING)" << ENDL << ENDL << "Use the \"help\" command to see the list of available commands." << ENDL + << "Use \"help \" to see a command's documentation." << ENDL << "**********************************************************************" << ENDL); m_starter_message_showed = true; } diff --git a/src/daemon/command_server.cpp b/src/daemon/command_server.cpp index b134aee61..7ff6b2bf3 100644 --- a/src/daemon/command_server.cpp +++ b/src/daemon/command_server.cpp @@ -48,215 +48,229 @@ t_command_server::t_command_server( , m_command_lookup() , m_is_rpc(is_rpc) { - m_command_lookup.set_handler( - "q" - , [] (const std::vector& args) {return true;} - , "ignored" - ); m_command_lookup.set_handler( "help" , std::bind(&t_command_server::help, this, p::_1) - , "Show this help" + , "help []" + , "Show the help section or the documentation about a ." ); m_command_lookup.set_handler( "print_height" , std::bind(&t_command_parser_executor::print_height, &m_parser, p::_1) - , "Print local blockchain height" + , "Print the local blockchain height." ); m_command_lookup.set_handler( "print_pl" , std::bind(&t_command_parser_executor::print_peer_list, &m_parser, p::_1) - , "Print peer list" + , "Print the current peer list." ); m_command_lookup.set_handler( "print_pl_stats" , std::bind(&t_command_parser_executor::print_peer_list_stats, &m_parser, p::_1) - , "Print peer list stats" + , "Print the peer list statistics." ); m_command_lookup.set_handler( "print_cn" , std::bind(&t_command_parser_executor::print_connections, &m_parser, p::_1) - , "Print connections" + , "Print the current connections." ); m_command_lookup.set_handler( "print_bc" , std::bind(&t_command_parser_executor::print_blockchain_info, &m_parser, p::_1) - , "Print blockchain info in a given blocks range, print_bc []" + , "print_bc []" + , "Print the blockchain info in a given blocks range." ); m_command_lookup.set_handler( "print_block" , std::bind(&t_command_parser_executor::print_block, &m_parser, p::_1) - , "Print block, print_block | " + , "print_block | " + , "Print a given block." ); m_command_lookup.set_handler( "print_tx" , std::bind(&t_command_parser_executor::print_transaction, &m_parser, p::_1) - , "Print transaction, print_tx [+hex] [+json]" + , "print_tx [+hex] [+json]" + , "Print a given transaction." ); m_command_lookup.set_handler( "is_key_image_spent" , std::bind(&t_command_parser_executor::is_key_image_spent, &m_parser, p::_1) - , "Prints whether a given key image is in the spent key images set, is_key_image_spent " + , "is_key_image_spent " + , "Print whether a given key image is in the spent key images set." ); m_command_lookup.set_handler( "start_mining" , std::bind(&t_command_parser_executor::start_mining, &m_parser, p::_1) - , "Start mining for specified address, start_mining [] [do_background_mining] [ignore_battery], default 1 thread, no background mining" + , "start_mining [] [do_background_mining] [ignore_battery]" + , "Start mining for specified address. Defaults to 1 thread and no background mining." ); m_command_lookup.set_handler( "stop_mining" , std::bind(&t_command_parser_executor::stop_mining, &m_parser, p::_1) - , "Stop mining" + , "Stop mining." ); m_command_lookup.set_handler( "print_pool" , std::bind(&t_command_parser_executor::print_transaction_pool_long, &m_parser, p::_1) - , "Print transaction pool (long format)" + , "Print the transaction pool using a long format." ); m_command_lookup.set_handler( "print_pool_sh" , std::bind(&t_command_parser_executor::print_transaction_pool_short, &m_parser, p::_1) - , "Print transaction pool (short format)" + , "Print transaction pool using a short format." ); m_command_lookup.set_handler( "print_pool_stats" , std::bind(&t_command_parser_executor::print_transaction_pool_stats, &m_parser, p::_1) - , "Print transaction pool statistics" + , "Print the transaction pool's statistics." ); m_command_lookup.set_handler( "show_hr" , std::bind(&t_command_parser_executor::show_hash_rate, &m_parser, p::_1) - , "Start showing hash rate" + , "Start showing the current hash rate." ); m_command_lookup.set_handler( "hide_hr" , std::bind(&t_command_parser_executor::hide_hash_rate, &m_parser, p::_1) - , "Stop showing hash rate" + , "Stop showing the hash rate." ); m_command_lookup.set_handler( "save" , std::bind(&t_command_parser_executor::save_blockchain, &m_parser, p::_1) - , "Save blockchain" + , "Save the blockchain." ); m_command_lookup.set_handler( "set_log" , std::bind(&t_command_parser_executor::set_log_level, &m_parser, p::_1) - , "set_log |<{+,-,}categories> - Change current log level/categories, is a number 0-4" + , "set_log |<{+,-,}categories>" + , "Change the current log level/categories where is a number 0-4." ); m_command_lookup.set_handler( "diff" , std::bind(&t_command_parser_executor::show_difficulty, &m_parser, p::_1) - , "Show difficulty" + , "Show the current difficulty." ); m_command_lookup.set_handler( "status" , std::bind(&t_command_parser_executor::show_status, &m_parser, p::_1) - , "Show status" + , "Show the current status." ); m_command_lookup.set_handler( "stop_daemon" , std::bind(&t_command_parser_executor::stop_daemon, &m_parser, p::_1) - , "Stop the daemon" + , "Stop the daemon." ); m_command_lookup.set_handler( "exit" , std::bind(&t_command_parser_executor::stop_daemon, &m_parser, p::_1) - , "Stop the daemon" + , "Stop the daemon." ); m_command_lookup.set_handler( "print_status" , std::bind(&t_command_parser_executor::print_status, &m_parser, p::_1) - , "Prints daemon status" + , "Print the current daemon status." ); m_command_lookup.set_handler( "limit" , std::bind(&t_command_parser_executor::set_limit, &m_parser, p::_1) - , "limit - Set download and upload limit" + , "limit []" + , "Get or set the download and upload limit." ); m_command_lookup.set_handler( "limit_up" , std::bind(&t_command_parser_executor::set_limit_up, &m_parser, p::_1) - , "limit - Set upload limit" + , "limit_up []" + , "Get or set the upload limit." ); m_command_lookup.set_handler( "limit_down" , std::bind(&t_command_parser_executor::set_limit_down, &m_parser, p::_1) - , "limit - Set download limit" + , "limit_down []" + , "Get or set the download limit." ); m_command_lookup.set_handler( "out_peers" , std::bind(&t_command_parser_executor::out_peers, &m_parser, p::_1) - , "Set max number of out peers" + , "out_peers " + , "Set the of out peers." ); m_command_lookup.set_handler( "start_save_graph" , std::bind(&t_command_parser_executor::start_save_graph, &m_parser, p::_1) - , "Start save data for dr monero" + , "Start saving data for dr monero." ); m_command_lookup.set_handler( "stop_save_graph" , std::bind(&t_command_parser_executor::stop_save_graph, &m_parser, p::_1) - , "Stop save data for dr monero" + , "Stop saving data for dr monero." ); m_command_lookup.set_handler( "hard_fork_info" , std::bind(&t_command_parser_executor::hard_fork_info, &m_parser, p::_1) - , "Print hard fork voting information" + , "Print the hard fork voting information." ); m_command_lookup.set_handler( "bans" , std::bind(&t_command_parser_executor::show_bans, &m_parser, p::_1) - , "Show the currently banned IPs" + , "Show the currently banned IPs." ); m_command_lookup.set_handler( "ban" , std::bind(&t_command_parser_executor::ban, &m_parser, p::_1) - , "Ban a given IP for a time" + , "ban []" + , "Ban a given for a given amount of ." ); m_command_lookup.set_handler( "unban" , std::bind(&t_command_parser_executor::unban, &m_parser, p::_1) - , "Unban a given IP" + , "unban " + , "Unban a given ." ); m_command_lookup.set_handler( "flush_txpool" , std::bind(&t_command_parser_executor::flush_txpool, &m_parser, p::_1) - , "Flush a transaction from the tx pool by its txid, or the whole tx pool" + , "flush_txpool []" + , "Flush a transaction from the tx pool by its , or the whole tx pool." ); m_command_lookup.set_handler( "output_histogram" , std::bind(&t_command_parser_executor::output_histogram, &m_parser, p::_1) - , "Print output histogram (amount, instances)" + , "output_histogram [@] []" + , "Print the output histogram of outputs." ); m_command_lookup.set_handler( "print_coinbase_tx_sum" , std::bind(&t_command_parser_executor::print_coinbase_tx_sum, &m_parser, p::_1) - , "Print sum of coinbase transactions [block count]" + , "print_coinbase_tx_sum []" + , "Print the sum of coinbase transactions." ); m_command_lookup.set_handler( "alt_chain_info" , std::bind(&t_command_parser_executor::alt_chain_info, &m_parser, p::_1) - , "Print information about alternative chains" + , "Print the information about alternative chains." ); m_command_lookup.set_handler( "bc_dyn_stats" , std::bind(&t_command_parser_executor::print_blockchain_dynamic_stats, &m_parser, p::_1) - , "Print information about current blockchain dynamic state, bc_dyn_stats " + , "bc_dyn_stats " + , "Print the information about current blockchain dynamic state." ); m_command_lookup.set_handler( "update" , std::bind(&t_command_parser_executor::update, &m_parser, p::_1) - , "subcommands: check (check if an update is available), download (download it if there is), update (not implemented)" + , "update (check|download)" + , "Check if an update is available, optionally downloads it if there is. Updating is not yet implemented." ); m_command_lookup.set_handler( "relay_tx" , std::bind(&t_command_parser_executor::relay_tx, &m_parser, p::_1) - , "Relay a given transaction by its txid" + , "relay_tx " + , "Relay a given transaction by its ." ); m_command_lookup.set_handler( "sync_info" , std::bind(&t_command_parser_executor::sync_info, &m_parser, p::_1) - , "Print information about blockchain sync state" + , "Print information about the blockchain sync state." ); } @@ -293,7 +307,14 @@ void t_command_server::stop_handling() bool t_command_server::help(const std::vector& args) { - std::cout << get_commands_str() << std::endl; + if(args.empty()) + { + std::cout << get_commands_str() << std::endl; + } + else + { + std::cout << get_command_usage(args) << std::endl; + } return true; } @@ -309,4 +330,25 @@ std::string t_command_server::get_commands_str() return ss.str(); } + std::string t_command_server::get_command_usage(const std::vector &args) + { + std::pair documentation = m_command_lookup.get_documentation(args); + std::stringstream ss; + if(documentation.first.empty()) + { + ss << "Unknown command: " << args.front() << std::endl; + } + else + { + std::string usage = documentation.second.empty() ? args.front() : documentation.first; + std::string description = documentation.second.empty() ? documentation.first : documentation.second; + usage.insert(0, " "); + ss << "Command usage: " << std::endl << usage << std::endl << std::endl; + boost::replace_all(description, "\n", "\n "); + description.insert(0, " "); + ss << "Command description: " << std::endl << description << std::endl; + } + return ss.str(); + } + } // namespace daemonize diff --git a/src/daemon/command_server.h b/src/daemon/command_server.h index 476b75141..2ad277f4a 100644 --- a/src/daemon/command_server.h +++ b/src/daemon/command_server.h @@ -73,6 +73,7 @@ private: bool help(const std::vector& args); std::string get_commands_str(); + std::string get_command_usage(const std::vector &args); }; } // namespace daemonize diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 17462bb81..489733120 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -365,6 +365,27 @@ std::string simple_wallet::get_commands_str() return ss.str(); } +std::string simple_wallet::get_command_usage(const std::vector &args) +{ + std::pair documentation = m_cmd_binder.get_documentation(args); + std::stringstream ss; + if(documentation.first.empty()) + { + ss << tr("Unknown command: ") << args.front(); + } + else + { + std::string usage = documentation.second.empty() ? args.front() : documentation.first; + std::string description = documentation.second.empty() ? documentation.first : documentation.second; + usage.insert(0, " "); + ss << tr("Command usage: ") << ENDL << usage << ENDL << ENDL; + boost::replace_all(description, "\n", "\n "); + description.insert(0, " "); + ss << tr("Command description: ") << ENDL << description << ENDL; + } + return ss.str(); +} + bool simple_wallet::viewkey(const std::vector &args/* = std::vector()*/) { if (m_wallet->ask_password() && !get_and_verify_password()) { return true; } @@ -885,7 +906,14 @@ bool simple_wallet::set_refresh_from_block_height(const std::vector bool simple_wallet::help(const std::vector &args/* = std::vector()*/) { - success_msg_writer() << get_commands_str(); + if(args.empty()) + { + success_msg_writer() << get_commands_str(); + } + else + { + success_msg_writer() << get_command_usage(args); + } return true; } @@ -898,63 +926,244 @@ simple_wallet::simple_wallet() , m_in_manual_refresh(false) , m_current_subaddress_account(0) { - m_cmd_binder.set_handler("start_mining", boost::bind(&simple_wallet::start_mining, this, _1), tr("start_mining [] [bg_mining] [ignore_battery] - Start mining in daemon (bg_mining and ignore_battery are optional booleans)")); - m_cmd_binder.set_handler("stop_mining", boost::bind(&simple_wallet::stop_mining, this, _1), tr("Stop mining in daemon")); - m_cmd_binder.set_handler("save_bc", boost::bind(&simple_wallet::save_bc, this, _1), tr("Save current blockchain data")); - m_cmd_binder.set_handler("refresh", boost::bind(&simple_wallet::refresh, this, _1), tr("Synchronize transactions and balance")); - m_cmd_binder.set_handler("balance", boost::bind(&simple_wallet::show_balance, this, _1), tr("balance [detail] - Show wallet balance of currently selected account")); - m_cmd_binder.set_handler("incoming_transfers", boost::bind(&simple_wallet::show_incoming_transfers, this, _1), tr("incoming_transfers [available|unavailable] [verbose] [index=[,,...]] - Show incoming transfers, all or filtered by availability and address index")); - m_cmd_binder.set_handler("payments", boost::bind(&simple_wallet::show_payments, this, _1), tr("payments [ ... ] - Show payments for given payment ID[s]")); - m_cmd_binder.set_handler("bc_height", boost::bind(&simple_wallet::show_blockchain_height, this, _1), tr("Show blockchain height")); - m_cmd_binder.set_handler("transfer_original", boost::bind(&simple_wallet::transfer, this, _1), tr("Same as transfer, but using an older transaction building algorithm")); - m_cmd_binder.set_handler("transfer", boost::bind(&simple_wallet::transfer_new, this, _1), tr("transfer [index=[,,...]] [] []
[] - Transfer to
. If the parameter \"index=[,,...]\" is specified, the wallet uses outputs received by addresses of those indices. If omitted, the wallet randomly chooses address indices to be used. In any case, it tries its best not to combine outputs across multiple addresses. is the priority of the transaction. The higher the priority, the higher the fee of the transaction. Valid values in priority order (from lowest to highest) are: unimportant, normal, elevated, priority. If omitted, the default value (see the command \"set priority\") is used. is the number of inputs to include for untraceability. Multiple payments can be made at once by adding etcetera (before the payment ID, if it's included)")); - m_cmd_binder.set_handler("locked_transfer", boost::bind(&simple_wallet::locked_transfer, this, _1), tr("locked_transfer [index=[,,...]] [] [] [] - Same as transfer, but with number of blocks to lock the transaction for, max 1000000")); - m_cmd_binder.set_handler("sweep_unmixable", boost::bind(&simple_wallet::sweep_unmixable, this, _1), tr("Send all unmixable outputs to yourself with ring_size 1")); - m_cmd_binder.set_handler("sweep_all", boost::bind(&simple_wallet::sweep_all, this, _1), tr("sweep_all [index=[,,...]] [] []
[] - Send all unlocked balance to an address. If the parameter \"index[,,...]\" is specified, the wallet sweeps outputs received by those address indices. If omitted, the wallet randomly chooses an address index to be used.")); - m_cmd_binder.set_handler("sweep_below", boost::bind(&simple_wallet::sweep_below, this, _1), tr("sweep_below [index=[,,...]] [] []
[] - Send all unlocked outputs below the threshold to an address")); - m_cmd_binder.set_handler("sweep_single", boost::bind(&simple_wallet::sweep_single, this, _1), tr("sweep_single [] []
[] - Send a single output of the given key image to an address without change")); - m_cmd_binder.set_handler("donate", boost::bind(&simple_wallet::donate, this, _1), tr("donate [index=[,,...]] [] [] [] - Donate to the development team (donate.getmonero.org)")); - m_cmd_binder.set_handler("sign_transfer", boost::bind(&simple_wallet::sign_transfer, this, _1), tr("Sign a transaction from a file")); - m_cmd_binder.set_handler("submit_transfer", boost::bind(&simple_wallet::submit_transfer, this, _1), tr("Submit a signed transaction from a file")); - m_cmd_binder.set_handler("set_log", boost::bind(&simple_wallet::set_log, this, _1), tr("set_log |{+,-,} - Change current log detail (level must be <0-4>)")); - m_cmd_binder.set_handler("account", boost::bind(&simple_wallet::account, this, _1), tr("account [new