From 78d26758184cd23b0ea27ab714a9e1d1c3aeba9b Mon Sep 17 00:00:00 2001 From: Arno Date: Sun, 31 Oct 2010 13:41:52 +0100 Subject: First try on ConsistencyChecker Well, it works, so let's shit it :) Unfortunately the database is inconsistent, so add a checker for that. Still needs some work, though. Eg. display errors seperately and make it possible to delete stray files. Also the Filesystem check must be implemented. --- consistencycheck.cpp | 176 +++++++++++++++++++++++++++++++++++++++++++++++++++ consistencycheck.h | 73 +++++++++++++++++++++ seriestreemodel.cpp | 1 + seriestreemodel.h | 2 + shemov.cpp | 9 +++ shemov.h | 5 +- shemov.pro | 6 +- 7 files changed, 268 insertions(+), 4 deletions(-) create mode 100644 consistencycheck.cpp create mode 100644 consistencycheck.h diff --git a/consistencycheck.cpp b/consistencycheck.cpp new file mode 100644 index 0000000..38aa4a1 --- /dev/null +++ b/consistencycheck.cpp @@ -0,0 +1,176 @@ +/* + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version + 2 of the License, or (at your option) any later version. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "consistencycheck.h" +#include "helper.h" + +ConsistencyCheck::ConsistencyCheck(QWidget *parent, Qt::WindowFlags f) : QDialog(parent, f), mChecker(0){ + // setup widget + mCheckLabel = new QLabel(tr("Checking database consistency")); + mDisplay = new QTextEdit; + mCancelExit = new QPushButton(tr("Cancel")); + mCheckDb = new QPushButton(tr("Check database")); + mCheckFs = new QPushButton(tr("Check Filesystem")); + QHBoxLayout *buttonLayout = new QHBoxLayout; + buttonLayout->addWidget(mCheckDb); + buttonLayout->addWidget(mCheckFs); + buttonLayout->addStretch(); + buttonLayout->addWidget(mCancelExit); + connect(mCancelExit, SIGNAL(clicked()), this, SLOT(cancelExit())); + + // signal mapper + QSignalMapper *mapper = new QSignalMapper(this); + connect(mCheckDb, SIGNAL(clicked()), mapper, SLOT(map())); + mapper->setMapping(mCheckDb, ConsistencyCheck::DbCheck); + connect(mCheckFs, SIGNAL(clicked()), mapper, SLOT(map())); + mapper->setMapping(mCheckFs, ConsistencyCheck::FsCheck); + connect(mapper, SIGNAL(mapped(int)), this, SLOT(startChecker(int))); + + // main layout + QVBoxLayout *mainLayout = new QVBoxLayout; + mainLayout->addWidget(mCheckLabel); + mainLayout->addWidget(mDisplay); + mainLayout->addLayout(buttonLayout); + setWindowTitle(tr("Checking consistency")); + setLayout(mainLayout); +} + +void ConsistencyCheck::startChecker(int checkerType){ + mChecker = new ConsistencyChecker; + if(mChecker->status() == ConsistencyChecker::Fail){ + return; + } + switch(checkerType){ + case DbCheck: + mChecker->setMode(ConsistencyCheck::DbCheck); + break; + case FsCheck: + ; + break; + default: + ; + } + connect(mChecker, SIGNAL(consistencyMsg(QString)), this, SLOT(addMessage(QString))); + mChecker->check(); +} + +void ConsistencyCheck::addMessage(const QString &message){ + QTextCursor cursor(mDisplay->textCursor()); + QTextCharFormat fmt; + if(message.startsWith("OK")){ + fmt.setForeground(QBrush(Qt::green)); + }else{ + fmt.setForeground(QBrush(Qt::red)); + } + cursor.insertBlock(); + cursor.setCharFormat(fmt); + cursor.insertText(message); +} + +void ConsistencyCheck::cancelExit(){ + if(mChecker->isRunning()){ + mChecker->cancel(true); + mCancelExit->setText(tr("Close")); + connect(mCancelExit, SIGNAL(clicked()), this, SLOT(accept())); + }else{ + close(); + } +} + +ConsistencyChecker::ConsistencyChecker(QObject *parent) : QThread(parent), mCanceled(false), mMode(-1), mStatus(Ok){ + mDb = QSqlDatabase::cloneDatabase(QSqlDatabase::database("treedb"), "checkerDb"); + if(!mDb.open()){ + mStatus = Fail; + } +} + +void ConsistencyChecker::check(){ + if(!isRunning()){ + start(); + } +} + +void ConsistencyChecker::cancel(bool cancel){ + if(!cancel){ + return; + } + QMutexLocker locker(&mCancelMutex); + mCanceled = true; +} + +ConsistencyChecker::~ConsistencyChecker(){ + mDb.close(); +} + +void ConsistencyChecker::run(){ + switch(mMode){ + case ConsistencyCheck::DbCheck: + dbCheck(); + break; + default: + ; + } +} + +void ConsistencyChecker::dbCheck(){ + QSqlQuery fileDbQuery = QSqlQuery("SELECT tfilename, cmd5sum, idvd FROM files ORDER BY tfilename", mDb); + while(fileDbQuery.next()){ + QMutexLocker locker(&mCancelMutex); + if(mCanceled){ + return; + } + QString fileName = fileDbQuery.value(0).toString(); + QString md5sum = fileDbQuery.value(1).toString(); + int dvdNo = fileDbQuery.value(2).toInt(); + QString fullPath = archivePath(fileName, md5sum); + if(fullPath.isEmpty()){ + if(dvdNo != -1){ + emit consistencyMsg(QString(tr("OK: %1")).arg(fileName)); + }else{ + emit consistencyMsg(QString(tr("NOT FOUND: %1")).arg(fileName)); + } + }else{ + if(dvdNo == -1){ + emit consistencyMsg(QString(tr("OK: %1")).arg(fileName)); + }else{ + QString mimeType = Helper::mimeType(fullPath); + if(mimeType.startsWith("image")){ + emit consistencyMsg(QString(tr("OK: %1")).arg(fileName)); + }else{ + emit consistencyMsg(QString(tr("FOUND: %1")).arg(fileName)); + } + } + } + } +} + +QString ConsistencyChecker::archivePath(const QString &fileName, const QString &md5sum) const { + QString filePath = Helper::createArchivePath(fileName, md5sum); + QFileInfo fi(filePath); + if(!fi.exists()){ + filePath = Helper::createArchivePath(fileName, md5sum, true); + fi = QFileInfo(filePath); + if(!fi.exists()){ + filePath.clear(); + } + } + return filePath; +} diff --git a/consistencycheck.h b/consistencycheck.h new file mode 100644 index 0000000..15d0da7 --- /dev/null +++ b/consistencycheck.h @@ -0,0 +1,73 @@ +/* + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version + 2 of the License, or (at your option) any later version. +*/ + +#ifndef CONSISTENCYCHECK_H +#define CONSISTENCYCHECK_H + +#include +#include +#include +#include + +class QPushButton; +class QTextEdit; +class QLabel; +class QString; +class ConsistencyChecker; + +class ConsistencyCheck : public QDialog { + Q_OBJECT + public: + enum Mode { DbCheck, FsCheck }; + explicit ConsistencyCheck(QWidget *parent = 0, Qt::WindowFlags f = 0); + + private slots: + void startChecker(int checkerType); + void addMessage(const QString &message); + void cancelExit(); + + private: + QPushButton *mCancelExit; + QPushButton *mCheckDb; + QPushButton *mCheckFs; + QTextEdit *mDisplay; + QLabel *mCheckLabel; + ConsistencyChecker *mChecker; +}; + +class ConsistencyChecker : public QThread { + Q_OBJECT + public: + enum Status { Ok, Fail }; + explicit ConsistencyChecker(QObject *parent = 0); + ~ConsistencyChecker(); + int mode() const { return mMode; } + void setMode(int mode) { mMode = mode; } + int status() const { return mStatus; } + void setStatus(int status) { mStatus = status; } + void check(); + + public slots: + void cancel(bool cancel); + + signals: + void consistencyMsg(const QString &msg); + + protected: + void run(); + + private: + void dbCheck(); + QString archivePath(const QString &fileName, const QString &md5sum) const; + bool mCanceled; + int mMode; + int mStatus; + QSqlDatabase mDb; + QMutex mCancelMutex; +}; + +#endif // CONSISTENCYCHECK_H diff --git a/seriestreemodel.cpp b/seriestreemodel.cpp index b74fa13..ab3fe8c 100644 --- a/seriestreemodel.cpp +++ b/seriestreemodel.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include "seriestreemodel.h" #include "smtreeitem.h" diff --git a/seriestreemodel.h b/seriestreemodel.h index d7e7a12..63820ec 100644 --- a/seriestreemodel.h +++ b/seriestreemodel.h @@ -54,12 +54,14 @@ class SeriesTreeModel : public SmTreeModel { signals: void needResort(); + void consistencyMsg(const QString &msg); private: void populate(); bool mergeSeries(const QModelIndex &from, const QModelIndex &to); bool renameSeries(const QModelIndex &source, const QVariant &value); bool setNewSeries(const QModelIndex &source, const QVariant &value); + QString archivePath(const QString &fileName, const QString &md5sum) const; QSqlDatabase mDb; QSqlQuery *mSeriesPartsQuery; QSqlQuery *mUpdateSeriesIdQuery; diff --git a/shemov.cpp b/shemov.cpp index ac11916..da3986f 100644 --- a/shemov.cpp +++ b/shemov.cpp @@ -42,6 +42,7 @@ #include "newmoviewizard.h" #include "filestreewidget.h" #include "filestreemodel.h" +#include "consistencycheck.h" SheMov::SheMov(QWidget *parent, Qt::WindowFlags flags) : QMainWindow(parent, flags), mOpenWithGroupFS(0), mOpenWithGroupAV(0) { //application icon @@ -286,6 +287,8 @@ void SheMov::createActions(){ connect(cleanup2, SIGNAL(triggered()), mCleanupMapper, SLOT(map())); mCleanupMapper->setMapping(cleanup2, "genres"); mCleanupGroup->addAction(cleanup2); + mConsistencyA = new QAction(tr("Check consisteny..."), this); + connect(mConsistencyA, SIGNAL(triggered()), this, SLOT(checkConsistency())); mQuitA = new QAction(tr("Quit"), this); mQuitA->setShortcut(tr("CTRL+q")); @@ -422,6 +425,7 @@ void SheMov::createMenus(){ QMenu *cleanupMenu = new QMenu(tr("Clean database"), this); cleanupMenu->addActions(mCleanupGroup->actions()); fileMenu->addMenu(cleanupMenu); + fileMenu->addAction(mConsistencyA); fileMenu->addSeparator(); fileMenu->addAction(mQuitA); menuBar()->addMenu(fileMenu); @@ -627,3 +631,8 @@ void SheMov::readSettings(){ ; } } + +void SheMov::checkConsistency(){ + ConsistencyCheck c; + c.exec(); +} diff --git a/shemov.h b/shemov.h index 547fbd2..7504cfe 100644 --- a/shemov.h +++ b/shemov.h @@ -10,6 +10,7 @@ #include #include +#include class QTabWidget; class FilesystemWidget; @@ -43,6 +44,7 @@ class SheMov : public QMainWindow { void newMovieWizard(); void newMovieWizardWithFiles(); void setSize(qint64 size); + void checkConsistency(); signals: void configChanged(); @@ -87,6 +89,7 @@ class SheMov : public QMainWindow { QAction *mOpenWithMenuAVA; QAction *mRenameMenuA; QAction *mArchiveSelectedA; + QAction *mConsistencyA; //TreeView Actions //Series Actions @@ -137,6 +140,4 @@ class SheMov : public QMainWindow { ArchiveTreeView *mATree; NewMovieWizard *mNewMovieWizard; }; - #endif - diff --git a/shemov.pro b/shemov.pro index 2015955..6a3bdea 100644 --- a/shemov.pro +++ b/shemov.pro @@ -33,7 +33,8 @@ SOURCES = main.cpp \ mappingtablewidget.cpp \ newmoviewizard.cpp \ filepropertiesdialog.cpp \ - hoverwindow.cpp + hoverwindow.cpp \ + consistencycheck.cpp HEADERS = listitem.h \ filesystemdirproxy.h \ filesystemwidget.h \ @@ -61,6 +62,7 @@ HEADERS = listitem.h \ mappingtablewidget.h \ newmoviewizard.h \ filepropertiesdialog.h \ - hoverwindow.h + hoverwindow.h \ + consistencycheck.h LIBS += -lmagic -lXfixes RESOURCES = shemov.qrc -- cgit v1.2.3-70-g09d2