aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsaturneric <[email protected]>2023-10-27 13:21:03 +0000
committersaturneric <[email protected]>2023-10-27 13:21:03 +0000
commit41c12e92031284e357bab04fe6e08b45c6dd3ba8 (patch)
treee5750afe5feee6cca15aa9b3b0915012047e3aba
parentfeat: gather more gnupg info to rt (diff)
downloadGpgFrontend-41c12e92031284e357bab04fe6e08b45c6dd3ba8.tar.gz
GpgFrontend-41c12e92031284e357bab04fe6e08b45c6dd3ba8.zip
feat: improve thread system and gathering gnupg options info to rt
-rw-r--r--src/core/function/gpg/GpgCommandExecutor.cpp59
-rw-r--r--src/core/function/gpg/GpgCommandExecutor.h5
-rw-r--r--src/core/function/gpg/GpgKeyOpera.cpp1
-rw-r--r--src/core/module/GlobalRegisterTable.cpp55
-rw-r--r--src/core/thread/Task.cpp67
-rw-r--r--src/core/thread/TaskRunnerGetter.cpp16
-rw-r--r--src/core/thread/TaskRunnerGetter.h6
-rw-r--r--src/module/integrated/gnupg_info_gathering_module/GnuPGInfoGatheringModule.cpp193
-rw-r--r--src/module/integrated/gnupg_info_gathering_module/GpgInfo.h21
-rw-r--r--src/ui/widgets/PlainTextEditorPage.cpp2
10 files changed, 261 insertions, 164 deletions
diff --git a/src/core/function/gpg/GpgCommandExecutor.cpp b/src/core/function/gpg/GpgCommandExecutor.cpp
index 3fd56d35..fb1d647d 100644
--- a/src/core/function/gpg/GpgCommandExecutor.cpp
+++ b/src/core/function/gpg/GpgCommandExecutor.cpp
@@ -33,14 +33,21 @@
#include "GpgFunctionObject.h"
#include "core/thread/DataObject.h"
#include "core/thread/TaskRunnerGetter.h"
+#include "module/Module.h"
#include "spdlog/spdlog.h"
+#include "thread/Task.h"
namespace GpgFrontend {
GpgCommandExecutor::ExecuteContext::ExecuteContext(
std::string cmd, std::vector<std::string> arguments,
- GpgCommandExecutorCallback callback, GpgCommandExecutorInteractor int_func)
- : cmd(cmd), arguments(arguments), cb_func(callback), int_func(int_func) {}
+ GpgCommandExecutorCallback callback, Module::TaskRunnerPtr task_runner,
+ GpgCommandExecutorInteractor int_func)
+ : cmd(cmd),
+ arguments(arguments),
+ cb_func(callback),
+ int_func(int_func),
+ task_runner(task_runner) {}
GpgCommandExecutor::GpgCommandExecutor(int channel)
: SingletonFunctionObject<GpgCommandExecutor>(channel) {}
@@ -52,13 +59,26 @@ void GpgCommandExecutor::ExecuteSync(ExecuteContext context) {
QObject::connect(task, &Thread::Task::SignalTaskEnd, &looper,
&QEventLoop::quit);
- GpgFrontend::Thread::TaskRunnerGetter::GetInstance()
- .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_External_Process)
- ->PostTask(task);
+ Thread::TaskRunnerPtr target_task_runner = nullptr;
- // block until task finished
- // this is to keep reference vaild until task finished
- looper.exec();
+ if (context.task_runner != nullptr) {
+ target_task_runner = context.task_runner;
+ } else {
+ target_task_runner =
+ GpgFrontend::Thread::TaskRunnerGetter::GetInstance().GetTaskRunner(
+ Thread::TaskRunnerGetter::kTaskRunnerType_External_Process);
+ }
+
+ target_task_runner->PostTask(task);
+
+ // to arvoid dead lock issue we need to check if current thread is the same as
+ // target thread. if it is, we can't call exec() because it will block the
+ // current thread.
+ if (QThread::currentThread() != target_task_runner->GetThread()) {
+ // block until task finished
+ // this is to keep reference vaild until task finished
+ looper.exec();
+ }
}
void GpgCommandExecutor::ExecuteConcurrentlyAsync(ExecuteContexts contexts) {
@@ -67,10 +87,14 @@ void GpgCommandExecutor::ExecuteConcurrentlyAsync(ExecuteContexts contexts) {
SPDLOG_INFO("gpg concurrently called cmd {}", cmd);
Thread::Task *task = build_task_from_exec_ctx(context);
- GpgFrontend::Thread::TaskRunnerGetter::GetInstance()
- .GetTaskRunner(
- Thread::TaskRunnerGetter::kTaskRunnerType_External_Process)
- ->PostTask(task);
+
+ if (context.task_runner != nullptr)
+ context.task_runner->PostTask(task);
+ else
+ GpgFrontend::Thread::TaskRunnerGetter::GetInstance()
+ .GetTaskRunner(
+ Thread::TaskRunnerGetter::kTaskRunnerType_External_Process)
+ ->PostTask(task);
}
}
@@ -92,10 +116,13 @@ void GpgCommandExecutor::ExecuteConcurrentlySync(
}
});
- GpgFrontend::Thread::TaskRunnerGetter::GetInstance()
- .GetTaskRunner(
- Thread::TaskRunnerGetter::kTaskRunnerType_External_Process)
- ->PostConcurrentTask(task);
+ if (context.task_runner != nullptr)
+ context.task_runner->PostTask(task);
+ else
+ GpgFrontend::Thread::TaskRunnerGetter::GetInstance()
+ .GetTaskRunner(
+ Thread::TaskRunnerGetter::kTaskRunnerType_External_Process)
+ ->PostTask(task);
}
looper.exec();
diff --git a/src/core/function/gpg/GpgCommandExecutor.h b/src/core/function/gpg/GpgCommandExecutor.h
index bd356b8b..fc9f2a83 100644
--- a/src/core/function/gpg/GpgCommandExecutor.h
+++ b/src/core/function/gpg/GpgCommandExecutor.h
@@ -29,6 +29,9 @@
#pragma once
#include <initializer_list>
+
+#include "core/module/Module.h"
+#include "core/thread/TaskRunner.h"
#ifndef WINDOWS
#include <boost/process.hpp>
#endif
@@ -55,11 +58,13 @@ class GPGFRONTEND_CORE_EXPORT GpgCommandExecutor
const std::vector<std::string> arguments;
const GpgCommandExecutorCallback cb_func;
const GpgCommandExecutorInteractor int_func;
+ Module::TaskRunnerPtr task_runner = nullptr;
ExecuteContext(
std::string cmd, std::vector<std::string> arguments,
GpgCommandExecutorCallback callback = [](int, std::string,
std::string) {},
+ Module::TaskRunnerPtr task_runner = nullptr,
GpgCommandExecutorInteractor int_func = [](QProcess *) {});
};
diff --git a/src/core/function/gpg/GpgKeyOpera.cpp b/src/core/function/gpg/GpgKeyOpera.cpp
index 1d31bb1d..eb7dfe9f 100644
--- a/src/core/function/gpg/GpgKeyOpera.cpp
+++ b/src/core/function/gpg/GpgKeyOpera.cpp
@@ -123,6 +123,7 @@ void GpgKeyOpera::GenerateRevokeCert(const GpgKey& key,
exit_code, p_out.size());
}
},
+ nullptr,
[](QProcess* proc) -> void {
// Code From Gpg4Win
while (proc->canReadLine()) {
diff --git a/src/core/module/GlobalRegisterTable.cpp b/src/core/module/GlobalRegisterTable.cpp
index 47552eb8..8d28dc34 100644
--- a/src/core/module/GlobalRegisterTable.cpp
+++ b/src/core/module/GlobalRegisterTable.cpp
@@ -40,12 +40,11 @@ namespace GpgFrontend::Module {
class GlobalRegisterTable::Impl {
public:
- struct Value {
- std::any value;
+ struct RTNode {
+ std::optional<std::any> value = std::nullopt;
+ std::unordered_map<std::string, std::unique_ptr<RTNode>> children;
int version = 0;
- const std::type_info& type;
-
- Value(std::any v) : value(v), type(v.type()) {}
+ const std::type_info* type = nullptr; // 保存类型信息
};
Impl(GlobalRegisterTable* parent)
@@ -55,23 +54,26 @@ class GlobalRegisterTable::Impl {
SPDLOG_DEBUG("publishing kv to rt, n: {}, k: {}, v type: {}", n, k,
v.type().name());
+ std::istringstream iss(k);
+ std::string segment;
+
int version = 0;
{
std::unique_lock lock(lock_);
- auto& sub_table =
- global_register_table_.emplace(n, SubTable{}).first->second;
-
- auto sub_it = sub_table.find(k);
- if (sub_it == sub_table.end()) {
- sub_it = sub_table.emplace(k, std::make_unique<Value>(Value{v})).first;
- } else {
- if (sub_it->second->type != v.type()) {
- return false;
- }
- sub_it->second->value = v;
+ auto& root_rt_node =
+ global_register_table_.emplace(n, std::make_unique<RTNode>())
+ .first->second;
+
+ RTNode* current = root_rt_node.get();
+ while (std::getline(iss, segment, '.')) {
+ current = current->children.emplace(segment, std::make_unique<RTNode>())
+ .first->second.get();
}
- version = ++sub_it->second->version;
+
+ current->value = v;
+ current->type = &v.type();
+ current->version++;
}
emit parent_->SignalPublish(n, k, version, v);
@@ -80,17 +82,23 @@ class GlobalRegisterTable::Impl {
std::optional<std::any> LookupKV(Namespace n, Key k) {
SPDLOG_DEBUG("looking up kv in rt, n: {}, k: {}", n, k);
+
+ std::istringstream iss(k);
+ std::string segment;
+
std::optional<std::any> rtn = std::nullopt;
{
std::shared_lock lock(lock_);
auto it = global_register_table_.find(n);
if (it == global_register_table_.end()) return std::nullopt;
- auto& sub_table = it->second;
- auto sub_it = sub_table.find(k);
- rtn = (sub_it != sub_table.end())
- ? std::optional<std::any>{sub_it->second->value}
- : std::nullopt;
+ RTNode* current = it->second.get();
+ while (std::getline(iss, segment, '.')) {
+ auto it = current->children.find(segment);
+ if (it == current->children.end()) return std::nullopt;
+ current = it->second.get();
+ }
+ rtn = current->value;
}
return rtn;
}
@@ -107,8 +115,7 @@ class GlobalRegisterTable::Impl {
}
private:
- using SubTable = std::unordered_map<Key, std::unique_ptr<Value>>;
- using Table = std::map<Namespace, SubTable>;
+ using Table = std::map<Namespace, std::unique_ptr<RTNode>>;
std::shared_mutex lock_;
GlobalRegisterTable* parent_;
diff --git a/src/core/thread/Task.cpp b/src/core/thread/Task.cpp
index ad3d3321..0e0f63ac 100644
--- a/src/core/thread/Task.cpp
+++ b/src/core/thread/Task.cpp
@@ -29,6 +29,7 @@
#include "core/thread/Task.h"
#include <qobjectdefs.h>
+#include <qtmetamacros.h>
#include <boost/stacktrace.hpp>
#include <boost/uuid/uuid.hpp>
@@ -36,6 +37,8 @@
#include <boost/uuid/uuid_io.hpp>
#include <memory>
+#include "spdlog/spdlog.h"
+
namespace GpgFrontend::Thread {
class Task::Impl : public QObject {
@@ -186,37 +189,81 @@ class Task::Impl : public QObject {
try {
if (callback_) {
+ SPDLOG_DEBUG("task {} has a callback function", GetFullID());
if (callback_thread_ == QThread::currentThread()) {
SPDLOG_DEBUG("for task {}, the callback thread is the same thread",
GetFullID(), callback_thread_->currentThreadId());
+
callback_(rtn, data_object_);
+
+ // raise signal, announcing this task comes to an end
+ SPDLOG_DEBUG(
+ "for task {}, its life comes to an end in the same thread after "
+ "its callback executed.",
+ parent_->GetFullID());
+ emit parent_->SignalTaskEnd();
} else {
SPDLOG_DEBUG("for task {}, callback thread is a different thread: {}",
GetFullID(), callback_thread_->currentThreadId());
- if (!QMetaObject::invokeMethod(callback_thread_,
- [callback = callback_, rtn = rtn_,
- data_object = data_object_]() {
- callback(rtn, data_object);
- })) {
- SPDLOG_ERROR("task {} had failed to invoke callback", GetFullID());
+ if (!QMetaObject::invokeMethod(
+ callback_thread_,
+ [callback = callback_, rtn = rtn_, data_object = data_object_,
+ parent_ = this->parent_]() {
+ SPDLOG_DEBUG("calling callback of task {}",
+ parent_->GetFullID());
+ try {
+ callback(rtn, data_object);
+ } catch (...) {
+ SPDLOG_ERROR(
+ "unknown exception was caught when execute "
+ "callback of task {}",
+ parent_->GetFullID());
+ }
+ // raise signal, announcing this task comes to an end
+ SPDLOG_DEBUG(
+ "for task {}, its life comes to an end whether its "
+ "callback function fails or not.",
+ parent_->GetFullID());
+ emit parent_->SignalTaskEnd();
+ })) {
+ SPDLOG_ERROR(
+ "task {} had failed to invoke the callback function to target "
+ "thread",
+ GetFullID());
+ SPDLOG_DEBUG(
+ "for task {}, its life must come to an end now, although it "
+ "has something not done yet.",
+ GetFullID());
+ emit parent_->SignalTaskEnd();
}
}
+ } else {
+ // raise signal, announcing this task comes to an end
+ SPDLOG_DEBUG(
+ "for task {}, its life comes to an end without callback "
+ "peacefully.",
+ GetFullID());
+ emit parent_->SignalTaskEnd();
}
} catch (std::exception &e) {
SPDLOG_ERROR("exception was caught at task callback: {}", e.what());
SPDLOG_ERROR(
"stacktrace of the exception: {}",
boost::stacktrace::to_string(boost::stacktrace::stacktrace()));
+ // raise signal, announcing this task comes to an end
+ SPDLOG_DEBUG("for task {}, its life comes to an end at chaos.",
+ GetFullID());
+ emit parent_->SignalTaskEnd();
} catch (...) {
SPDLOG_ERROR("unknown exception was caught");
SPDLOG_ERROR(
"stacktrace of the exception: {}",
boost::stacktrace::to_string(boost::stacktrace::stacktrace()));
+ // raise signal, announcing this task comes to an end
+ SPDLOG_DEBUG("for task {}, its life comes to an end at unknown chaos.",
+ GetFullID());
+ emit parent_->SignalTaskEnd();
}
-
- // raise signal, announcing this task come to an end
- SPDLOG_DEBUG("for task {}, its life comes to an end.", GetFullID());
- emit parent_->SignalTaskEnd();
}
};
diff --git a/src/core/thread/TaskRunnerGetter.cpp b/src/core/thread/TaskRunnerGetter.cpp
index 70ac5226..ce7dbd32 100644
--- a/src/core/thread/TaskRunnerGetter.cpp
+++ b/src/core/thread/TaskRunnerGetter.cpp
@@ -28,21 +28,27 @@
#include "core/thread/TaskRunnerGetter.h"
-GpgFrontend::Thread::TaskRunnerGetter::TaskRunnerGetter(int channel)
+#include <memory>
+
+#include "thread/TaskRunner.h"
+
+namespace GpgFrontend::Thread {
+
+TaskRunnerGetter::TaskRunnerGetter(int channel)
: SingletonFunctionObject<TaskRunnerGetter>(channel) {}
-GpgFrontend::Thread::TaskRunner*
-GpgFrontend::Thread::TaskRunnerGetter::GetTaskRunner(
+TaskRunnerPtr GpgFrontend::Thread::TaskRunnerGetter::GetTaskRunner(
TaskRunnerType runner_type) {
while (true) {
auto it = task_runners_.find(runner_type);
if (it != task_runners_.end()) {
return it->second;
} else {
- auto runner = new TaskRunner();
+ auto runner = std::make_shared<TaskRunner>();
task_runners_[runner_type] = runner;
runner->Start();
continue;
}
}
-} \ No newline at end of file
+}
+} // namespace GpgFrontend::Thread \ No newline at end of file
diff --git a/src/core/thread/TaskRunnerGetter.h b/src/core/thread/TaskRunnerGetter.h
index f6500a5f..c76de036 100644
--- a/src/core/thread/TaskRunnerGetter.h
+++ b/src/core/thread/TaskRunnerGetter.h
@@ -34,6 +34,8 @@
namespace GpgFrontend::Thread {
+using TaskRunnerPtr = std::shared_ptr<TaskRunner>;
+
class GPGFRONTEND_CORE_EXPORT TaskRunnerGetter
: public GpgFrontend::SingletonFunctionObject<TaskRunnerGetter> {
public:
@@ -47,11 +49,11 @@ class GPGFRONTEND_CORE_EXPORT TaskRunnerGetter
TaskRunnerGetter(int channel = SingletonFunctionObject::GetDefaultChannel());
- TaskRunner *GetTaskRunner(
+ TaskRunnerPtr GetTaskRunner(
TaskRunnerType runner_type = kTaskRunnerType_Default);
private:
- std::map<TaskRunnerType, TaskRunner *> task_runners_;
+ std::map<TaskRunnerType, TaskRunnerPtr> task_runners_;
};
} // namespace GpgFrontend::Thread
diff --git a/src/module/integrated/gnupg_info_gathering_module/GnuPGInfoGatheringModule.cpp b/src/module/integrated/gnupg_info_gathering_module/GnuPGInfoGatheringModule.cpp
index 3cb3c9b4..a9eb543b 100644
--- a/src/module/integrated/gnupg_info_gathering_module/GnuPGInfoGatheringModule.cpp
+++ b/src/module/integrated/gnupg_info_gathering_module/GnuPGInfoGatheringModule.cpp
@@ -144,10 +144,12 @@ int GnuPGInfoGatheringModule::Exec(EventRefrernce event) {
component_infos.push_back(c_i_gpgme);
component_infos.push_back(c_i_gpgconf);
+ nlohmann::json jsonlized_gpgme_component_info = c_i_gpgme;
+ nlohmann::json jsonlized_gpgconf_component_info = c_i_gpgconf;
UpsertRTValue(GetModuleIdentifier(), "gnupg.components.gpgme",
- std::string(nlohmann::json{c_i_gpgme}.dump()));
+ std::string(jsonlized_gpgme_component_info.dump()));
UpsertRTValue(GetModuleIdentifier(), "gnupg.components.gpgconf",
- std::string(nlohmann::json{c_i_gpgconf}.dump()));
+ std::string(jsonlized_gpgme_component_info.dump()));
std::vector<std::string> line_split_list;
boost::split(line_split_list, p_out, boost::is_any_of("\n"));
@@ -182,7 +184,7 @@ int GnuPGInfoGatheringModule::Exec(EventRefrernce event) {
std::string version = "/";
if (component_name == "gpg") {
- const auto version = RetrieveRTValueTypedOrDefault<>(
+ version = RetrieveRTValueTypedOrDefault<>(
"core", "gpgme.ctx.gnupg_version", std::string{"2.0.0"});
}
if (component_name == "gpg-agent") {
@@ -206,24 +208,26 @@ int GnuPGInfoGatheringModule::Exec(EventRefrernce event) {
c_i.path = component_path;
c_i.binary_checksum =
binary_checksum.has_value() ? binary_checksum.value() : "/";
+
+ nlohmann::json jsonlized_component_info = c_i;
UpsertRTValue(
GetModuleIdentifier(),
(boost::format("gnupg.components.%1%") % component_name).str(),
- std::string(nlohmann::json{c_i}.dump()));
+ std::string(jsonlized_component_info.dump()));
+
+ component_infos.push_back(c_i);
}
}
nlohmann::json jsonlized_components_info;
for (auto &component_info : component_infos) {
- jsonlized_components_info.emplace_back(
- nlohmann::json{component_info});
+ jsonlized_components_info.emplace_back(component_info);
}
UpsertRTValue(GetModuleIdentifier(), "gnupg.components_info",
std::string(jsonlized_components_info.dump()));
- }});
-
- MODULE_LOG_DEBUG("start to get dirs info");
+ },
+ getTaskRunner()});
GpgCommandExecutor::ExecuteContexts exec_contexts;
@@ -276,9 +280,8 @@ int GnuPGInfoGatheringModule::Exec(EventRefrernce event) {
(boost::format("gnupg.dirs.%1%") % configuration_name).str(),
configuration_value);
}
- }});
-
- MODULE_LOG_DEBUG("start to get components info");
+ },
+ getTaskRunner()});
const std::string components_info_json = RetrieveRTValueTypedOrDefault(
GetModuleIdentifier(), "gnupg.components_info", std::string{});
@@ -287,17 +290,20 @@ int GnuPGInfoGatheringModule::Exec(EventRefrernce event) {
return -1;
}
- nlohmann::json jsonlized_components_info =
- nlohmann::json{components_info_json};
+ nlohmann::json jsonlized_components_info = nlohmann::json::parse(
+ components_info_json, nullptr, false, true); // parse without exception
+ MODULE_LOG_DEBUG("start to check components options info, components: {}",
+ jsonlized_components_info);
+
if (!jsonlized_components_info.is_array()) {
- MODULE_LOG_ERROR("cannot parse components inforamtion of gnupg from rt");
+ MODULE_LOG_ERROR(
+ "cannot parse components inforamtion of gnupg to json from rt");
return -1;
}
for (const auto &jsonlized_component_info : jsonlized_components_info) {
GpgComponentInfo component_info =
jsonlized_component_info.get<GpgComponentInfo>();
-
MODULE_LOG_DEBUG("gpgconf check options ready, component: {}",
component_info.name);
@@ -306,23 +312,23 @@ int GnuPGInfoGatheringModule::Exec(EventRefrernce event) {
exec_contexts.emplace_back(GpgCommandExecutor::ExecuteContext{
gpgconf_path,
- {"--check-options", component_info.name},
- [component_info](int exit_code, const std::string &p_out,
- const std::string &p_err) {
+ {"--list-options", component_info.name},
+ [this, component_info](int exit_code, const std::string &p_out,
+ const std::string &p_err) {
MODULE_LOG_DEBUG(
- "gpgconf {} options exit_code: {} process stdout "
+ "gpgconf {} avaliable options exit_code: {} process stdout "
"size: {} ",
component_info.name, exit_code, p_out.size());
if (exit_code != 0) {
MODULE_LOG_ERROR(
- "gpgconf {} options execute error, process "
- "stderr: {} , process stdout:",
+ "gpgconf {} avaliable options execute error, process stderr: "
+ "{} , process stdout:",
component_info.name, p_err, p_out);
return;
}
- // auto &options_info = info_.OptionsInfo;
+ std::vector<GpgOptionsInfo> options_infos;
std::vector<std::string> line_split_list;
boost::split(line_split_list, p_out, boost::is_any_of("\n"));
@@ -331,106 +337,81 @@ int GnuPGInfoGatheringModule::Exec(EventRefrernce event) {
std::vector<std::string> info_split_list;
boost::split(info_split_list, line, boost::is_any_of(":"));
- MODULE_LOG_DEBUG("component {} options line: {} info size: {}",
- component_info.name, line, info_split_list.size());
+ MODULE_LOG_DEBUG(
+ "component {} avaliable options line: {} info size: {}",
+ component_info.name, line, info_split_list.size());
- if (info_split_list.size() != 6) continue;
+ if (info_split_list.size() < 10) continue;
- auto configuration_name = info_split_list[0];
- boost::algorithm::trim(configuration_name);
- {
- // options_info[configuration_name] = {
- // info_split_list[1], info_split_list[2], info_split_list[3],
- // info_split_list[4], info_split_list[5]};
+ // The format of each line is:
+ // name:flags:level:description:type:alt-type:argname:default:argdef:value
- // boost::algorithm::trim(options_info[configuration_name][0]);
- // boost::algorithm::trim(options_info[configuration_name][1]);
- // boost::algorithm::trim(options_info[configuration_name][2]);
- // boost::algorithm::trim(options_info[configuration_name][3]);
- // boost::algorithm::trim(options_info[configuration_name][4]);
- }
- }
- }});
- }
+ auto option_name = info_split_list[0];
+ boost::algorithm::trim(option_name);
- MODULE_LOG_DEBUG("start to get avaliable component options info");
+ auto option_flags = info_split_list[1];
+ boost::algorithm::trim(option_flags);
- for (const auto &jsonlized_component_info : jsonlized_components_info) {
- GpgComponentInfo component_info =
- jsonlized_component_info.get<GpgComponentInfo>();
- MODULE_LOG_DEBUG("gpgconf check options ready, component: {}",
- component_info.name);
+ auto option_level = info_split_list[2];
+ boost::algorithm::trim(option_level);
- if (component_info.name == "gpgme" || component_info.name == "gpgconf")
- continue;
+ auto option_desc = info_split_list[3];
+ boost::algorithm::trim(option_desc);
- exec_contexts.emplace_back(GpgCommandExecutor::ExecuteContext{
- gpgconf_path,
- {"--list-options", component_info.name},
- [component_info](int exit_code, const std::string &p_out,
- const std::string &p_err) {
- MODULE_LOG_DEBUG(
- "gpgconf {} avaliable options exit_code: {} process stdout "
- "size: {} ",
- component_info.name, exit_code, p_out.size());
+ auto option_type = info_split_list[4];
+ boost::algorithm::trim(option_type);
- if (exit_code != 0) {
- MODULE_LOG_ERROR(
- "gpgconf {} avaliable options execute error, process stderr: "
- "{} , process stdout:",
- component_info.name, p_err, p_out);
- return;
- }
+ auto option_alt_type = info_split_list[5];
+ boost::algorithm::trim(option_alt_type);
- // auto &available_options_info = info_.AvailableOptionsInfo;
+ auto option_argname = info_split_list[6];
+ boost::algorithm::trim(option_argname);
- std::vector<std::string> line_split_list;
- boost::split(line_split_list, p_out, boost::is_any_of("\n"));
+ auto option_default = info_split_list[7];
+ boost::algorithm::trim(option_default);
- for (const auto &line : line_split_list) {
- std::vector<std::string> info_split_list;
- boost::split(info_split_list, line, boost::is_any_of(":"));
+ auto option_argdef = info_split_list[8];
+ boost::algorithm::trim(option_argdef);
- MODULE_LOG_DEBUG(
- "component {} avaliable options line: {} info size: {}",
- component_info.name, line, info_split_list.size());
+ auto option_value = info_split_list[9];
+ boost::algorithm::trim(option_value);
+
+ GpgOptionsInfo info;
+ info.name = option_name;
+ info.flags = option_flags;
+ info.level = option_level;
+ info.description = option_desc;
+ info.type = option_type;
+ info.alt_type = option_alt_type;
+ info.argname = option_argname;
+ info.default_value = option_default;
+ info.argdef = option_argdef;
+ info.value = option_value;
- if (info_split_list.size() != 10) continue;
-
- auto configuration_name = info_split_list[0];
- boost::algorithm::trim(configuration_name);
- {
- // available_options_info[configuration_name] = {
- // info_split_list[1], info_split_list[2], info_split_list[3],
- // info_split_list[4], info_split_list[5], info_split_list[6],
- // info_split_list[7], info_split_list[8],
- // info_split_list[9]};
-
- // boost::algorithm::trim(
- // available_options_info[configuration_name][0]);
- // boost::algorithm::trim(
- // available_options_info[configuration_name][1]);
- // boost::algorithm::trim(
- // available_options_info[configuration_name][2]);
- // boost::algorithm::trim(
- // available_options_info[configuration_name][3]);
- // boost::algorithm::trim(
- // available_options_info[configuration_name][4]);
- // boost::algorithm::trim(
- // available_options_info[configuration_name][5]);
- // boost::algorithm::trim(
- // available_options_info[configuration_name][6]);
- // boost::algorithm::trim(
- // available_options_info[configuration_name][7]);
- // boost::algorithm::trim(
- // available_options_info[configuration_name][8]);
- }
+ nlohmann::json jsonlized_option_info = info;
+ UpsertRTValue(GetModuleIdentifier(),
+ (boost::format("gnupg.components.%1%.options.%2%") %
+ component_info.name % option_name)
+ .str(),
+ std::string(jsonlized_option_info.dump()));
+ options_infos.push_back(info);
}
- }});
+
+ nlohmann::json jsonlized_options_info;
+ for (auto &option_info : options_infos) {
+ jsonlized_options_info.emplace_back(option_info);
+ }
+ UpsertRTValue(GetModuleIdentifier(),
+ (boost::format("gnupg.components.%1%"
+ ".options_info") %
+ component_info.name)
+ .str(),
+ std::string(jsonlized_options_info.dump()));
+ },
+ getTaskRunner()});
}
GpgCommandExecutor::GetInstance().ExecuteConcurrentlySync(exec_contexts);
-
UpsertRTValue(GetModuleIdentifier(), "gnupg.gathering_done", true);
return 0;
diff --git a/src/module/integrated/gnupg_info_gathering_module/GpgInfo.h b/src/module/integrated/gnupg_info_gathering_module/GpgInfo.h
index 5b88e221..9aaa2005 100644
--- a/src/module/integrated/gnupg_info_gathering_module/GpgInfo.h
+++ b/src/module/integrated/gnupg_info_gathering_module/GpgInfo.h
@@ -60,4 +60,25 @@ struct GpgComponentInfo {
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(GpgComponentInfo, name, desc, version, path,
binary_checksum);
+/**
+ * The format of each line is:
+ * name:flags:level:description:type:alt-type:argname:default:argdef:value
+ */
+struct GpgOptionsInfo {
+ std::string name;
+ std::string flags;
+ std::string level;
+ std::string description;
+ std::string type;
+ std::string alt_type;
+ std::string argname;
+ std::string default_value;
+ std::string argdef;
+ std::string value;
+};
+
+NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(GpgOptionsInfo, name, flags, level,
+ description, type, alt_type, argname,
+ default_value, argdef, value);
+
} // namespace GpgFrontend::Module::Integrated::GnuPGInfoGatheringModule
diff --git a/src/ui/widgets/PlainTextEditorPage.cpp b/src/ui/widgets/PlainTextEditorPage.cpp
index 483973f2..1ac12d0d 100644
--- a/src/ui/widgets/PlainTextEditorPage.cpp
+++ b/src/ui/widgets/PlainTextEditorPage.cpp
@@ -175,7 +175,7 @@ void PlainTextEditorPage::ReadFile() {
const auto target_path = this->full_file_path_.toStdString();
- auto *task_runner =
+ auto task_runner =
GpgFrontend::Thread::TaskRunnerGetter::GetInstance().GetTaskRunner();
auto *read_task = new FileReadTask(target_path);