diff options
Diffstat (limited to 'consistencycheck.cpp')
-rw-r--r-- | consistencycheck.cpp | 215 |
1 files changed, 170 insertions, 45 deletions
diff --git a/consistencycheck.cpp b/consistencycheck.cpp index 43e06d2..7330cd2 100644 --- a/consistencycheck.cpp +++ b/consistencycheck.cpp @@ -24,20 +24,42 @@ #include <QDir> #include <QFileDialog> #include <QMessageBox> +#include <QProgressBar> +#include <QGroupBox> #include "consistencycheck.h" #include "helper.h" ConsistencyCheck::ConsistencyCheck(QWidget *parent, Qt::WindowFlags f) : SmDialog(parent, f), mChecker(0){ // setup widget - QLabel *okLabel = new QLabel(tr("Ok")); + // OK + QGroupBox *okBox = new QGroupBox(tr("Ok")); + QHBoxLayout *okLayout = new QHBoxLayout; mOkDisplay = new QPlainTextEdit; mOkDisplay->setReadOnly(true); mOkDisplay->setLineWrapMode(QPlainTextEdit::NoWrap); - QLabel *errorLabel = new QLabel(tr("Errors")); + okLayout->addWidget(mOkDisplay); + okBox->setLayout(okLayout); + + // Errors + QGroupBox *errorBox = new QGroupBox(tr("Errors")); + QHBoxLayout *errorLayout = new QHBoxLayout; mErrorDisplay = new QPlainTextEdit; mErrorDisplay->setReadOnly(true); mErrorDisplay->setLineWrapMode(QPlainTextEdit::NoWrap); + errorLayout->addWidget(mErrorDisplay); + errorBox->setLayout(errorLayout); + + // Progress + QGroupBox *progressBox = new QGroupBox(tr("Progress")); + QVBoxLayout *progressLayout = new QVBoxLayout; + mProgress = new QProgressBar(); + progressLayout->addWidget(mProgress); + mActivity = new QLabel(tr("Idle...")); + progressLayout->addWidget(mActivity); + progressBox->setLayout(progressLayout); + + // Buttons mCancelExit = new QPushButton(tr("Close")); mCheckDb = new QPushButton(tr("Check database")); mCheckFs = new QPushButton(tr("Check Filesystem")); @@ -65,19 +87,36 @@ ConsistencyCheck::ConsistencyCheck(QWidget *parent, Qt::WindowFlags f) : SmDialo connect(mChecker, SIGNAL(started()), this, SLOT(checkerStarted())); connect(mChecker, SIGNAL(finished()), this, SLOT(checkerFinished())); connect(mChecker, SIGNAL(consistencyMsg(QString)), this, SLOT(addMessage(QString))); + connect(mChecker, SIGNAL(approxTotal(int)), this, SLOT(setProgressBarMax(int))); + connect(mChecker, SIGNAL(progress(int)), this, SLOT(setProgress(int))); // main layout QVBoxLayout *mainLayout = new QVBoxLayout; - mainLayout->addWidget(okLabel); - mainLayout->addWidget(mOkDisplay); - mainLayout->addWidget(errorLabel); - mainLayout->addWidget(mErrorDisplay); + mainLayout->addWidget(okBox); + mainLayout->addWidget(errorBox); + mainLayout->addWidget(progressBox); mainLayout->addLayout(buttonLayout); setWindowTitle(tr("Checking consistency")); setLayout(mainLayout); setMinimumWidth(600); } +void ConsistencyCheck::setProgressBarMax(int max){ + mProgress->reset(); + mProgress->setMaximum(max); + QString activity = QString(tr("Expecting %1 files")).arg(QString::number(max)); + mActivity->setText(activity); +} + +void ConsistencyCheck::setProgress(int value){ + if(value >= mProgress->maximum()){ + mProgress->setMaximum(value + 100); + QString activity = QString(tr("Just got pregnant. Expecting %1 now.")).arg(QString::number(value + 100)); + mActivity->setText(activity); + } + mProgress->setValue(value); +} + void ConsistencyCheck::startChecker(int checkerType){ if(mChecker->status() == ConsistencyChecker::Fail){ return; @@ -125,13 +164,15 @@ void ConsistencyCheck::checkerStarted(){ } void ConsistencyCheck::checkerFinished(){ + mProgress->setValue(mProgress->maximum()); + mActivity->setText(tr("Idle...")); mCheckDb->setEnabled(true); mCheckFs->setEnabled(true); mCancelExit->setText(tr("Close")); mCancelExit->disconnect(); connect(mCancelExit, SIGNAL(clicked()), this, SLOT(accept())); mChecker->setCancel(false); - if(!mChecker->strayFiles().isEmpty() || !mChecker->strayIds().isEmpty()){ + if(!mChecker->strayFiles().isEmpty() || !mChecker->strayFileIds().isEmpty()){ mCleanup->setEnabled(true); } } @@ -144,14 +185,22 @@ void ConsistencyCheck::cleanup(){ QStringList strayFiles = mChecker->strayFiles(); moveFiles(strayFiles); if(mChecker->mode() == DbCheck){ - QList<int> fileIds = mChecker->strayIds(); + QList<int> fileIds = mChecker->strayFileIds(); if(!fileIds.isEmpty()){ - QString msg = QString(tr("Really delete %1 entries from database?")).arg(QString::number(fileIds.count())); + QString msg = QString(tr("Really delete %1 files from database?")).arg(QString::number(fileIds.count())); int retval = QMessageBox::critical(this, tr("Delete from database"), msg, QMessageBox::Yes | QMessageBox::No); if(retval == QMessageBox::Yes){ - mChecker->deleteIds(fileIds); + mChecker->deleteFileIds(fileIds); } } + QList<int> picIds = mChecker->strayPicIds(); + if(!picIds.isEmpty()){ + QString msg = QString(tr("Really delete %1 pictures from database?")).arg(QString::number(picIds.count())); + int retval = QMessageBox::critical(this, tr("Delete from database"), msg, QMessageBox::Yes | QMessageBox::No); + if(retval == QMessageBox::Yes){ + //mChecker->deleteIds(fileIds); + } + } } mCleanup->setEnabled(false); } @@ -210,14 +259,19 @@ void ConsistencyChecker::clearStrayFiles(){ mStrayFiles.clear(); } -const QList<int> ConsistencyChecker::strayIds(){ - QMutexLocker locker(&mStrayIdsMutex); - return mStrayIds; +const QList<int> ConsistencyChecker::strayFileIds(){ + QMutexLocker locker(&mStrayFileIdMutex); + return mStrayFileIds; +} + +const QList<int> ConsistencyChecker::strayPicIds(){ + QMutexLocker locker(&mStrayPicsIdMutex); + return mStrayPicIds; } void ConsistencyChecker::clearStrayIds(){ - QMutexLocker locker(&mStrayIdsMutex); - mStrayIds.clear(); + QMutexLocker locker(&mStrayFileIdMutex); + mStrayFileIds.clear(); } void ConsistencyChecker::setCancel(bool cancel){ @@ -225,7 +279,7 @@ void ConsistencyChecker::setCancel(bool cancel){ mCanceled = cancel; } -void ConsistencyChecker::deleteIds(const QList<int> &ids){ +void ConsistencyChecker::deleteFileIds(const QList<int> &ids){ QSqlQuery idQuery(mDb); idQuery.prepare("DELETE FROM files WHERE ifiles_id = :id"); foreach(int id, ids){ @@ -234,6 +288,15 @@ void ConsistencyChecker::deleteIds(const QList<int> &ids){ } } +void ConsistencyChecker::deletePicIds(const QList<int> &ids){ + QSqlQuery idQuery(mDb); + idQuery.prepare("DELETE FROM pics WHERE ipicsid = :id"); + foreach(int id, ids){ + idQuery.bindValue(":id", id); + idQuery.exec(); + } +} + void ConsistencyChecker::run(){ clearStrayFiles(); clearStrayIds(); @@ -241,14 +304,18 @@ void ConsistencyChecker::run(){ fsCheck(); } if(mMode == ConsistencyCheck::DbCheck){ - dbCheck(); + dbCheck(); } } -void ConsistencyChecker::dbCheck(){ +void ConsistencyChecker::doDbCheckFiles(){ QSqlQuery fileDbQuery = QSqlQuery("SELECT tfilename, cmd5sum, idvd, ifiles_id FROM files ORDER BY tfilename", mDb); while(fileDbQuery.next()){ - QMutexLocker locker(&mCancelMutex); + ++mCurCount; + if(mCurCount % 50 == 0){ + emit progress(mCurCount); + } + QMutexLocker locker(&mCancelMutex); if(mCanceled){ quit(); }else{ @@ -263,9 +330,9 @@ void ConsistencyChecker::dbCheck(){ if(dvdNo != -1){ emit consistencyMsg(QString(tr("OK: %1")).arg(fileName)); }else{ - mStrayIdsMutex.lock(); - mStrayIds << fileId; - mStrayIdsMutex.unlock(); + mStrayFileIdMutex.lock(); + mStrayFileIds << fileId; + mStrayFileIdMutex.unlock(); emit consistencyMsg(QString(tr("NOT FOUND: %1")).arg(fileName)); } }else{ @@ -288,44 +355,102 @@ void ConsistencyChecker::dbCheck(){ quit(); } +void ConsistencyChecker::doDbCheckPics(){ + QSqlQuery picsQuery = QSqlQuery("SELECT tfilename, cmd5sum, ipicsid FROM pics ORDER BY tfilename", mDb); + while(picsQuery.next()){ + ++mCurCount; + if(mCurCount % 50 == 0){ + emit progress(mCurCount); + } + QMutexLocker locker(&mCancelMutex); + if(mCanceled){ + quit(); + }else{ + locker.unlock(); + } + QString fileName = picsQuery.value(0).toString(); + QString md5sum = picsQuery.value(1).toString(); + QString fullPath = archivePath(fileName, md5sum); + if(fullPath.isEmpty()){ + mStrayPicsIdMutex.lock(); + mStrayPicIds << picsQuery.value(2).toInt(); + mStrayPicsIdMutex.unlock(); + emit consistencyMsg(QString(tr("NOT FOUND: %1")).arg(fileName)); + }else{ + emit consistencyMsg(QString(tr("OK: %1")).arg(fileName)); + } + } +} + +void ConsistencyChecker::dbCheck(){ + QSqlQuery numFilesQ("SELECT COUNT(*) FROM files", mDb); + int numFiles; + while(numFilesQ.next()){ + numFiles = numFilesQ.value(0).toInt(); + } + QSqlQuery numPicsQ("SELECT COUNT(*) FROM pics", mDb); + int numPics; + while(numPicsQ.next()){ + numPics = numPicsQ.value(0).toInt(); + } + emit approxTotal(numFiles + numPics); + mCurCount = 0; + doDbCheckFiles(); + doDbCheckPics(); + quit(); +} + void ConsistencyChecker::fsCheck(){ mStrayFilesMutex.lock(); mStrayFiles.clear(); mStrayFilesMutex.unlock(); + QVector<QString> md5sums; + QSqlQuery picsmd5("SELECT cmd5sum FROM pics", mDb); + while(picsmd5.next()){ + md5sums << picsmd5.value(0).toString(); + } + QSqlQuery filesmd5("SELECT cmd5sum FROM files", mDb); + while(filesmd5.next()){ + md5sums << filesmd5.value(0).toString(); + } + emit approxTotal(md5sums.size()); + mCurCount = 0; QSettings s; QString startDir = s.value("paths/archivedir").toString(); QFileInfo startFi(startDir); - doFsCheck(startFi); + doFsCheck(startFi, md5sums); quit(); } -void ConsistencyChecker::doFsCheck(const QFileInfo &start){ +void ConsistencyChecker::doFsCheck(const QFileInfo &start, const QVector<QString> &md5sums){ if(start.isDir()){ - QMutexLocker locker(&mCancelMutex); - if(mCanceled){ - quit(); - }else{ - locker.unlock(); - } QDir curDir(start.absoluteFilePath()); foreach(QFileInfo fi, curDir.entryInfoList(QDir::AllEntries | QDir::NoDotAndDotDot)){ + mCancelMutex.lock(); + if(mCanceled){ + mCancelMutex.unlock(); + return; + } + mCancelMutex.unlock(); if(fi.isDir()){ - doFsCheck(fi); - }else{ + if(fi.fileName() == ".frameCache"){ + continue; + } + doFsCheck(fi, md5sums); + }else{ QString md5sum = Helper::md5Sum(fi.absoluteFilePath()); - mFileQuery->bindValue(":md5sum", md5sum); - mFileQuery->exec(); - while(mFileQuery->next()){ - int count = mFileQuery->value(0).toInt(); - if(count > 0){ - emit consistencyMsg(QString(tr("OK: %1 -> %2")).arg(fi.fileName()).arg(md5sum)); - }else{ - mStrayFilesMutex.lock(); - mStrayFiles << fi.absoluteFilePath(); - mStrayFilesMutex.unlock(); - emit consistencyMsg(QString(tr("NOT FOUND: %1 -> %2")).arg(fi.fileName()).arg(md5sum)); - } - } + if(md5sums.contains(md5sum)){ + emit consistencyMsg(QString(tr("OK: %1 -> %2")).arg(fi.fileName()).arg(md5sum)); + }else{ + mStrayFilesMutex.lock(); + mStrayFiles << fi.absoluteFilePath(); + mStrayFilesMutex.unlock(); + emit consistencyMsg(QString(tr("NOT FOUND: %1 -> %2")).arg(fi.fileName()).arg(md5sum)); + } + ++mCurCount; + if(mCurCount % 50 == 0){ + emit progress(mCurCount); + } } } } |