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':
|
case 'a': case 'A':
|
||||||
return 'a';
|
return 'a';
|
||||||
break;
|
break;
|
||||||
|
case 't': case 'T':
|
||||||
|
return 't';
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return 'x';
|
return 'x';
|
||||||
break;
|
break;
|
||||||
|
@ -91,7 +94,7 @@ void createAccount (std::string account){
|
||||||
if (colon != std::string::npos && colon != 0 && colon != account.size()){
|
if (colon != std::string::npos && colon != 0 && colon != account.size()){
|
||||||
std::string uname = account.substr(0, colon);
|
std::string uname = account.substr(0, colon);
|
||||||
std::string pword = account.substr(colon + 1, std::string::npos);
|
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);
|
Controller::Storage["account"][uname]["password"] = Secure::md5(pword);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -155,6 +158,7 @@ void statusMonitor(void * np){
|
||||||
/// shutdown reason
|
/// shutdown reason
|
||||||
/// ~~~~~~~~~~~~~~~
|
/// ~~~~~~~~~~~~~~~
|
||||||
int main_loop(int argc, char ** argv){
|
int main_loop(int argc, char ** argv){
|
||||||
|
Controller::isTerminal = Controller::isColorized = isatty(fileno(stdin));
|
||||||
Controller::Storage = JSON::fromFile("config.json");
|
Controller::Storage = JSON::fromFile("config.json");
|
||||||
JSON::Value stored_port = JSON::fromString("{\"long\":\"port\", \"short\":\"p\", \"arg\":\"integer\", \"help\":\"TCP port to listen on.\"}");
|
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"];
|
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));
|
DEBUG_MSG(DLVL_ERROR, "Could not redirect output to %s: %s",Controller::conf.getString("logfile").c_str(),strerror(errno));
|
||||||
return 7;
|
return 7;
|
||||||
}else{
|
}else{
|
||||||
|
Controller::isTerminal = Controller::isColorized = false;
|
||||||
dup2(output,STDOUT_FILENO);
|
dup2(output,STDOUT_FILENO);
|
||||||
dup2(output,STDERR_FILENO);
|
dup2(output,STDERR_FILENO);
|
||||||
time_t rawtime;
|
time_t rawtime;
|
||||||
|
@ -250,67 +255,73 @@ int main_loop(int argc, char ** argv){
|
||||||
createAccount(Controller::conf.getString("account"));
|
createAccount(Controller::conf.getString("account"));
|
||||||
|
|
||||||
//if a terminal is connected and we're not logging to file
|
//if a terminal is connected and we're not logging to file
|
||||||
if (isatty(fileno(stdin))){
|
if (Controller::isTerminal){
|
||||||
if (Controller::conf.getString("logfile") == ""){
|
//check for username
|
||||||
//check for username
|
if ( !Controller::Storage.isMember("account") || Controller::Storage["account"].size() < 1){
|
||||||
if ( !Controller::Storage.isMember("account") || Controller::Storage["account"].size() < 1){
|
std::string in_string = "";
|
||||||
std::string in_string = "";
|
while(yna(in_string) == 'x'){
|
||||||
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 << "Account not set, do you want to create an account? (y)es, (n)o, (a)bort: ";
|
std::cout.flush();
|
||||||
std::cout.flush();
|
std::getline(std::cin, in_string);
|
||||||
std::getline(std::cin, in_string);
|
switch (yna(in_string)){
|
||||||
if (yna(in_string) == 'y'){
|
case 'y':{
|
||||||
//create account
|
//create account
|
||||||
std::string usr_string = "";
|
std::string usr_string = "";
|
||||||
while(!(Controller::Storage.isMember("account") && Controller::Storage["account"].size() > 0)){
|
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 << "Please type in the username, a colon and a password in the following format; username:password" << std::endl << ": ";
|
||||||
std::cout.flush();
|
std::cout.flush();
|
||||||
std::getline(std::cin, usr_string);
|
std::getline(std::cin, usr_string);
|
||||||
createAccount(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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}else if(yna(in_string) == 'a'){
|
break;
|
||||||
//abort controller startup
|
case 'a': return 0; //abort bootup
|
||||||
return 0;
|
case 't':
|
||||||
}
|
createAccount("test:test");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}else{//logfile is enabled
|
}
|
||||||
//check for username
|
//check for protocols
|
||||||
if ( !Controller::Storage.isMember("account") || Controller::Storage["account"].size() < 1){
|
if ( !Controller::Storage.isMember("config") || !Controller::Storage["config"].isMember("protocols") || Controller::Storage["config"]["protocols"].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;
|
std::string in_string = "";
|
||||||
}
|
while(yna(in_string) == 'x'){
|
||||||
//check for protocols
|
std::cout << "Protocols not set, do you want to enable default protocols? (y)es, (n)o, (a)bort: ";
|
||||||
if ( !Controller::Storage.isMember("config") || !Controller::Storage["config"].isMember("protocols") || Controller::Storage["config"]["protocols"].size() < 1){
|
std::cout.flush();
|
||||||
std::cout << "No protocols enabled, remember to set them up through the web interface on port " << Controller::conf.getInteger("port") << " or API." << std::endl;
|
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
|
//check for streams - regardless of logfile setting
|
||||||
if ( !Controller::Storage.isMember("streams") || Controller::Storage["streams"].size() < 1){
|
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::Log("CONF", "Controller started");
|
||||||
Controller::conf.activate();//activate early, so threads aren't killed.
|
Controller::conf.activate();//activate early, so threads aren't killed.
|
||||||
|
|
|
@ -20,12 +20,25 @@ namespace Controller{
|
||||||
unsigned long long logCounter = 0;
|
unsigned long long logCounter = 0;
|
||||||
bool configChanged = false;
|
bool configChanged = false;
|
||||||
bool restarting = false;
|
bool restarting = false;
|
||||||
|
bool isTerminal = false;
|
||||||
|
bool isColorized = false;
|
||||||
|
|
||||||
///\brief Store and print a log message.
|
///\brief Store and print a log message.
|
||||||
///\param kind The type of message.
|
///\param kind The type of message.
|
||||||
///\param message The message to be logged.
|
///\param message The message to be logged.
|
||||||
void Log(std::string kind, std::string message){
|
void Log(std::string kind, std::string message){
|
||||||
tthread::lock_guard<tthread::mutex> guard(logMutex);
|
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;
|
JSON::Value m;
|
||||||
m.append(Util::epoch());
|
m.append(Util::epoch());
|
||||||
m.append(kind);
|
m.append(kind);
|
||||||
|
@ -38,7 +51,7 @@ namespace Controller{
|
||||||
time(&rawtime);
|
time(&rawtime);
|
||||||
timeinfo = localtime(&rawtime);
|
timeinfo = localtime(&rawtime);
|
||||||
strftime(buffer, 100, "%F %H:%M:%S", timeinfo);
|
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++;
|
logCounter++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,8 @@ namespace Controller {
|
||||||
extern tthread::mutex configMutex;///< Mutex for server config access.
|
extern tthread::mutex configMutex;///< Mutex for server config access.
|
||||||
extern bool configChanged; ///< Bool that indicates config must be written to SHM.
|
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 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
|
extern unsigned long long logCounter; ///<Count of logged messages since boot
|
||||||
|
|
||||||
/// Store and print a log message.
|
/// Store and print a log message.
|
||||||
|
|
Loading…
Add table
Reference in a new issue