From ca6f9990c691a5d20e2b8d97ad98e4ad80c13a9e Mon Sep 17 00:00:00 2001 From: isanae <14251494+isanae@users.noreply.github.com> Date: Tue, 17 Dec 2019 06:32:08 -0500 Subject: added text in when running loot stop indeterminate progress bar on errors add errors and warnings to report --- src/loot.cpp | 124 ++++++++++++++++++++++++++++++++++++++++++---------- src/loot.h | 17 +++++-- src/lootdialog.cpp | 18 +++++--- src/organizer_en.ts | 50 +++++++++++++++------ 4 files changed, 164 insertions(+), 45 deletions(-) (limited to 'src') diff --git a/src/loot.cpp b/src/loot.cpp index a86cdcff..3feb95c9 100644 --- a/src/loot.cpp +++ b/src/loot.cpp @@ -231,11 +231,31 @@ log::Levels levelFromLoot(lootcli::LogLevels level) } } - QString Loot::Report::toMarkdown() const { QString s; + if (!okay) { + s += "## " + tr("Loot failed to run") + "\n"; + + if (errors.empty() && warnings.empty()) { + s += tr("No errors were reported. The log below might have more information.\n"); + } + } + + s += errorsMarkdown(); + + if (okay) { + s += "\n" + successMarkdown(); + } + + return s; +} + +QString Loot::Report::successMarkdown() const +{ + QString s; + if (!messages.empty()) { s += "### " + QObject::tr("General messages") + "\n"; @@ -268,6 +288,33 @@ QString Loot::Report::toMarkdown() const return s; } +QString Loot::Report::errorsMarkdown() const +{ + QString s; + + if (!errors.empty()) { + s += "### " + tr("Errors") + ":\n"; + + for (auto&& e : errors) { + s += " - " + e + "\n"; + } + } + + if (!warnings.empty()) { + if (!s.isEmpty()) { + s += "\n"; + } + + s += "### " + tr("Warnings") + ":\n"; + + for (auto&& w : warnings) { + s += " - " + w + "\n"; + } + } + + return s; +} + QString Loot::Stats::toMarkdown() const { return QString("`stats: %1s, lootcli %2, loot %3`") @@ -396,20 +443,13 @@ Loot::~Loot() m_thread->wait(); } - if (QFile::exists(LootReportPath)) { - log::debug("deleting temporary loot report '{}'", LootReportPath); - const auto r = shell::Delete(LootReportPath); - - if (!r) { - log::error( - "failed to remove temporary loot json report '{}': {}", - LootReportPath, r.toString()); - } - } + deleteReportFile(); } bool Loot::start(QWidget* parent, bool didUpdateMasterList) { + deleteReportFile(); + log::debug("starting loot"); m_pipe.reset(new AsyncPipe); @@ -506,6 +546,16 @@ const Loot::Report& Loot::report() const return m_report; } +const std::vector& Loot::errors() const +{ + return m_errors; +} + +const std::vector& Loot::warnings() const +{ + return m_warnings; +} + void Loot::lootThread() { try @@ -514,8 +564,9 @@ void Loot::lootThread() if (waitForCompletion()) { m_result = true; - processOutputFile(); } + + m_report = createReport(); } catch(...) { @@ -624,7 +675,15 @@ void Loot::processMessage(const lootcli::Message& m) { case lootcli::MessageType::Log: { - emit log(levelFromLoot(m.logLevel), QString::fromStdString(m.log)); + const auto level = levelFromLoot(m.logLevel); + + if (level == log::Error) { + m_errors.push_back(QString::fromStdString(m.log)); + } else if (level == log::Warning) { + m_warnings.push_back(QString::fromStdString(m.log)); + } + + emit log(level, QString::fromStdString(m.log)); break; } @@ -636,7 +695,36 @@ void Loot::processMessage(const lootcli::Message& m) } } -void Loot::processOutputFile() +Loot::Report Loot::createReport() const +{ + Report r; + + r.okay = m_result; + r.errors = m_errors; + r.warnings = m_warnings; + + if (m_result) { + processOutputFile(r); + } + + return r; +} + +void Loot::deleteReportFile() +{ + if (QFile::exists(LootReportPath)) { + log::debug("deleting temporary loot report '{}'", LootReportPath); + const auto r = shell::Delete(LootReportPath); + + if (!r) { + log::error( + "failed to remove temporary loot json report '{}': {}", + LootReportPath, r.toString()); + } + } +} + +void Loot::processOutputFile(Report& r) const { log::debug("parsing json output file at '{}'", LootReportPath); @@ -661,21 +749,13 @@ void Loot::processOutputFile() return; } - m_report = createReport(doc); -} - -Loot::Report Loot::createReport(const QJsonDocument& doc) const -{ requireObject(doc, "root"); - Report r; const QJsonObject object = doc.object(); r.messages = reportMessages(getOpt(object, "messages")); r.plugins = reportPlugins(getOpt(object, "plugins")); r.stats = reportStats(getWarn(object, "stats")); - - return r; } std::vector Loot::reportPlugins(const QJsonArray& plugins) const diff --git a/src/loot.h b/src/loot.h index 4ec06d6f..f9943626 100644 --- a/src/loot.h +++ b/src/loot.h @@ -71,11 +71,17 @@ public: struct Report { + bool okay = false; + std::vector errors, warnings; std::vector messages; std::vector plugins; Stats stats; QString toMarkdown() const; + + private: + QString successMarkdown() const; + QString errorsMarkdown() const; }; @@ -85,13 +91,16 @@ public: bool start(QWidget* parent, bool didUpdateMasterList); void cancel(); bool result() const; + const QString& outPath() const; const Report& report() const; + const std::vector& errors() const; + const std::vector& warnings() const; signals: void output(const QString& s); void progress(const lootcli::Progress p); - void log(MOBase::log::Levels level, const QString& s); + void log(MOBase::log::Levels level, const QString& s) const; void finished(); private: @@ -102,6 +111,7 @@ private: env::HandlePtr m_lootProcess; std::unique_ptr m_pipe; std::string m_outputBuffer; + std::vector m_errors, m_warnings; Report m_report; bool spawnLootcli( @@ -113,9 +123,10 @@ private: void processStdout(const std::string &lootOut); void processMessage(const lootcli::Message& m); - void processOutputFile(); + Report createReport() const; + void processOutputFile(Report& r) const; + void deleteReportFile(); - Report createReport(const QJsonDocument& doc) const; Message reportMessage(const QJsonObject& message) const; std::vector reportPlugins(const QJsonArray& plugins) const; Loot::Plugin reportPlugin(const QJsonObject& plugin) const; diff --git a/src/lootdialog.cpp b/src/lootdialog.cpp index ae3b1164..5ac65907 100644 --- a/src/lootdialog.cpp +++ b/src/lootdialog.cpp @@ -212,6 +212,8 @@ void LootDialog::createUI() ui->buttons->setStandardButtons(QDialogButtonBox::Cancel); + m_report.setText(tr("Running LOOT...")); + resize(650, 450); } @@ -243,9 +245,15 @@ void LootDialog::onFinished() close(); } else { log::debug("loot dialog: showing report"); + showReport(); + ui->openJsonReport->setEnabled(true); ui->buttons->setStandardButtons(QDialogButtonBox::Close); + + // if loot failed, the Done progress won't be received; this makes sure + // the progress bar is stopped + setProgress(lootcli::Progress::Done); } } @@ -262,16 +270,14 @@ void LootDialog::log(log::Levels lv, const QString& s) void LootDialog::showReport() { - if (m_loot.result()) { - const auto& lootReport = m_loot.report(); + const auto& lootReport = m_loot.report(); + if (m_loot.result()) { m_core.pluginList()->clearAdditionalInformation(); for (auto&& p : lootReport.plugins) { m_core.pluginList()->addLootReport(p.name, p); } - - m_report.setText(lootReport.toMarkdown()); - } else { - m_report.setText("**" + tr("Loot failed to run") + "**"); } + + m_report.setText(lootReport.toMarkdown()); } diff --git a/src/organizer_en.ts b/src/organizer_en.ts index 2540b1ba..32474a23 100644 --- a/src/organizer_en.ts +++ b/src/organizer_en.ts @@ -1681,12 +1681,34 @@ This is likely due to a corrupted or incompatible download or unrecognized archi Loot - + + Loot failed to run + + + + + No errors were reported. The log below might have more information. + + No errors were reported. The log below might have more information. + + + + + Errors + + + + + Warnings + + + + failed to start loot - + Loot failed. Exit code was: %1 @@ -1724,8 +1746,8 @@ This is likely due to a corrupted or incompatible download or unrecognized archi - - Loot failed to run + + Running LOOT... @@ -5500,7 +5522,7 @@ p, li { white-space: pre-wrap; } - + @@ -5945,49 +5967,49 @@ If the folder was still in use, restart MO and try again. - + General messages - + Plugins - + No messages. - + Incompatibilities - + Missing masters - + Verified clean by %1 - + %1 found %2 ITM record(s), %3 deleted reference(s) and %4 deleted navmesh(es). - + Warning - + failed to run loot: %1 -- cgit v1.3.1