]> gitweb.hamatoma.de Git - reqt/commitdiff
rebackgui works
authorhama <hama@siduction.net>
Sat, 13 Feb 2016 10:30:07 +0000 (11:30 +0100)
committerhama <hama@siduction.net>
Sat, 13 Feb 2016 10:30:07 +0000 (11:30 +0100)
appl/rebackgui/BackupEngine.cpp
appl/rebackgui/BackupEngine.hpp
appl/rebackgui/Configuration.cpp
appl/rebackgui/mainwindow.cpp
appl/rebackgui/mainwindow.hpp
appl/rebackgui/mainwindow.ui
base/rebase.hpp

index 56a906ff1b615bd30e3b6c358fe5e88ddea7d0cb..8ee51a9b082863581b7336baa3a0fe55f0105896 100644 (file)
@@ -10,7 +10,7 @@
  */
 
 #include "backupgui.hpp"
-
+ReVerbose_t BackupEngine::m_verboseLevel = VerboseStandard;
 bool BackupEngine::m_shouldStop = false;
 QStringList BackupEngine::m_files;
 qint64 BackupEngine::m_hotBytes = 0;
@@ -115,55 +115,6 @@ bool BackupEngine::log(const QString& message){
    return true;
 }
 
-/**
- * Inserts a remove command into queue for too old files in the shadow.
- *
- * Note: this method is recursive.
- *
- * @param directory    directory to inspect, e.g. "/media/trg/x"
- * @param maxAge       all files older than this time point will be deleted
- */
-void BackupEngine::removeOlder(const QString& directory, const QDateTime& time){
-       QDirIterator it(directory);
-       QString info, node;
-       m_mutex.lock();
-       m_totalDirs++;
-       m_mutex.unlock();
-       bool isEmpty = true;
-       while (it.hasNext()){
-          if (m_shouldStop){
-                 break;
-          }
-          it.next();
-          node = it.fileName();
-          if (it.fileInfo().isDir()){
-                  if (node != "." && node != ".."){
-                          removeOlder(it.filePath(), time);
-                          isEmpty = false;
-                  }
-          } else if (it.fileInfo().lastModified() < time){
-                  isEmpty = false;
-                  info = QChar(MAX_INDEX) + it.filePath() + m_separatorString
-                                  + QChar(CmdRemove);
-                  m_mutex.lock();
-                  m_files.append(info);
-                  m_hotFiles++;
-                  m_hotBytes += it.fileInfo().size();
-                  m_totalFiles++;
-                  m_mutex.unlock();
-          }
-       }
-       if (isEmpty){
-               info = QChar(MAX_INDEX) + it.filePath() + m_separatorString
-                               + QChar(CmdRemoveDir);
-               m_mutex.lock();
-               m_files.append(info);
-               m_matchedFiles++;
-               m_mutex.unlock();
-       }
-
-}
-
 /**
  * Constructor.
  *
@@ -207,15 +158,17 @@ void BackupTask::copyFile(int index, const QString& relPath,
                        error(tr("cannot make directory (%1): %2").arg(errno).arg(targetDir));
        }
        QFileInfo info(source);
-       m_mainWindow->addToFileList(source + " " + ReQStringUtils::readableSize(info.size()));
+       if (m_verboseLevel >= VerboseStandard)
+               m_mainWindow->addToFileList(source + " " + ReQStringUtils::readableSize(info.size()));
        m_processedFiles++;
        m_processedBytes += info.size();
 
        QString errorMsg = ReFileUtils::copy(source, target, &info, m_buffer);
        if (! errorMsg.isEmpty()){
                error(errorMsg);
-               m_mainWindow->expandFileList(errorMsg);
-       } else {
+               if (m_verboseLevel >= VerboseStandard)
+                       m_mainWindow->expandFileList(errorMsg);
+       } else if (m_verboseLevel >= VerboseStandard) {
                m_mainWindow->expandFileList(ReQStringUtils::readableDuration(
                                QDateTime::currentMSecsSinceEpoch() - start));
        }
@@ -252,15 +205,17 @@ void BackupTask::run()
                                relPath = info.mid(1, pos - 1);
                        node = info.mid(pos + 1);
                        copyFile(index, relPath, node);
-                       qint64 duration = QDateTime::currentMSecsSinceEpoch() - start.currentMSecsSinceEpoch();
-                       double factor = double(m_hotBytes) / max(1LL, m_processedBytes);
-                       m_mainWindow->externalAppend(ReGuiQueueItem::StatusLine, NULL,
-                                       tr("%1 of %2 (%3 of %4) %5 MB/sec runtime: %6")
-                                       .arg(m_processedFiles).arg(m_hotFiles)
-                                       .arg(ReQStringUtils::readableSize(m_processedBytes))
-                                       .arg(ReQStringUtils::readableSize(m_hotBytes))
-                                       .arg(m_processedBytes / 1024.0 / 1024 * 1000 / max(1LL, duration), 0, 'f', 3)
-                                       .arg(ReQStringUtils::runtimeEstimation(start, factor)));
+                       if (m_verboseLevel > VerboseQuiet){
+                               qint64 duration = QDateTime::currentMSecsSinceEpoch() - start.currentMSecsSinceEpoch();
+                               double factor = double(m_hotBytes) / max(1LL, m_processedBytes);
+                               m_mainWindow->externalAppend(ReGuiQueueItem::StatusLine, NULL,
+                                                                                        tr("%1 of %2 (%3 of %4) %5 MB/sec runtime: %6")
+                                                                                        .arg(m_processedFiles).arg(m_hotFiles)
+                                                                                        .arg(ReQStringUtils::readableSize(m_processedBytes))
+                                                                                        .arg(ReQStringUtils::readableSize(m_hotBytes))
+                                                                                        .arg(m_processedBytes / 1024.0 / 1024 * 1000 / max(1LL, duration), 0, 'f', 3)
+                                                                                        .arg(ReQStringUtils::runtimeEstimation(start, factor)));
+                       }
                }
        }
        m_mainWindow->externalTaskFinished(tr("backup complete after %1. Errors: %2")
@@ -314,7 +269,7 @@ QByteArray ChecksumTask::buildChecksum(bool isSource, int index,
        m_mutex.unlock();
        if (rc.isEmpty()){
                error(QObject::tr("cannot build checksum: %1").arg(filename) );
-       } else {
+       } if (m_verboseLevel >= VerboseStandard){
                m_mainWindow->addToFileList(QString(rc) + " " + filename);
        }
        return rc;
@@ -450,16 +405,18 @@ void ChecksumOfTargetTask::run()
                        processedBytes = m_processedBytes;
                        processedFiles = m_processedFiles;
                        m_mutex.unlock();
-                       now = QDateTime::currentMSecsSinceEpoch();
-                       qint64 duration = (now - start.currentMSecsSinceEpoch());
-                       double factor = double(m_hotBytes) * 2 / max(1LL, m_processedBytes);
-                       m_mainWindow->externalAppend(ReGuiQueueItem::StatusLine, NULL,
-                                       tr("%1 of %2 (%3 of %4) %5 MB/sec runtime: %6")
+                       if (m_verboseLevel > VerboseQuiet){
+                               now = QDateTime::currentMSecsSinceEpoch();
+                               qint64 duration = (now - start.currentMSecsSinceEpoch());
+                               double factor = double(m_hotBytes) * 2 / max(1LL, m_processedBytes);
+                               m_mainWindow->externalAppend(ReGuiQueueItem::StatusLine, NULL,
+                                                                                        tr("%1 of %2 (%3 of %4) %5 MB/sec runtime: %6")
                                        .arg(processedFiles).arg(hotFiles * 2)
                                                                                 .arg(ReQStringUtils::readableSize(processedBytes))
                                                                                 .arg(ReQStringUtils::readableSize(hotBytes * 2))
                                                                                 .arg(processedBytes / 1024.0 / 1024 / max(1LL, duration) * 1000.0, 0, 'f', 3)
                                                                                 .arg(ReQStringUtils::runtimeEstimation(start, factor)));
+                       }
 
                }
        }
@@ -514,6 +471,7 @@ void CleanTask::run()
                } else {
                        int index = int(info.at(0).unicode()) - 1;
                        int pos = info.indexOf(m_separator, 1);
+                       struct stat info2;
                        if (pos == 1)
                                relPath.clear();
                        else
@@ -522,14 +480,22 @@ void CleanTask::run()
                        node = info.mid(pos + 2);
                        switch(command){
                        case CmdRemove:
-                               if (unlink(I18N::s2b(relPath)) != 0)
-                                       error(QObject::tr("cannot delete target (%1): %2").arg(errno)
+                               if (unlink(I18N::s2b(relPath)) != 0){
+                                       int errNo = errno;
+                                       if (stat(I18N::s2b(relPath), &info2) == 0)
+                                               error(QObject::tr("cannot delete (%1): %2").arg(errNo)
                                                  .arg(relPath));
-                               else
+                               } else if (m_verboseLevel >= VerboseStandard)
                                        m_mainWindow->addToFileList("- " + relPath);
                                break;
                        case CmdRemoveDir:
-                               m_mainWindow->addToFileList("/ " + relPath);
+                               if (_rmdir(I18N::s2b(relPath)) != 0){
+                                       int errNo = errno;
+                                       if (stat(I18N::s2b(relPath), &info2) == 0)
+                                               error(QObject::tr("cannot remove directory (%1): %2").arg(errNo)
+                                                 .arg(relPath));
+                               } else if (m_verboseLevel >= VerboseStandard)
+                                       m_mainWindow->addToFileList("/ " + relPath);
                                break;
                        case CmdMove:
                        {
@@ -551,24 +517,27 @@ void CleanTask::run()
                                if (rename(I18N::s2b(target).constData(), shadow2.constData()) != 0)
                                        error(QObject::tr("cannot rename target file (%1): %2 -> %3")
                                                  .arg(errno).arg(target).arg(shadow));
-                               m_mainWindow->addToFileList(">" + target);
+                               if (m_verboseLevel >= VerboseStandard)
+                                       m_mainWindow->addToFileList(">" + target);
                                break;
                        }
                        default:
                                error("unknown command: " + QString::number(command));
                                break;
                        }
-                       double factor = double(m_hotFiles) / max(1, m_processedFiles);
-                       qint64 duration = QDateTime::currentMSecsSinceEpoch() - start.currentMSecsSinceEpoch();
-                       m_mainWindow->externalAppend(ReGuiQueueItem::StatusLine, NULL,
-                                       tr("%1 of %2 (%3 of %4) %5 MB/sec runtime: %6")
-                                       .arg(m_processedFiles)
-                                       .arg(m_hotFiles)
-                                       .arg(ReQStringUtils::readableSize(m_processedBytes))
-                                       .arg(ReQStringUtils::readableSize(m_hotBytes))
-                                       .arg(m_processedBytes / 1024.0 / 1024 * 1000
-                                                / max(1.0, (double) duration), 0, 'f', 3)
-                                       .arg(ReQStringUtils::runtimeEstimation(start, factor)));
+                       if (m_verboseLevel > VerboseQuiet){
+                               double factor = double(m_hotFiles) / max(1, m_processedFiles);
+                               qint64 duration = QDateTime::currentMSecsSinceEpoch() - start.currentMSecsSinceEpoch();
+                               m_mainWindow->externalAppend(ReGuiQueueItem::StatusLine, NULL,
+                                                                                        tr("%1 of %2 (%3 of %4) %5 MB/sec runtime: %6")
+                                                                                        .arg(m_processedFiles)
+                                                                                        .arg(m_hotFiles)
+                                                                                        .arg(ReQStringUtils::readableSize(m_processedBytes))
+                                                                                        .arg(ReQStringUtils::readableSize(m_hotBytes))
+                                                                                        .arg(m_processedBytes / 1024.0 / 1024 * 1000
+                                                                                                 / max(1.0, (double) duration), 0, 'f', 3)
+                                                                                        .arg(ReQStringUtils::runtimeEstimation(start, factor)));
+                       }
                }
        }
        m_mainWindow->externalTaskFinished(tr("backup complete after %1. Errors: %2")
@@ -748,6 +717,61 @@ SearchTargetTask::SearchTargetTask(const QString& name, const QStringList& sourc
        initializeShadowDir();
 }
 
+/**
+ * Inserts a remove command into queue for too old files in the shadow.
+ *
+ * Note: this method is recursive.
+ *
+ * @param directory    directory to inspect, e.g. "/media/trg/x"
+ * @param maxAge       all files older than this time point will be deleted
+ * @return                     <code>true</code>: the directory was deleted if empty
+ */
+bool SearchTargetTask::removeOlder(const QString& directory, const QDateTime& time){
+       QDirIterator it(directory);
+       QString info, node;
+       m_mutex.lock();
+       m_totalDirs++;
+       m_mutex.unlock();
+       bool isEmpty = true;
+       while (it.hasNext()){
+          if (m_shouldStop){
+                 break;
+          }
+          it.next();
+          node = it.fileName();
+          if (it.fileInfo().isDir()){
+                  if (node != "." && node != ".."){
+                          if (! removeOlder(it.filePath(), time))
+                                  isEmpty = false;
+                  }
+          } else if (it.fileInfo().lastModified() < time){
+                  if (m_verboseLevel >= VerboseChatty)
+                          m_mainWindow->addToFileList("% " + it.filePath() + " "
+                                                                                  + it.fileInfo().lastModified().toString("yyyy.MM.dd/hh:mm:ss"));
+                  isEmpty = false;
+                  info = QChar(MAX_INDEX) + it.filePath() + m_separatorString
+                                  + QChar(CmdRemove);
+                  m_mutex.lock();
+                  m_files.append(info);
+                  m_hotFiles++;
+                  m_hotBytes += it.fileInfo().size();
+                  m_totalFiles++;
+                  m_mutex.unlock();
+          }
+       }
+       if (isEmpty){
+               if (m_verboseLevel >= VerboseChatty)
+                       m_mainWindow->addToFileList("x " + directory);
+               info = QChar(MAX_INDEX) + directory + m_separatorString
+                               + QChar(CmdRemoveDir);
+               m_mutex.lock();
+               m_files.append(info);
+               m_matchedFiles++;
+               m_mutex.unlock();
+       }
+       return isEmpty;
+}
+
 /**
  * Search the files to clean.
  *
@@ -786,6 +810,8 @@ void SearchTargetTask::searchOneDirectory(const QString& target,
                   QString fullSrc = source + it.fileName();
                   QFileInfo src(fullSrc);
                   if (! src.exists()){
+                          if (m_verboseLevel >= VerboseChatty)
+                                  m_mainWindow->addToFileList("? " + fullSrc);
                           const QFileInfo trg = it.fileInfo();
                           QDateTime trgTime = trg.lastModified();
                           if (trgTime < m_maxAge){
@@ -846,8 +872,6 @@ void SearchTargetTask::moveToShadow(const QString& target, const QString& relPat
                if (rename(I18N::s2b(target).constData(), I18N::s2b(shadow).constData()) != 0){
                        error(QObject::tr("cannot move to shadow directory (%1): %2 -> %3")
                                  .arg(errno).arg(target).arg(shadow));
-               } else {
-                       removeOlder(shadow, m_maxAge);
                }
        }
 }
index 80b1cacb40bad78f5dc544f8e713eacfc5acfae4..598eac1011327d2f6e8476654a1e7cd239f84b31 100644 (file)
@@ -35,7 +35,6 @@ public:
    bool log(const QString& message);
 protected:
    void initializeShadowDir();
-   void removeOlder(const QString& directory, const QDateTime& time);
        virtual void run() = 0;
 protected:
    // list of source dirs, trailing with separator
@@ -51,6 +50,7 @@ protected:
    MainWindow* m_mainWindow;
    QString m_name;
 public:
+   static ReVerbose_t m_verboseLevel;
    static bool m_shouldStop;
    /// Entry: <index_of_source_dir><relative_path>TAB<node>
    static QStringList m_files;
@@ -192,6 +192,7 @@ public:
        virtual void run();
 private:
        void moveToShadow(const QString& target, const QString& relPath, int index);
+       bool removeOlder(const QString& directory, const QDateTime& time);
        void searchOneDirectory(const QString& target, const QString& source,
                                                        int index);
 protected:
index 348eb3554d87289419c2e24b4fa54bc0c05393a4..b6edc2cc325bee93cc19f6a52b06c48ca0ffcabb 100644 (file)
@@ -114,7 +114,7 @@ void Configuration::load(QString filename)
        FILE* fp = fopen(I18N::s2b(filename).constData(), "r");
        m_items.clear();
        if (fp == NULL){
-               m_mainWindow->error(QObject::tr("cannot open (%1): %2").arg(errno)
+               m_mainWindow->say(LOG_ERROR, QObject::tr("cannot open (%1): %2").arg(errno)
                                                                        .arg(filename));
        } else {
                char line[64000];
@@ -146,7 +146,7 @@ void Configuration::load(QString filename)
                                if (time > 24*3600)
                                        getItem(no, map).m_lastBackup.setMSecsSinceEpoch(time);
                        } else {
-                               m_mainWindow->error(QObject::tr("unknown format in %1-%2: %3")
+                               m_mainWindow->say(LOG_ERROR, QObject::tr("unknown format in %1-%2: %3")
                                                                                        .arg(filename).arg(lineNo)
                                                                                        .arg(line2));
                        }
@@ -174,7 +174,7 @@ void Configuration::save(QString filename)
                filename = m_mainWindow->fileOfHome(m_mainWindow->applicationName() + ".conf");
        FILE* fp = fopen(I18N::s2b(filename).constData(), "w");
        if (fp == NULL){
-               m_mainWindow->error(QObject::tr("cannot open (%1): %2").arg(errno)
+               m_mainWindow->say(LOG_ERROR, QObject::tr("cannot open (%1): %2").arg(errno)
                                                                        .arg(filename));
        } else {
                QByteArray buffer;
@@ -195,7 +195,7 @@ void Configuration::save(QString filename)
                        buffer += "lastbackup." + QByteArray::number(ix) + "="
                                        + BackupUtils::dateToString(item.m_lastBackup) + "\n";
                        if (fputs(buffer.constData(), fp) < 0)
-                               m_mainWindow->error(QObject::tr("cannot write (%1): %2").arg(errno)
+                               m_mainWindow->say(LOG_ERROR, QObject::tr("cannot write (%1): %2").arg(errno)
                                                                                        .arg(filename));
                }
                fclose(fp);
index 2524d4d049138308b0c0a147739423610bbae223..c6bb0368ffb4001df31dadab34c2c0397608d7e7 100644 (file)
@@ -106,6 +106,15 @@ void MainWindow::addToFileList(const QString info){
        externalAppend(ReGuiQueueItem::ListEnd, ui->listWidgetFile, info);
 }
 
+/**
+ * Returns the error count.
+ * @return     the error count
+ */
+int MainWindow::errors() const
+{
+       return m_errors;
+}
+
 /**
  * Appends a string to the current line in the filelist.
  *
@@ -117,29 +126,6 @@ void MainWindow::expandFileList(const QString info){
        externalAppend(ReGuiQueueItem::ListAppendToCurrent, ui->listWidgetFile, info);
 }
 
-/**
- * Issues an error message.
- *
- * @param message      the message to issue
- * @return                     <code>false</code>
- */
-bool MainWindow::error(const QString& message){
-       ui->listWidgetError->addItem(message);
-       ui->listWidgetError->setCurrentRow(ui->listWidgetError->count() - 1);
-       m_errors++;
-       return false;
-}
-
-/**
- * Returns the count of errors since the last start of the backup.
- *
- * @return     the current count of errors
- */
-int MainWindow::errors() const
-{
-       return m_errors;
-}
-
 /**
  * Find the target identification.
  *
@@ -184,20 +170,20 @@ void MainWindow::onGuiTimerUpdate()
                                ui->listWidgetLog->addItem(item.m_value);
                                break;
                        case ReGuiQueueItem::ReadyMessage:
-                               log(item.m_value);
+                               say(LOG_INFO, item.m_value);
                                startStop(false);
                                break;
                        case ReGuiQueueItem::LogMessage:
-                               log(item.m_value);
+                               say(LOG_INFO, item.m_value);
                                break;
                        case ReGuiQueueItem::LogError:
-                               error(item.m_value);
+                               say(LOG_ERROR, item.m_value);
                                break;
                        case ReGuiQueueItem::StatusLine:
                                setStatusMessage(LOG_INFO, item.m_value);
                                break;
                        default:
-                               error("unknown item type: " + QString::number(item.m_type)
+                               say(LOG_ERROR, "unknown item type: " + QString::number(item.m_type)
                                        + " " + item.m_value);
                                break;
                        }
@@ -236,18 +222,6 @@ bool MainWindow::initializeStart(){
        return rc;
 }
 
-/**
- * @brief Logs a message
- *
- * @param message   the message to log
- * @return          <code>true</code>
- */
-bool MainWindow::log(const QString& message){
-   ui->listWidgetLog->addItem(message);
-   ui->listWidgetLog->setCurrentRow(ui->listWidgetLog->count() - 1);
-   return true;
-}
-
 /**
  * Shows the "about" window.
  */
@@ -550,10 +524,20 @@ void MainWindow::saveState(){
  * @return                     <code>false</code>level is error or warning
  */
 bool MainWindow::say(ReLoggerLevel level, const QString& message){
-       if (level == LOG_ERROR || level == LOG_WARNING)
-               error(message);
-       else
-               log(message);
+       switch(level){
+       case LOG_ERROR:
+       case LOG_WARNING:
+               ui->listWidgetError->addItem(message);
+               ui->listWidgetError->setCurrentRow(ui->listWidgetError->count() - 1);
+               setStatusMessage(LOG_ERROR, message);
+               m_errors++;
+               break;
+       default:
+       case LOG_INFO:
+               ui->listWidgetLog->addItem(message);
+               ui->listWidgetLog->setCurrentRow(ui->listWidgetLog->count() - 1);
+               break;
+       }
        return level >= LOG_INFO;
 }
 
@@ -570,6 +554,8 @@ void MainWindow::startStop(bool isStart){
        ui->pushButtonStop->setEnabled(isStart);
        ui->pushButtonChecksum->setEnabled(! isStart);
        ui->actionChecksums->setEnabled(! isStart);
+       if (isStart)
+               BackupEngine::m_verboseLevel = (ReVerbose_t) ui->comboBoxVerbose->currentIndex();
 }
 
 
index ed735f713c1287f0017b64572214d38b8dbf02b8..d12b9888c4de1180b150f51bf811174cb67b2c51 100644 (file)
@@ -28,10 +28,8 @@ public:
 public:
        void addToFileList(const QString info);
        QString buildTargetDir(const QString& target);
-   bool error(const QString& message);
    int errors() const;
    void expandFileList(const QString info);
-   bool log(const QString& message);
    virtual bool say(ReLoggerLevel level, const QString& message);
    void startStop(bool isStart);
    void restoreState();
index b85e259286a4507dfa2c53073c4abc9ce45ae9fb..884d43fb1dc4c2558e6dc7a6e25d9616abb51ed4 100644 (file)
                   <height>0</height>
                  </size>
                 </property>
+                <property name="maximumSize">
+                 <size>
+                  <width>16777215</width>
+                  <height>16777215</height>
+                 </size>
+                </property>
                 <property name="toolTip">
                  <string>Starting a task cleans filelist and errorlist</string>
                 </property>
                 </property>
                </spacer>
               </item>
+              <item>
+               <widget class="QComboBox" name="comboBoxVerbose">
+                <property name="minimumSize">
+                 <size>
+                  <width>125</width>
+                  <height>0</height>
+                 </size>
+                </property>
+                <property name="toolTip">
+                 <string>Verbose level</string>
+                </property>
+                <property name="currentIndex">
+                 <number>2</number>
+                </property>
+                <item>
+                 <property name="text">
+                  <string>Quiet</string>
+                 </property>
+                </item>
+                <item>
+                 <property name="text">
+                  <string>Summary</string>
+                 </property>
+                </item>
+                <item>
+                 <property name="text">
+                  <string>File log</string>
+                 </property>
+                </item>
+                <item>
+                 <property name="text">
+                  <string>Chatty</string>
+                 </property>
+                </item>
+               </widget>
+              </item>
              </layout>
             </item>
             <item>
index 9322374a09f1aa228f07e533a9d0cc797228913e..56a121bda1de6be4b6e6fbace1abb5a248842424 100644 (file)
@@ -88,7 +88,7 @@ typedef int mode_t;
 #define OS_2nd_SEPARATOR '/'
 #define OS_2nd_SEPARATOR_STR "/"
 #endif
-
+enum ReVerbose_t { VerboseQuiet, VerboseSummary, VerboseStandard, VerboseChatty };
 typedef union {
 public:
        inline void fromBytes(const uint8_t* source){