summaryrefslogtreecommitdiff
path: root/src/loot.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/loot.cpp')
-rw-r--r--src/loot.cpp177
1 files changed, 94 insertions, 83 deletions
diff --git a/src/loot.cpp b/src/loot.cpp
index 35ac9cff..eef16b45 100644
--- a/src/loot.cpp
+++ b/src/loot.cpp
@@ -262,6 +262,16 @@ Loot::Loot()
Loot::~Loot()
{
m_thread->wait();
+
+ if (!m_outPath.isEmpty()) {
+ const auto r = shell::Delete(m_outPath);
+
+ if (!r) {
+ log::error(
+ "failed to remove temporary loot json report '{}': {}",
+ m_outPath, r.toString());
+ }
+ }
}
bool Loot::start(QWidget* parent, OrganizerCore& core, bool didUpdateMasterList)
@@ -369,32 +379,39 @@ void Loot::lootThread()
bool Loot::waitForCompletion()
{
- HANDLE waitHandle = m_lootProcess.get();
- DWORD res = ::MsgWaitForMultipleObjects(1, &waitHandle, false, 100, QS_KEY | QS_MOUSE);
+ bool terminating = false;
- while ((res != WAIT_FAILED) && (res != WAIT_OBJECT_0)) {
- if (m_cancel) {
- ::TerminateProcess(m_lootProcess.get(), 1);
+ for (;;) {
+ DWORD res = WaitForSingleObject(m_lootProcess.get(), 100);
+
+ if (res == WAIT_OBJECT_0) {
+ // done
+ break;
}
- std::string lootOut = readFromPipe();
- processStdout(lootOut);
+ if (res == WAIT_FAILED) {
+ const auto e = GetLastError();
+ log::error("failed to wait on loot process, {}", formatSystemMessage(e));
+ return false;
+ }
- res = ::MsgWaitForMultipleObjects(1, &waitHandle, false, 100, QS_KEY | QS_MOUSE);
- }
+ if (m_cancel) {
+ // terminate and wait to finish
+ ::TerminateProcess(m_lootProcess.get(), 1);
+ WaitForSingleObject(m_lootProcess.get(), INFINITE);
+ return false;
+ }
- const std::string remainder = readFromPipe();
- if (!remainder.empty()) {
- processStdout(remainder);
+ processStdout(readFromPipe());
}
if (m_cancel) {
return false;
}
+ processStdout(readFromPipe());
// checking exit code
-
DWORD exitCode = 0;
if (!::GetExitCodeProcess(m_lootProcess.get(), &exitCode)) {
@@ -559,113 +576,107 @@ void Loot::processOutputFile()
return;
}
- if (!doc.isArray()) {
- logJsonError("root is {}, not an array", jsonType(doc));
+ if (!doc.isObject()) {
+ logJsonError("root is {}, not an object", jsonType(doc));
return;
}
- const QJsonArray array = doc.array();
+ const QJsonObject object = doc.object();
- for (auto pluginValue : array) {
- processOutputPlugin(pluginValue);
- }
-}
+ if (object.contains("messages")) {
+ const auto messagesValue = object["messages"];
-bool Loot::processOutputPlugin(const QJsonValue& pluginValue)
-{
- if (!pluginValue.isObject()) {
- logJsonError(
- "value in root array is {}, not an object", jsonType(pluginValue));
- return false;
- }
+ if (messagesValue.isArray()) {
+ processMessages(messagesValue.toArray());
+ } else {
+ logJsonError(
+ "'messages' property is {}, not an array", jsonType(messagesValue));
+ }
- const auto plugin = pluginValue.toObject();
+ }
+ if (object.contains("plugins")) {
+ const auto pluginsValue = object["plugins"];
- if (!plugin.contains("name")) {
- logJsonError("plugin value doesn't have a 'name' property");
- return false;
+ if (pluginsValue.isArray()) {
+ processPlugins(pluginsValue.toArray());
+ } else {
+ logJsonError(
+ "'plugins' property is {}, not an array", jsonType(pluginsValue));
+ }
}
+}
- const auto pluginNameValue = plugin["name"];
- if (!pluginNameValue.isString()) {
- logJsonError(
- "plugin property 'name' is {}, not a string", jsonType(pluginNameValue));
- return false;
+bool Loot::processMessages(const QJsonArray& messages)
+{
+ for (auto messageValue : messages) {
+ if (messageValue.isObject()) {
+ processMessage(messageValue.toObject());
+ } else {
+ logJsonError("a message is {}, not an object", jsonType(messageValue));
+ }
}
- const auto pluginName = pluginNameValue.toString();
-
- processPluginMessages(pluginName, plugin);
- processPluginDirty(pluginName, plugin);
-
return true;
}
-bool Loot::processPluginMessages(
- const QString& pluginName, const QJsonObject& plugin)
+bool Loot::processMessage(const QJsonObject& message)
{
- if (!plugin.contains("messages")) {
- return true;
- }
-
- const auto messagesValue = plugin["messages"];
-
- if (!messagesValue.isArray()) {
- logJsonError(
- "'messages' value for plugin '{}' is {}, not an array",
- pluginName, jsonType(messagesValue));
+ const auto messageType = message["type"].toString();
+ const auto messageString = message["message"].toString();
+ if (messageType.isEmpty()) {
+ logJsonError("there's a message with no 'type' property");
return false;
}
- const auto messages = messagesValue.toArray();
+ if (messageString.isEmpty()) {
+ logJsonError("there's a message with no 'message' property");
+ return false;
+ }
+ emit log(levelFromLoot(
+ lootcli::logLevelFromString(messageType.toStdString())),
+ messageString);
- for (auto messageValue : messages) {
- if (!messageValue.isObject()) {
- logJsonError(
- "plugin '{}' has a message that's {}, not an object",
- pluginName, jsonType(messageValue));
+ return true;
+}
- continue;
+bool Loot::processPlugins(const QJsonArray& plugins)
+{
+ for (auto pluginValue : plugins) {
+ if (pluginValue.isObject()) {
+ processPlugin(pluginValue.toObject());
+ } else {
+ logJsonError("a plugin is {}, not an object", jsonType(pluginValue));
}
-
- processPluginMessage(pluginName, messageValue.toObject());
}
return true;
}
-bool Loot::processPluginMessage(
- const QString& pluginName, const QJsonObject& message)
+bool Loot::processPlugin(const QJsonObject& plugin)
{
- const auto messageType = message["type"].toString();
- const auto messageString = message["message"].toString();
-
- if (messageType.isEmpty()) {
- logJsonError(
- "plugin '{}' has a message with no 'type' property", pluginName);
+ if (!plugin.contains("name")) {
+ logJsonError("plugin missing 'name' property");
return false;
}
- if (messageString.isEmpty()) {
- logJsonError(
- "plugin '{}' has a message with no 'message' property", pluginName);
+ const auto nameValue = plugin["name"];
+ if (!nameValue.isString()) {
+ logJsonError("plugin property 'name' is {}, not a string", jsonType(nameValue));
return false;
}
- const auto info = QString("%1: %2")
- .arg(messageType)
- .arg(messageString);
+ const auto name = nameValue.toString();
+
+ processPluginDirty(name, plugin);
- emit information(pluginName, info);
return true;
}
-bool Loot::processPluginDirty(
- const QString& pluginName, const QJsonObject& plugin)
+bool Loot::processPluginDirty(const QString& name, const QJsonObject& plugin)
{
if (!plugin.contains("dirty")) {
return true;
@@ -676,7 +687,7 @@ bool Loot::processPluginDirty(
if (!dirtyValue.isArray()) {
logJsonError(
"'dirty' value for plugin '{}' is {}, not an array",
- pluginName, jsonType(dirtyValue));
+ name, jsonType(dirtyValue));
return false;
}
@@ -688,7 +699,7 @@ bool Loot::processPluginDirty(
if (!stringValue.isString()) {
logJsonError(
"'dirty' value for plugin '{}' is {}, not a string",
- pluginName, jsonType(stringValue));
+ name, jsonType(stringValue));
continue;
}
@@ -696,11 +707,11 @@ bool Loot::processPluginDirty(
const auto string = stringValue.toString();
if (string.isEmpty()) {
- logJsonError("'dirty' string for plugin '{}' is empty", pluginName);
+ logJsonError("'dirty' string for plugin '{}' is empty", name);
continue;
}
- emit information(pluginName, string);
+ emit information(name, string);
}
return true;