summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--consistencycheck.cpp215
-rw-r--r--consistencycheck.h29
2 files changed, 193 insertions, 51 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);
+ }
}
}
}
diff --git a/consistencycheck.h b/consistencycheck.h
index b62dfbc..ca078f1 100644
--- a/consistencycheck.h
+++ b/consistencycheck.h
@@ -23,6 +23,7 @@ class QString;
class QSqlQuery;
class QFileInfo;
class ConsistencyChecker;
+class QProgressBar;
class ConsistencyCheck : public SmDialog {
Q_OBJECT
@@ -30,6 +31,10 @@ class ConsistencyCheck : public SmDialog {
enum Mode { DbCheck, FsCheck };
explicit ConsistencyCheck(QWidget *parent = 0, Qt::WindowFlags f = 0);
+ public slots:
+ void setProgressBarMax(int max);
+ void setProgress(int value);
+
private slots:
void startChecker(int checkerType);
void addMessage(const QString &message);
@@ -46,6 +51,8 @@ class ConsistencyCheck : public SmDialog {
QPushButton *mCleanup;
QPlainTextEdit *mOkDisplay;
QPlainTextEdit *mErrorDisplay;
+ QLabel *mActivity;
+ QProgressBar *mProgress;
ConsistencyChecker *mChecker;
};
@@ -56,32 +63,39 @@ class ConsistencyChecker : public QThread {
explicit ConsistencyChecker(QObject *parent = 0);
~ConsistencyChecker();
int mode() const { return mMode; }
+ int count() const { return mCurCount; }
void setMode(int mode) { mMode = mode; }
int status() const { return mStatus; }
void setStatus(int status) { mStatus = status; }
void check();
const QStringList strayFiles();
void clearStrayFiles();
- const QList<int> strayIds();
+ const QList<int> strayFileIds();
+ const QList<int> strayPicIds();
void clearStrayIds();
public slots:
void setCancel(bool cancel);
- void deleteIds(const QList<int> &ids);
+ void deleteFileIds(const QList<int> &ids);
+ void deletePicIds(const QList<int> &ids);
private slots:
- void dbCheck();
+ void dbCheck();
void fsCheck();
signals:
void consistencyMsg(const QString &msg);
+ void approxTotal(int);
+ void progress(int);
protected:
void run();
private:
QString archivePath(const QString &fileName, const QString &md5sum) const;
- void doFsCheck(const QFileInfo &start);
+ void doFsCheck(const QFileInfo &start, const QVector<QString> &md5sums);
+ void doDbCheckFiles();
+ void doDbCheckPics();
bool mCanceled;
int mMode;
int mStatus;
@@ -89,9 +103,12 @@ class ConsistencyChecker : public QThread {
QSqlQuery *mFileQuery;
QMutex mCancelMutex;
QMutex mStrayFilesMutex;
- QMutex mStrayIdsMutex;
+ QMutex mStrayFileIdMutex;
+ QMutex mStrayPicsIdMutex;
QStringList mStrayFiles;
- QList<int> mStrayIds;
+ QList<int> mStrayFileIds;
+ QList<int> mStrayPicIds;
+ int mCurCount;
};
#endif // CONSISTENCYCHECK_H