Improved console interface
This commit is contained in:
parent
d352c74ad0
commit
831e454ebb
3 changed files with 80 additions and 54 deletions
|
@ -77,6 +77,9 @@ static inline char yna(std::string & user_input){
|
|||
case 'a': case 'A':
|
||||
return 'a';
|
||||
break;
|
||||
case 't': case 'T':
|
||||
return 't';
|
||||
break;
|
||||
default:
|
||||
return 'x';
|
||||
break;
|
||||
|
@ -91,7 +94,7 @@ void createAccount (std::string account){
|
|||
if (colon != std::string::npos && colon != 0 && colon != account.size()){
|
||||
std::string uname = account.substr(0, colon);
|
||||
std::string pword = account.substr(colon + 1, std::string::npos);
|
||||
Controller::Log("CONF", "Created account " + uname + " through commandline option");
|
||||
Controller::Log("CONF", "Created account " + uname + " through console interface");
|
||||
Controller::Storage["account"][uname]["password"] = Secure::md5(pword);
|
||||
}
|
||||
}
|
||||
|
@ -155,6 +158,7 @@ void statusMonitor(void * np){
|
|||
/// shutdown reason
|
||||
/// ~~~~~~~~~~~~~~~
|
||||
int main_loop(int argc, char ** argv){
|
||||
Controller::isTerminal = Controller::isColorized = isatty(fileno(stdin));
|
||||
Controller::Storage = JSON::fromFile("config.json");
|
||||
JSON::Value stored_port = JSON::fromString("{\"long\":\"port\", \"short\":\"p\", \"arg\":\"integer\", \"help\":\"TCP port to listen on.\"}");
|
||||
stored_port["default"] = Controller::Storage["config"]["controller"]["port"];
|
||||
|
@ -193,6 +197,7 @@ int main_loop(int argc, char ** argv){
|
|||
DEBUG_MSG(DLVL_ERROR, "Could not redirect output to %s: %s",Controller::conf.getString("logfile").c_str(),strerror(errno));
|
||||
return 7;
|
||||
}else{
|
||||
Controller::isTerminal = Controller::isColorized = false;
|
||||
dup2(output,STDOUT_FILENO);
|
||||
dup2(output,STDERR_FILENO);
|
||||
time_t rawtime;
|
||||
|
@ -250,67 +255,73 @@ int main_loop(int argc, char ** argv){
|
|||
createAccount(Controller::conf.getString("account"));
|
||||
|
||||
//if a terminal is connected and we're not logging to file
|
||||
if (isatty(fileno(stdin))){
|
||||
if (Controller::conf.getString("logfile") == ""){
|
||||
//check for username
|
||||
if ( !Controller::Storage.isMember("account") || Controller::Storage["account"].size() < 1){
|
||||
std::string in_string = "";
|
||||
while(yna(in_string) == 'x'){
|
||||
std::cout << "Account not set, do you want to create an account? (y)es, (n)o, (a)bort: ";
|
||||
std::cout.flush();
|
||||
std::getline(std::cin, in_string);
|
||||
if (yna(in_string) == 'y'){
|
||||
//create account
|
||||
std::string usr_string = "";
|
||||
while(!(Controller::Storage.isMember("account") && Controller::Storage["account"].size() > 0)){
|
||||
std::cout << "Please type in the username, a colon and a password in the following format; username:password" << std::endl << ": ";
|
||||
std::cout.flush();
|
||||
std::getline(std::cin, usr_string);
|
||||
createAccount(usr_string);
|
||||
}
|
||||
}else if(yna(in_string) == 'a'){
|
||||
//abort controller startup
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
//check for protocols
|
||||
if ( !Controller::Storage.isMember("config") || !Controller::Storage["config"].isMember("protocols") || Controller::Storage["config"]["protocols"].size() < 1){
|
||||
std::string in_string = "";
|
||||
while(yna(in_string) == 'x'){
|
||||
std::cout << "Protocols not set, do you want to enable default protocols? (y)es, (n)o, (a)bort: ";
|
||||
std::cout.flush();
|
||||
std::getline(std::cin, in_string);
|
||||
if (yna(in_string) == 'y'){
|
||||
//create protocols
|
||||
jsonForEach(Controller::capabilities["connectors"], it) {
|
||||
if (!it->isMember("required")){
|
||||
JSON::Value newProtocol;
|
||||
newProtocol["connector"] = it.key();
|
||||
Controller::Storage["config"]["protocols"].append(newProtocol);
|
||||
if (Controller::isTerminal){
|
||||
//check for username
|
||||
if ( !Controller::Storage.isMember("account") || Controller::Storage["account"].size() < 1){
|
||||
std::string in_string = "";
|
||||
while(yna(in_string) == 'x'){
|
||||
std::cout << "Account not set, do you want to create an account? (y)es, (n)o, (a)bort: ";
|
||||
std::cout.flush();
|
||||
std::getline(std::cin, in_string);
|
||||
switch (yna(in_string)){
|
||||
case 'y':{
|
||||
//create account
|
||||
std::string usr_string = "";
|
||||
while(!(Controller::Storage.isMember("account") && Controller::Storage["account"].size() > 0)){
|
||||
std::cout << "Please type in the username, a colon and a password in the following format; username:password" << std::endl << ": ";
|
||||
std::cout.flush();
|
||||
std::getline(std::cin, usr_string);
|
||||
createAccount(usr_string);
|
||||
}
|
||||
}
|
||||
}else if(yna(in_string) == 'a'){
|
||||
//abort controller startup
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case 'a': return 0; //abort bootup
|
||||
case 't':
|
||||
createAccount("test:test");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}else{//logfile is enabled
|
||||
//check for username
|
||||
if ( !Controller::Storage.isMember("account") || Controller::Storage["account"].size() < 1){
|
||||
std::cout << "No login configured. To create one, attempt to login through the web interface on port " << Controller::conf.getInteger("port") << " and follow the instructions." << std::endl;
|
||||
}
|
||||
//check for protocols
|
||||
if ( !Controller::Storage.isMember("config") || !Controller::Storage["config"].isMember("protocols") || Controller::Storage["config"]["protocols"].size() < 1){
|
||||
std::cout << "No protocols enabled, remember to set them up through the web interface on port " << Controller::conf.getInteger("port") << " or API." << std::endl;
|
||||
}
|
||||
//check for protocols
|
||||
if ( !Controller::Storage.isMember("config") || !Controller::Storage["config"].isMember("protocols") || Controller::Storage["config"]["protocols"].size() < 1){
|
||||
std::string in_string = "";
|
||||
while(yna(in_string) == 'x'){
|
||||
std::cout << "Protocols not set, do you want to enable default protocols? (y)es, (n)o, (a)bort: ";
|
||||
std::cout.flush();
|
||||
std::getline(std::cin, in_string);
|
||||
if (yna(in_string) == 'y'){
|
||||
//create protocols
|
||||
jsonForEach(Controller::capabilities["connectors"], it) {
|
||||
if (!it->isMember("required")){
|
||||
JSON::Value newProtocol;
|
||||
newProtocol["connector"] = it.key();
|
||||
Controller::Storage["config"]["protocols"].append(newProtocol);
|
||||
}
|
||||
}
|
||||
}else if(yna(in_string) == 'a'){
|
||||
//abort controller startup
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Check if we have a usable server, if not, print messages with helpful hints
|
||||
{
|
||||
std::string web_port = JSON::Value((long long)Controller::conf.getInteger("port")).asString();
|
||||
//check for username
|
||||
if ( !Controller::Storage.isMember("account") || Controller::Storage["account"].size() < 1){
|
||||
Controller::Log("CONF", "No login configured. To create one, attempt to login through the web interface on port "+web_port+" and follow the instructions.");
|
||||
}
|
||||
//check for protocols
|
||||
if ( !Controller::Storage.isMember("config") || !Controller::Storage["config"].isMember("protocols") || Controller::Storage["config"]["protocols"].size() < 1){
|
||||
Controller::Log("CONF", "No protocols enabled, remember to set them up through the web interface on port "+web_port+" or API.");
|
||||
}
|
||||
//check for streams - regardless of logfile setting
|
||||
if ( !Controller::Storage.isMember("streams") || Controller::Storage["streams"].size() < 1){
|
||||
std::cout << "No streams configured, remember to set up streams through the web interface on port " << Controller::conf.getInteger("port") << " or API." << std::endl;
|
||||
Controller::Log("CONF", "No streams configured, remember to set up streams through the web interface on port "+web_port+" or API.");
|
||||
}
|
||||
}//connected to a terminal
|
||||
}
|
||||
|
||||
Controller::Log("CONF", "Controller started");
|
||||
Controller::conf.activate();//activate early, so threads aren't killed.
|
||||
|
|
|
@ -20,12 +20,25 @@ namespace Controller{
|
|||
unsigned long long logCounter = 0;
|
||||
bool configChanged = false;
|
||||
bool restarting = false;
|
||||
bool isTerminal = false;
|
||||
bool isColorized = false;
|
||||
|
||||
///\brief Store and print a log message.
|
||||
///\param kind The type of message.
|
||||
///\param message The message to be logged.
|
||||
void Log(std::string kind, std::string message){
|
||||
tthread::lock_guard<tthread::mutex> guard(logMutex);
|
||||
std::string color_time, color_msg, color_end;
|
||||
if (Controller::isColorized){
|
||||
color_end = "\033[0m";
|
||||
color_time = "\033[2m";
|
||||
color_msg = color_end;
|
||||
if (kind == "CONF"){color_msg = "\033[0;1;37m";}
|
||||
if (kind == "FAIL"){color_msg = "\033[0;1;31m";}
|
||||
if (kind == "ERROR"){color_msg = "\033[0;31m";}
|
||||
if (kind == "WARN"){color_msg = "\033[0;1;33m";}
|
||||
if (kind == "INFO"){color_msg = "\033[0;36m";}
|
||||
}
|
||||
JSON::Value m;
|
||||
m.append(Util::epoch());
|
||||
m.append(kind);
|
||||
|
@ -38,7 +51,7 @@ namespace Controller{
|
|||
time(&rawtime);
|
||||
timeinfo = localtime(&rawtime);
|
||||
strftime(buffer, 100, "%F %H:%M:%S", timeinfo);
|
||||
std::cout << "[" << buffer << "] " << kind << ": " << message << std::endl;
|
||||
std::cout << color_time << "[" << buffer << "] " << color_msg << kind << ": " << message << color_end << std::endl;
|
||||
logCounter++;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,8 @@ namespace Controller {
|
|||
extern tthread::mutex configMutex;///< Mutex for server config access.
|
||||
extern bool configChanged; ///< Bool that indicates config must be written to SHM.
|
||||
extern bool restarting;///< Signals if the controller is shutting down (false) or restarting (true).
|
||||
extern bool isTerminal;///< True if connected to a terminal and not a log file.
|
||||
extern bool isColorized;///< True if we colorize the output
|
||||
extern unsigned long long logCounter; ///<Count of logged messages since boot
|
||||
|
||||
/// Store and print a log message.
|
||||
|
|
Loading…
Add table
Reference in a new issue