...
This commit is contained in:
parent
9e377f6b35
commit
9ce14495b7
@ -65,7 +65,7 @@ void list_servers() {
|
||||
if (ss.init(server.name, service))
|
||||
{
|
||||
if (ss.is_healthy())
|
||||
serviceticks += ":tick: ";
|
||||
serviceticks += ":tick: :tick: :cross: ";
|
||||
else
|
||||
serviceticks += ":cross: ";
|
||||
}
|
||||
|
@ -7,36 +7,81 @@
|
||||
#include <sstream>
|
||||
#include <codecvt>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
|
||||
// Helper function to replace all occurrences of a substring in a regular string
|
||||
std::wstring replace_all(const std::string& str, const std::string& from, const std::wstring& to) {
|
||||
std::wstring result;
|
||||
size_t start_pos = 0;
|
||||
size_t find_pos;
|
||||
enum kTextColors {
|
||||
kTextColor_Default,
|
||||
kTextColor_Red,
|
||||
kTextColor_Green,
|
||||
kTextColor_Yellow,
|
||||
kTextColor_Blue,
|
||||
kTextColor_Magenta,
|
||||
kTextColor_Cyan
|
||||
};
|
||||
|
||||
while ((find_pos = str.find(from, start_pos)) != std::string::npos) {
|
||||
result += std::wstring(str.begin() + start_pos, str.begin() + find_pos);
|
||||
result += to;
|
||||
start_pos = find_pos + from.length();
|
||||
struct coloredText {
|
||||
std::string text;
|
||||
kTextColors color;
|
||||
};
|
||||
|
||||
const std::map<std::string, coloredText> kReplacements = {
|
||||
{":tick:", {"✓", kTextColor_Green}},
|
||||
{":cross:", {"✗", kTextColor_Red}},
|
||||
{":warning:", {"⚠️", kTextColor_Yellow}},
|
||||
{":info:", {"ℹ️", kTextColor_Blue}},
|
||||
{":check:", {"✅", kTextColor_Green}},
|
||||
{":x:", {"❌", kTextColor_Red}}
|
||||
};
|
||||
|
||||
// Helper function to get ANSI color code
|
||||
std::string get_color_code(kTextColors color) {
|
||||
switch (color) {
|
||||
case kTextColor_Red: return "\033[1;31m";
|
||||
case kTextColor_Green: return "\033[1;32m";
|
||||
case kTextColor_Yellow: return "\033[1;33m";
|
||||
case kTextColor_Blue: return "\033[1;34m";
|
||||
case kTextColor_Magenta: return "\033[1;35m";
|
||||
case kTextColor_Cyan: return "\033[1;36m";
|
||||
default: return "\033[0m";
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to process a cell with replacements
|
||||
std::string process_cell(const std::string& cell) {
|
||||
std::string result;
|
||||
size_t pos = 0;
|
||||
while (pos < cell.length()) {
|
||||
bool found_replacement = false;
|
||||
for (const auto& [key, value] : kReplacements) {
|
||||
if (cell.compare(pos, key.length(), key) == 0) {
|
||||
result += get_color_code(value.color) + value.text + "\033[0m";
|
||||
pos += key.length();
|
||||
found_replacement = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found_replacement) {
|
||||
result += cell[pos];
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
result += std::wstring(str.begin() + start_pos, str.end());
|
||||
return result;
|
||||
}
|
||||
|
||||
// Helper function to replace all occurrences of a substring in a wide string
|
||||
std::wstring replace_all(const std::wstring& str, const std::string& from, const std::wstring& to) {
|
||||
std::wstring result;
|
||||
size_t start_pos = 0;
|
||||
size_t find_pos;
|
||||
std::wstring from_w(from.begin(), from.end());
|
||||
|
||||
while ((find_pos = str.find(from_w, start_pos)) != std::wstring::npos) {
|
||||
result += str.substr(start_pos, find_pos - start_pos);
|
||||
result += to;
|
||||
start_pos = find_pos + from_w.length();
|
||||
// Helper function to get visible length (ignoring color codes)
|
||||
size_t get_visible_length(const std::string& str) {
|
||||
size_t length = 0;
|
||||
bool in_color_code = false;
|
||||
for (size_t i = 0; i < str.length(); ++i) {
|
||||
if (str[i] == '\033') {
|
||||
while (i < str.length() && str[i] != 'm') {
|
||||
i++;
|
||||
}
|
||||
} else {
|
||||
length++;
|
||||
}
|
||||
}
|
||||
result += str.substr(start_pos);
|
||||
return result;
|
||||
return length;
|
||||
}
|
||||
|
||||
tableprint::tableprint(const std::string title) : title(title) {
|
||||
@ -51,24 +96,48 @@ void tableprint::set_title(const std::string title) {
|
||||
}
|
||||
|
||||
void tableprint::add_row(const std::vector<std::string>& row) {
|
||||
rows.push_back(row);
|
||||
std::vector<std::string> trimmed_row;
|
||||
for (const auto& cell : row) {
|
||||
// Trim whitespace from start and end
|
||||
auto start = cell.find_first_not_of(" \t");
|
||||
auto end = cell.find_last_not_of(" \t");
|
||||
if (start == std::string::npos) {
|
||||
trimmed_row.push_back("");
|
||||
} else {
|
||||
trimmed_row.push_back(cell.substr(start, end - start + 1));
|
||||
}
|
||||
}
|
||||
rows.push_back(trimmed_row);
|
||||
}
|
||||
|
||||
void tableprint::print() {
|
||||
if (rows.empty()) return;
|
||||
|
||||
// Calculate column widths
|
||||
std::vector<size_t> col_widths(rows[0].size(), 0);
|
||||
// First, process all cells and store the processed versions
|
||||
std::vector<std::vector<std::string>> processed_rows;
|
||||
for (const auto& row : rows) {
|
||||
std::vector<std::string> processed_row;
|
||||
for (const auto& cell : row) {
|
||||
processed_row.push_back(process_cell(cell));
|
||||
}
|
||||
processed_rows.push_back(processed_row);
|
||||
}
|
||||
|
||||
// Calculate column widths based on processed cells (ignoring color codes)
|
||||
std::vector<size_t> col_widths(rows[0].size(), 0);
|
||||
for (const auto& row : processed_rows) {
|
||||
for (size_t i = 0; i < row.size(); ++i) {
|
||||
std::string cell = row[i];
|
||||
// Count occurrences of :tick: and :cross:
|
||||
size_t tick_count = std::count(cell.begin(), cell.end(), ':') / 2;
|
||||
// Adjust width: original length minus 5 for each :tick: or :cross: (since they become 1 char)
|
||||
col_widths[i] = std::max(col_widths[i], cell.length() - (tick_count * 5));
|
||||
col_widths[i] = std::max(col_widths[i], get_visible_length(row[i]));
|
||||
}
|
||||
}
|
||||
|
||||
// Debug output
|
||||
std::cerr << "Column widths: ";
|
||||
for (size_t width : col_widths) {
|
||||
std::cerr << width << " ";
|
||||
}
|
||||
std::cerr << std::endl;
|
||||
|
||||
// Calculate total table width
|
||||
size_t total_width = 0;
|
||||
for (size_t width : col_widths) {
|
||||
@ -80,29 +149,27 @@ void tableprint::print() {
|
||||
if (!title.empty()) {
|
||||
std::cout << "\033[90m"; // Dark grey color for borders
|
||||
std::cout << "┌";
|
||||
for (size_t i = 0; i < total_width; ++i) {
|
||||
std::cout << "-";
|
||||
for (size_t i = 0; i < rows[0].size(); ++i) {
|
||||
std::cout << std::string(col_widths[i] + 2, '-');
|
||||
if (i < rows[0].size() - 1) std::cout << "┬";
|
||||
}
|
||||
std::cout << "┐" << std::endl;
|
||||
|
||||
std::cout << "│" << "\033[1;37m"; // White color for title
|
||||
size_t padding = (total_width - title.length()) / 2;
|
||||
for (size_t i = 0; i < padding; ++i) {
|
||||
std::cout << " ";
|
||||
}
|
||||
std::cout << title;
|
||||
for (size_t i = 0; i < total_width - title.length() - padding; ++i) {
|
||||
std::cout << " ";
|
||||
size_t title_width = 0;
|
||||
for (size_t width : col_widths) {
|
||||
title_width += width + 2; // +2 for padding
|
||||
}
|
||||
title_width += col_widths.size() - 1; // Add space for vertical borders
|
||||
size_t padding = (title_width - title.length()) / 2;
|
||||
std::cout << std::string(padding, ' ') << title << std::string(title_width - title.length() - padding, ' ');
|
||||
std::cout << "\033[90m│" << std::endl;
|
||||
|
||||
// Use └─┴─┘ for bottom of title box to connect with table
|
||||
std::cout << "├";
|
||||
for (size_t i = 0; i < rows[0].size(); ++i) {
|
||||
for (size_t j = 0; j < col_widths[i] + 2; ++j) {
|
||||
std::cout << "-";
|
||||
}
|
||||
if (i < rows[0].size() - 1) std::cout << "┬";
|
||||
std::cout << std::string(col_widths[i] + 2, '-');
|
||||
if (i < rows[0].size() - 1) std::cout << "┼";
|
||||
}
|
||||
std::cout << "┤" << std::endl;
|
||||
} else {
|
||||
@ -110,9 +177,7 @@ void tableprint::print() {
|
||||
std::cout << "\033[90m"; // Dark grey color for borders
|
||||
std::cout << "┌";
|
||||
for (size_t i = 0; i < rows[0].size(); ++i) {
|
||||
for (size_t j = 0; j < col_widths[i] + 2; ++j) {
|
||||
std::cout << "-";
|
||||
}
|
||||
std::cout << std::string(col_widths[i] + 2, '-');
|
||||
if (i < rows[0].size() - 1) std::cout << "┬";
|
||||
}
|
||||
std::cout << "┐" << std::endl;
|
||||
@ -121,9 +186,9 @@ void tableprint::print() {
|
||||
// Print header
|
||||
std::cout << "│";
|
||||
std::cout << "\033[1;36m"; // Cyan color for header
|
||||
for (size_t i = 0; i < rows[0].size(); ++i) {
|
||||
std::cout << " " << std::setw(col_widths[i]) << std::left << rows[0][i] << " ";
|
||||
if (i < rows[0].size() - 1) {
|
||||
for (size_t i = 0; i < processed_rows[0].size(); ++i) {
|
||||
std::cout << " " << std::setw(col_widths[i]) << std::left << processed_rows[0][i] << " ";
|
||||
if (i < processed_rows[0].size() - 1) {
|
||||
std::cout << "\033[90m│\033[1;36m"; // Border color then back to cyan
|
||||
} else {
|
||||
std::cout << "\033[90m│"; // Just border color for last column
|
||||
@ -142,50 +207,21 @@ void tableprint::print() {
|
||||
std::cout << "┤" << std::endl;
|
||||
|
||||
// Print rows
|
||||
for (size_t row_idx = 1; row_idx < rows.size(); ++row_idx) {
|
||||
const auto& row = rows[row_idx];
|
||||
for (size_t row_idx = 1; row_idx < processed_rows.size(); ++row_idx) {
|
||||
const auto& row = processed_rows[row_idx];
|
||||
std::cout << "│";
|
||||
for (size_t i = 0; i < row.size(); ++i) {
|
||||
std::string cell = row[i];
|
||||
// Replace :tick: and :cross: with colored symbols
|
||||
std::string processed_cell;
|
||||
size_t pos = 0;
|
||||
while (pos < cell.length()) {
|
||||
if (cell.compare(pos, 6, ":tick:") == 0) {
|
||||
processed_cell += "\033[1;32m✓\033[0m";
|
||||
pos += 6;
|
||||
} else if (cell.compare(pos, 7, ":cross:") == 0) {
|
||||
processed_cell += "\033[1;31m✗\033[0m";
|
||||
pos += 7;
|
||||
} else {
|
||||
processed_cell += cell[pos];
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
|
||||
// Set the appropriate color for the row
|
||||
if (row_idx % 2 == 1) {
|
||||
std::cout << " " << "\033[38;5;142m";
|
||||
if (cell.find(":tick:") != std::string::npos || cell.find(":cross:") != std::string::npos) {
|
||||
std::cout << " " << processed_cell << " ";
|
||||
} else {
|
||||
std::cout << std::setw(col_widths[i]) << std::left << processed_cell;
|
||||
}
|
||||
std::cout << "\033[90m" << " │";
|
||||
std::cout << " " << "\033[38;5;142m" << std::setw(col_widths[i]) << std::left << row[i] << "\033[90m" << " │";
|
||||
} else {
|
||||
std::cout << " " << "\033[38;5;250m";
|
||||
if (cell.find(":tick:") != std::string::npos || cell.find(":cross:") != std::string::npos) {
|
||||
std::cout << " " << processed_cell << " ";
|
||||
} else {
|
||||
std::cout << std::setw(col_widths[i]) << std::left << processed_cell;
|
||||
}
|
||||
std::cout << "\033[90m" << " │";
|
||||
std::cout << " " << "\033[38;5;250m" << std::setw(col_widths[i]) << std::left << row[i] << "\033[90m" << " │";
|
||||
}
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
// Print row separator if not the last row
|
||||
if (row_idx < rows.size() - 1) {
|
||||
if (row_idx < processed_rows.size() - 1) {
|
||||
std::cout << "├";
|
||||
for (size_t i = 0; i < rows[0].size(); ++i) {
|
||||
for (size_t j = 0; j < col_widths[i] + 2; ++j) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user