Add a button to create a debug archive
authorKevin Ottens <kevin.ottens@nextcloud.com>
Mon, 5 Oct 2020 17:45:40 +0000 (19:45 +0200)
committerMichael Schuster (Rebase PR Action) <misch7@users.noreply.github.com>
Wed, 7 Oct 2020 13:33:20 +0000 (13:33 +0000)
This will harvest everything we might need for debugging purposes:
 * config file
 * sync journal dbs
 * log files

Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
src/gui/generalsettings.cpp
src/gui/generalsettings.h
src/gui/generalsettings.ui

index fff5c9076bf1a13dbf5ad5eedd2fb139222dc406..f910601ac65805b7cc78dafbdc10abc1b83986f4 100644 (file)
 
 #include "ignorelisteditor.h"
 #include "common/utility.h"
+#include "logger.h"
 
 #include "config.h"
 
 #include "legalnotice.h"
 
+#include <QFileDialog>
+#include <QMessageBox>
 #include <QNetworkProxy>
 #include <QDir>
 #include <QScopedValueRollback>
 
+#include <private/qzipwriter_p.h>
+
 #define QTLEGACY (QT_VERSION < QT_VERSION_CHECK(5,9,0))
 
 #if !(QTLEGACY)
 #include <QOperatingSystemVersion>
 #endif
 
+namespace {
+struct ZipEntry {
+    QString localFilename;
+    QString zipFilename;
+};
+
+ZipEntry fileInfoToZipEntry(const QFileInfo &info)
+{
+    return {
+        info.absoluteFilePath(),
+        info.fileName()
+    };
+}
+
+ZipEntry fileInfoToLogZipEntry(const QFileInfo &info)
+{
+    auto entry = fileInfoToZipEntry(info);
+    entry.zipFilename.prepend(QStringLiteral("logs/"));
+    return entry;
+}
+
+ZipEntry syncFolderToZipEntry(OCC::Folder *f)
+{
+    const auto journalPath = f->journalDb()->databaseFilePath();
+    const auto journalInfo = QFileInfo(journalPath);
+    return fileInfoToZipEntry(journalInfo);
+}
+
+QVector<ZipEntry> createFileList()
+{
+    auto list = QVector<ZipEntry>();
+    OCC::ConfigFile cfg;
+
+    list.append(fileInfoToZipEntry(QFileInfo(cfg.configFile())));
+
+    const auto logger = OCC::Logger::instance();
+
+    if (!logger->logDir().isEmpty()) {
+        list.append({QString(), QStringLiteral("logs")});
+
+        QDir dir(logger->logDir());
+        const auto infoList = dir.entryInfoList(QDir::Files);
+        std::transform(std::cbegin(infoList), std::cend(infoList),
+                       std::back_inserter(list),
+                       fileInfoToLogZipEntry);
+    } else if (!logger->logFile().isEmpty()) {
+        list.append(fileInfoToZipEntry(QFileInfo(logger->logFile())));
+    }
+
+    const auto folders = OCC::FolderMan::instance()->map().values();
+    std::transform(std::cbegin(folders), std::cend(folders),
+                   std::back_inserter(list),
+                   syncFolderToZipEntry);
+
+    return list;
+}
+
+void createDebugArchive(const QString &filename)
+{
+    const auto entries = createFileList();
+
+    QZipWriter zip(filename);
+    for (const auto &entry : entries) {
+        if (entry.localFilename.isEmpty()) {
+            zip.addDirectory(entry.zipFilename);
+        } else {
+            QFile file(entry.localFilename);
+            if (!file.open(QFile::ReadOnly)) {
+                continue;
+            }
+            zip.addFile(entry.zipFilename, &file);
+        }
+    }
+}
+}
+
 namespace OCC {
 
 GeneralSettings::GeneralSettings(QWidget *parent)
@@ -122,6 +203,7 @@ GeneralSettings::GeneralSettings(QWidget *parent)
     _ui->monoIconsCheckBox->setVisible(Theme::instance()->monoIconsAvailable());
 
     connect(_ui->ignoredFilesButton, &QAbstractButton::clicked, this, &GeneralSettings::slotIgnoreFilesEditor);
+    connect(_ui->debugArchiveButton, &QAbstractButton::clicked, this, &GeneralSettings::slotCreateDebugArchive);
 
     // accountAdded means the wizard was finished and the wizard might change some options.
     connect(AccountManager::instance(), &AccountManager::accountAdded, this, &GeneralSettings::loadMiscSettings);
@@ -260,6 +342,17 @@ void GeneralSettings::slotIgnoreFilesEditor()
     }
 }
 
+void GeneralSettings::slotCreateDebugArchive()
+{
+    const auto filename = QFileDialog::getSaveFileName(this, tr("Create Debug Archive"), QString(), tr("Zip Archives") + " (*.zip)");
+    if (filename.isEmpty()) {
+        return;
+    }
+
+    createDebugArchive(filename);
+    QMessageBox::information(this, tr("Debug Archive Created"), tr("Debug archive is created at %1").arg(filename));
+}
+
 void GeneralSettings::slotShowLegalNotice()
 {
     auto notice = new LegalNotice();
index 4b5e6a538f636e17478b4fe6f3219b9676f6cde1..fa6fe11b9cefed562bb789c8bc23f08a25c235d1 100644 (file)
@@ -48,6 +48,7 @@ private slots:
     void slotToggleOptionalServerNotifications(bool);
     void slotShowInExplorerNavigationPane(bool);
     void slotIgnoreFilesEditor();
+    void slotCreateDebugArchive();
     void loadMiscSettings();
     void slotShowLegalNotice();
 #if defined(BUILD_UPDATER)
index ebc69ebd665fd2c048572bcad4941130cebeb615..67e9af6ee901b66d5ad5e8822c07ab7fbafb41b3 100644 (file)
@@ -6,8 +6,8 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>516</width>
-    <height>523</height>
+    <width>553</width>
+    <height>558</height>
    </rect>
   </property>
   <property name="windowTitle">
           </property>
          </widget>
         </item>
+        <item>
+         <widget class="QPushButton" name="debugArchiveButton">
+          <property name="text">
+           <string>Create Debug Archive...</string>
+          </property>
+         </widget>
+        </item>
         <item>
          <spacer name="horizontalSpacer_4">
           <property name="orientation">