diff --git a/IO/HandleOutput.cpp b/IO/HandleOutput.cpp index 8305496..3150d83 100644 --- a/IO/HandleOutput.cpp +++ b/IO/HandleOutput.cpp @@ -1,34 +1,93 @@ #include "./HandleOutput.hpp" +// The contents of RSC's help command. +// WARNING: DO NOT USE TABS, ONLY SPACES! +const std::string HandleOutput::HELP_TEXT = +R"(USAGE: rsc [OPTIONS] [COMMAND] + +Robust Server Controller (rsc) +provides simple functionallity to save server information and automatically find IPv4 addresses. + +COMMANDS: + $ rsc # lists all saved server information. + $ rsc --addservers # adds servers from LAN. + $ rsc --addipv4 # adds a server by its IPv4 address. + $ rsc --remove # removes from the saved servers list. + $ rsc --changename --newname # changes to . + +FLAGS: + -h, --help help for rsc. + -v, --verbose provides verbose output for rsc. + -a, --addservers add servers from online servers on LAN. + -rm, --remove remove a saved server profile. + -cn, --changename changes a profiles name. + +DESCRIPTION: + rsc is a sever controller written in c++. it provides simple functionallity + for managing LAN servers whose addresses may change due to a NAT.)"; + + + // prints the host vector `hosts` in a numbered list. // only prints IPv4 and MAC addresses. -void HandleOutput::printHostVectorNumberedList(std::vector hosts) { - int i = 1; +void HandleOutput::printHostVectorNumberedTable(std::vector hosts) { + int hostIndex = 1; + // TODO: change these to a struct called TableContext? could + // be useful for printing other tables... and will make + // it easier to use the printTableHeader() and the + // printTableHostColumn() methods. + int rowNumberColumnMargin = 4; + int IPv4ColumnMargin = 15; + int MACColumnMargin = 20; + + printNumberedTableHeader(rowNumberColumnMargin, IPv4ColumnMargin, MACColumnMargin); + for (auto &h : hosts) { + printNumberedTableHostRow(hostIndex, h, rowNumberColumnMargin, IPv4ColumnMargin, MACColumnMargin); + hostIndex++; + } +} + +// prints the numbered host table header. +// TODO: seems unintuitive. +void HandleOutput::printNumberedTableHeader(int rowNumberColumnMargin, int IPv4ColumnMargin, int MACColumnMargin) { + // + // # IPV4 MAC <---------- prints this! + // 1 + // 2 + // ..... + // std::cout << "\n"; std::cout << BOLD << std::left - << std::setw(4) << "#" - << std::setw(15) << "IPV4" - << std::setw(20) << "MAC" + << std::setw(rowNumberColumnMargin) << "#" + << std::setw(IPv4ColumnMargin) << "IPV4" + << std::setw(MACColumnMargin) << "MAC" << RESET << '\n'; +} - for (const auto &h : hosts) { - std::cout << std::left - << std::setw(4) << i << RESET - << GREEN - << std::setw(15) << h.getIPv4() - << std::setw(20) << h.getMAC()<< RESET - << '\n'; - i++; - } +// prints a new row to the numbered table. +// TODO: seems unintuitive. +void HandleOutput::printNumberedTableHostRow(int rowNumber, Host& h, int rowNumberColumnMargin, int IPv4ColumnMargin, int MACColumnMargin) { + // + // # IPV4 MAC + // 1 <-------- prints this! + // 2 <-------- prints this! + // ..... + // + std::cout << std::left + << std::setw(rowNumberColumnMargin) << rowNumber << RESET + << GREEN + << std::setw(IPv4ColumnMargin) << h.getIPv4() + << std::setw(MACColumnMargin) << h.getMAC()<< RESET + << '\n'; } std::vector HandleOutput::StartChooseHostsLoop(std::vector foundHosts) { int hostNum; std::vector chosenAddrs; while (true) { - printHostVectorNumberedList(foundHosts); + printHostVectorNumberedTable(foundHosts); std::cout << "[AddServers::Start()] choose host number (-1 if done): "; std::string num; diff --git a/IO/HandleOutput.hpp b/IO/HandleOutput.hpp index 362acdc..e3ba406 100644 --- a/IO/HandleOutput.hpp +++ b/IO/HandleOutput.hpp @@ -4,21 +4,29 @@ class HandleOutput { public: + // The contents of RSC's help command. + // WARNING: DO NOT USE TABS, ONLY SPACES! + static const std::string HELP_TEXT; + // pretty prints hosts in chosenHosts as a table. // TODO: change name. static void printHostVectorTable(); static std::vector StartChooseHostsLoop(std::vector foundHosts); - // pretty prints hosts in chosenHosts as a list. + // pretty prints hosts in chosenHosts as a numbered table. // only prints ipv4 and mac. - static void printHostVectorNumberedList(std::vector hosts); + static void printHostVectorNumberedTable(std::vector hosts); + + // prints the numbered host table header. + // TODO: seems unintuitive. + static void printNumberedTableHeader(int rowNumberColumnMargin, int IPv4ColumnMargin, int MACColumnMargin); + + // prints a new row to the numbered table. + // TODO: seems unintuitive. + static void printNumberedTableHostRow(int rowNumber, Host& h, int rowNumberColumnMargin, int IPv4ColumnMargin, int MACColumnMargin); // prints msg if verbose is equal to true. static void verbosePrint(const std::string& msg, bool verbose); - // prints the help command to the screen. - // TODO: Change to a field and create a command - // called `printHelp()` in `HandleCommand`. - static void helpCommand(); }; diff --git a/command/HandleCommand.cpp b/command/HandleCommand.cpp index 5f55dc6..7efe719 100644 --- a/command/HandleCommand.cpp +++ b/command/HandleCommand.cpp @@ -37,6 +37,11 @@ void HandleCommand::printHosts(){ PrintOutput(); } +// prints the help command to the screen. +void HandleCommand::printHelp() { + std::cout << HandleOutput::HELP_TEXT << std::endl; +} + void HandleCommand::addMultipleHosts() { std::vector foundHosts = ArpUtils::scanHosts(); std::vector newChosenHosts = HandleOutput::StartChooseHostsLoop(foundHosts); diff --git a/command/HandleCommand.hpp b/command/HandleCommand.hpp index 9c50b30..fb551ad 100644 --- a/command/HandleCommand.hpp +++ b/command/HandleCommand.hpp @@ -37,6 +37,9 @@ class HandleCommand { // TODO: change name. static void printHosts(); + // prints the help command to the screen. + static void printHelp(); + // resets rsc into default settings. static void factoryReset(); }; diff --git a/host/Host.cpp b/host/Host.cpp index a9b88aa..23c7f60 100644 --- a/host/Host.cpp +++ b/host/Host.cpp @@ -41,3 +41,25 @@ void Host::setStatus(const bool status) { _status = status; } +std::ostream& operator<<(std::ostream& os, const Host& host) { + // TODO: change these to a struct called TableContext? could + // be useful... + int nameColumnMargin = 20; + int IPv4ColumnMargin = 15; + int MACColumnMargin = 20; + int statusColumnMargin = 15; + + std::string hostName = host.getName(); + std::string hostIPv4 = host.getIPv4(); + std::string hostMAC = host.getMAC(); + bool hostStatus = host.getStatus(); + + os << std::left; + + os << std::setw(nameColumnMargin) << hostName << RESET; + os << std::setw(IPv4ColumnMargin) << hostIPv4 << RESET; + os << std::setw(MACColumnMargin) << hostMAC << RESET; + os << std::setw(statusColumnMargin) << (hostStatus ? "online" : "offline") << RESET; + + return os; +} diff --git a/host/Host.hpp b/host/Host.hpp index de01a21..8651783 100644 --- a/host/Host.hpp +++ b/host/Host.hpp @@ -27,3 +27,4 @@ class Host bool _status; // offline-online }; +std::ostream& operator<<(std::ostream& os, const Host& host); diff --git a/host/HostList.cpp b/host/HostList.cpp index a2b7261..9d41bfe 100644 --- a/host/HostList.cpp +++ b/host/HostList.cpp @@ -16,3 +16,32 @@ void HostList::populateChosenHosts() { throw std::runtime_error(std::string("[Commands::UpdateHosts()] FILE ERROR: ") + e.what()); } } + +std::ostream& operator<<(std::ostream& os, const HostList& hosts) { + int hostIndex = 1; + + int rowNumberColumnMargin = 4; + int nameColumnMargin = 20; + int IPv4ColumnMargin = 15; + int MACColumnMargin = 20; + int statusColumnMargin = 15; + + // header + os << "\n"; + os << BOLD + << std::left + << std::setw(rowNumberColumnMargin) << "#" + << std::setw(nameColumnMargin) << "NAME" + << std::setw(IPv4ColumnMargin) << "IPV4" + << std::setw(MACColumnMargin) << "MAC" + << std::setw(statusColumnMargin) << "STATUS" + << RESET + << '\n'; + + for (const auto &h : hosts.getChosenHosts()) { + os << std::setw(rowNumberColumnMargin) << hostIndex + << h << '\n'; + hostIndex++; + } + return os; +} diff --git a/host/HostList.hpp b/host/HostList.hpp index f0d51bf..fb1d34f 100644 --- a/host/HostList.hpp +++ b/host/HostList.hpp @@ -6,7 +6,9 @@ class HostList { public: // TODO: change name. static std::vector chosenHosts; - + + static std::vector getChosenHosts(); + // populates `chosenHosts` with hosts saved on the json DB. static void populateChosenHosts(); @@ -21,3 +23,4 @@ class HostList { // TODO: add Commands contructor. }; +std::ostream& operator<<(std::ostream& os, const HostList& hosts);