From: hama Date: Sat, 13 Feb 2016 10:30:07 +0000 (+0100) Subject: rebackgui works X-Git-Url: https://gitweb.hamatoma.de/?a=commitdiff_plain;h=b0673ed9f1c30e2d8cd6e51dd99098a15f2b1a85;p=reqt rebackgui works --- diff --git a/appl/rebackgui/BackupEngine.cpp b/appl/rebackgui/BackupEngine.cpp index 56a906f..8ee51a9 100644 --- a/appl/rebackgui/BackupEngine.cpp +++ b/appl/rebackgui/BackupEngine.cpp @@ -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 true: 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); } } } diff --git a/appl/rebackgui/BackupEngine.hpp b/appl/rebackgui/BackupEngine.hpp index 80b1cac..598eac1 100644 --- a/appl/rebackgui/BackupEngine.hpp +++ b/appl/rebackgui/BackupEngine.hpp @@ -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: TAB 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: diff --git a/appl/rebackgui/Configuration.cpp b/appl/rebackgui/Configuration.cpp index 348eb35..b6edc2c 100644 --- a/appl/rebackgui/Configuration.cpp +++ b/appl/rebackgui/Configuration.cpp @@ -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); diff --git a/appl/rebackgui/mainwindow.cpp b/appl/rebackgui/mainwindow.cpp index 2524d4d..c6bb036 100644 --- a/appl/rebackgui/mainwindow.cpp +++ b/appl/rebackgui/mainwindow.cpp @@ -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 false - */ -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 true - */ -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 falselevel 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(); } diff --git a/appl/rebackgui/mainwindow.hpp b/appl/rebackgui/mainwindow.hpp index ed735f7..d12b988 100644 --- a/appl/rebackgui/mainwindow.hpp +++ b/appl/rebackgui/mainwindow.hpp @@ -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(); diff --git a/appl/rebackgui/mainwindow.ui b/appl/rebackgui/mainwindow.ui index b85e259..884d43f 100644 --- a/appl/rebackgui/mainwindow.ui +++ b/appl/rebackgui/mainwindow.ui @@ -128,6 +128,12 @@ 0 + + + 16777215 + 16777215 + + Starting a task cleans filelist and errorlist @@ -152,6 +158,42 @@ + + + + + 125 + 0 + + + + Verbose level + + + 2 + + + + Quiet + + + + + Summary + + + + + File log + + + + + Chatty + + + + diff --git a/base/rebase.hpp b/base/rebase.hpp index 9322374..56a121b 100644 --- a/base/rebase.hpp +++ b/base/rebase.hpp @@ -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){