mirror of
https://github.com/ashaduri/gsmartcontrol.git
synced 2026-09-25 05:15:33 +00:00
Support saving smartctl output to text (using old text format) instead of json (#76).
This commit is contained in:
@@ -198,6 +198,26 @@ hz::ExpectedVoid<SmartctlParserError> SmartctlJsonAtaParser::parse_section_info(
|
||||
|
||||
static const std::vector<std::tuple<std::string, std::string, PropertyRetrievalFunc>> json_keys = {
|
||||
|
||||
{"smartctl/output", _("Smartctl Text Output"), // the old text format
|
||||
[](const nlohmann::json& root_node, const std::string& key, const std::string& displayable_name)
|
||||
-> hz::ExpectedValue<StorageProperty, SmartctlParserError>
|
||||
{
|
||||
auto table_node = get_node(root_node, "smartctl/output");
|
||||
if (table_node.has_value() && table_node->is_array() && !table_node.value().empty()) {
|
||||
std::vector<std::string> lines;
|
||||
for (const auto& entry : table_node.value()) {
|
||||
lines.emplace_back(entry.get<std::string>());
|
||||
}
|
||||
StorageProperty p;
|
||||
p.set_name(key, displayable_name);
|
||||
p.value = hz::string_join(lines, "\n");
|
||||
p.show_in_ui = false;
|
||||
return p;
|
||||
}
|
||||
return hz::Unexpected(SmartctlParserError::KeyNotFound, fmt::format("Error getting key {} from JSON data.", key));
|
||||
}
|
||||
},
|
||||
|
||||
{"device/type", _("Smartctl Device Type"), // nvme, sat, etc.
|
||||
[](const nlohmann::json& root_node, const std::string& key, const std::string& displayable_name)
|
||||
-> hz::ExpectedValue<StorageProperty, SmartctlParserError>
|
||||
|
||||
@@ -75,6 +75,26 @@ hz::ExpectedVoid<SmartctlParserError> SmartctlJsonBasicParser::parse_section_bas
|
||||
// 2. Present in devices for which we do not have specialized parsers (USB, etc.)
|
||||
static const std::vector<std::tuple<std::string, std::string, PropertyRetrievalFunc>> info_keys = {
|
||||
|
||||
{"smartctl/output", _("Smartctl Text Output"), // the old text format
|
||||
[](const nlohmann::json& root_node, const std::string& key, const std::string& displayable_name)
|
||||
-> hz::ExpectedValue<StorageProperty, SmartctlParserError>
|
||||
{
|
||||
auto table_node = get_node(root_node, "smartctl/output");
|
||||
if (table_node.has_value() && table_node->is_array() && !table_node.value().empty()) {
|
||||
std::vector<std::string> lines;
|
||||
for (const auto& entry : table_node.value()) {
|
||||
lines.emplace_back(entry.get<std::string>());
|
||||
}
|
||||
StorageProperty p;
|
||||
p.set_name(key, displayable_name);
|
||||
p.value = hz::string_join(lines, "\n");
|
||||
p.show_in_ui = false;
|
||||
return p;
|
||||
}
|
||||
return hz::Unexpected(SmartctlParserError::KeyNotFound, fmt::format("Error getting key {} from JSON data.", key));
|
||||
}
|
||||
},
|
||||
|
||||
{"device/type", _("Smartctl Device Type"), // nvme, sat, etc.
|
||||
[](const nlohmann::json& root_node, const std::string& key, const std::string& displayable_name)
|
||||
-> hz::ExpectedValue<StorageProperty, SmartctlParserError>
|
||||
|
||||
@@ -114,6 +114,26 @@ hz::ExpectedVoid<SmartctlParserError> SmartctlJsonNvmeParser::parse_section_info
|
||||
|
||||
static const std::vector<std::tuple<std::string, std::string, PropertyRetrievalFunc>> json_keys = {
|
||||
|
||||
{"smartctl/output", _("Smartctl Text Output"), // the old text format
|
||||
[](const nlohmann::json& root_node, const std::string& key, const std::string& displayable_name)
|
||||
-> hz::ExpectedValue<StorageProperty, SmartctlParserError>
|
||||
{
|
||||
auto table_node = get_node(root_node, "smartctl/output");
|
||||
if (table_node.has_value() && table_node->is_array() && !table_node.value().empty()) {
|
||||
std::vector<std::string> lines;
|
||||
for (const auto& entry : table_node.value()) {
|
||||
lines.emplace_back(entry.get<std::string>());
|
||||
}
|
||||
StorageProperty p;
|
||||
p.set_name(key, displayable_name);
|
||||
p.value = hz::string_join(lines, "\n");
|
||||
p.show_in_ui = false;
|
||||
return p;
|
||||
}
|
||||
return hz::Unexpected(SmartctlParserError::KeyNotFound, fmt::format("Error getting key {} from JSON data.", key));
|
||||
}
|
||||
},
|
||||
|
||||
{"device/type", _("Smartctl Device Type"), // nvme, sat, etc.
|
||||
[](const nlohmann::json& root_node, const std::string& key, const std::string& displayable_name)
|
||||
-> hz::ExpectedValue<StorageProperty, SmartctlParserError>
|
||||
|
||||
@@ -231,6 +231,16 @@ hz::ExpectedVoid<SmartctlParserError> SmartctlTextAtaParser::parse(std::string_v
|
||||
return hz::Unexpected(SmartctlParserError::IncompatibleVersion, "Incompatible smartctl version.");
|
||||
}
|
||||
|
||||
// Full text output
|
||||
{
|
||||
StorageProperty p;
|
||||
p.set_name("smartctl/output", "Smartctl Text Output");
|
||||
p.reported_value = smartctl_output;
|
||||
p.value = p.reported_value; // string-type value
|
||||
p.show_in_ui = false;
|
||||
add_property(p);
|
||||
}
|
||||
|
||||
|
||||
// sections
|
||||
|
||||
|
||||
@@ -67,6 +67,16 @@ hz::ExpectedVoid<SmartctlParserError> SmartctlTextBasicParser::parse(std::string
|
||||
add_property(p);
|
||||
}
|
||||
|
||||
// Full text output
|
||||
{
|
||||
StorageProperty p;
|
||||
p.set_name("smartctl/output", "Smartctl Text Output");
|
||||
p.reported_value = output;
|
||||
p.value = p.reported_value; // string-type value
|
||||
p.show_in_ui = false;
|
||||
add_property(p);
|
||||
}
|
||||
|
||||
bool is_raid = false;
|
||||
|
||||
// Detect type. note: we can't distinguish between sata and scsi (on linux, for -d ata switch).
|
||||
|
||||
@@ -848,6 +848,14 @@ void GscInfoWindow::on_save_info_button_clicked()
|
||||
specific_filter->add_pattern("*.json");
|
||||
specific_filter->add_pattern("*.txt");
|
||||
|
||||
Glib::RefPtr<Gtk::FileFilter> json_filter = Gtk::FileFilter::create();
|
||||
json_filter->set_name(_("JSON Files"));
|
||||
json_filter->add_pattern("*.json");
|
||||
|
||||
Glib::RefPtr<Gtk::FileFilter> txt_filter = Gtk::FileFilter::create();
|
||||
txt_filter->set_name(_("Text Files"));
|
||||
txt_filter->add_pattern("*.txt");
|
||||
|
||||
Glib::RefPtr<Gtk::FileFilter> all_filter = Gtk::FileFilter::create();
|
||||
all_filter->set_name(_("All Files"));
|
||||
all_filter->add_pattern("*");
|
||||
@@ -860,6 +868,8 @@ void GscInfoWindow::on_save_info_button_clicked()
|
||||
gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog.get()), TRUE);
|
||||
|
||||
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog.get()), specific_filter->gobj());
|
||||
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog.get()), json_filter->gobj());
|
||||
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog.get()), txt_filter->gobj());
|
||||
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog.get()), all_filter->gobj());
|
||||
|
||||
if (!last_dir.empty())
|
||||
@@ -881,6 +891,8 @@ void GscInfoWindow::on_save_info_button_clicked()
|
||||
dialog.set_do_overwrite_confirmation(true);
|
||||
|
||||
dialog.add_filter(specific_filter);
|
||||
dialog.add_filter(json_filter);
|
||||
dialog.add_filter(txt_filter);
|
||||
dialog.add_filter(all_filter);
|
||||
|
||||
if (!last_dir.empty())
|
||||
@@ -907,14 +919,27 @@ void GscInfoWindow::on_save_info_button_clicked()
|
||||
#endif
|
||||
rconfig::set_data("gui/drive_data_open_save_dir", last_dir);
|
||||
|
||||
bool txt_selected = gtk_file_chooser_get_filter(GTK_FILE_CHOOSER(dialog.get())) == txt_filter->gobj();
|
||||
|
||||
if (file.extension() != ".json" && file.extension() != ".txt") {
|
||||
file += ".json";
|
||||
file += (txt_selected ? ".txt" : ".json");
|
||||
}
|
||||
|
||||
bool save_txt = txt_selected || file.extension() == ".txt";
|
||||
|
||||
std::string data = this->drive_->get_full_output();
|
||||
if (data.empty()) {
|
||||
data = this->drive_->get_basic_output();
|
||||
}
|
||||
if (save_txt) {
|
||||
if (auto p = this->drive_->get_property_repository().lookup_property("smartctl/output"); !p.empty()) {
|
||||
const std::string text_output = p.get_value<std::string>();
|
||||
if (!text_output.empty()) {
|
||||
data = text_output;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const std::error_code ec = hz::fs_file_put_contents(file, data);
|
||||
if (ec) {
|
||||
gui_show_error_dialog(_("Cannot save SMART data to file"), ec.message(), this);
|
||||
|
||||
Reference in New Issue
Block a user