summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--filesystemwidget.cpp35
-rw-r--r--filesystemwidget.h9
-rw-r--r--fileview.cpp4
-rw-r--r--helper.cpp6
-rw-r--r--shemov.pro2
-rw-r--r--smdirmodel.cpp71
-rw-r--r--smdirmodel.h12
-rw-r--r--smdirwatcher.cpp255
-rw-r--r--smdirwatcher.h93
9 files changed, 256 insertions, 231 deletions
diff --git a/filesystemwidget.cpp b/filesystemwidget.cpp
index 24d9ec3..64f5ee8 100644
--- a/filesystemwidget.cpp
+++ b/filesystemwidget.cpp
@@ -43,10 +43,6 @@ FilesystemWidget::FilesystemWidget(QWidget *parent) : QWidget(parent), mClipboar
mFileModel = new SmDirModel(fHeaders, this);
connect(mFileModel, SIGNAL(needResize()), this, SLOT(resizeFileView()));
- mProgressDlg = 0;
- connect(mFileModel->collector(), SIGNAL(totalFiles(int)), this, SLOT(setupProgressDlg(int)));
- connect(mFileModel->collector(), SIGNAL(progress()), this, SLOT(progress()));
-
mDirProxy = new FilesystemDirProxy;
mDirProxy->setSourceModel(mModel);
mDirView = new SmTreeView;
@@ -171,7 +167,7 @@ void FilesystemWidget::fileViewActivated(const QModelIndex &idx){
/* we cannot use idx from the SIGNAL here, since the model
* may already have changed */
Q_UNUSED(idx);
- TimerHandler h(mFileModel->refresTimer());
+ TimerHandler h(mFileModel->refreshTimer());
QModelIndexList selected = mFileView->selectionModel()->selectedRows();
if(selected.isEmpty()){
return;
@@ -229,7 +225,7 @@ void FilesystemWidget::goBack(){
}
void FilesystemWidget::deleteFiles(){
- TimerHandler h(mFileModel->refresTimer());
+ TimerHandler h(mFileModel->refreshTimer());
QSortFilterProxyModel *proxy = qobject_cast<QSortFilterProxyModel*>(mFileView->model());
QModelIndexList selected = mFileView->selectionModel()->selectedRows();
if(selected.isEmpty()){
@@ -247,7 +243,7 @@ void FilesystemWidget::deleteFiles(){
}
void FilesystemWidget::toClipboard(int clipmode){
- TimerHandler h(mFileModel->refresTimer());
+ TimerHandler h(mFileModel->refreshTimer());
mClipboardMode = clipmode;
QClipboard *clip = qApp->clipboard();
QModelIndexList selected = mFileView->selectionModel()->selectedRows();
@@ -294,7 +290,7 @@ void FilesystemWidget::fromClipboard(){
}
void FilesystemWidget::renameFile(){
- TimerHandler h(mFileModel->refresTimer());
+ TimerHandler h(mFileModel->refreshTimer());
QModelIndex curIdx = mFileView->currentIndex();
if(curIdx.data().toString() == ".."){
return;
@@ -303,7 +299,7 @@ void FilesystemWidget::renameFile(){
}
void FilesystemWidget::playSelected(const QString &player){
- TimerHandler h(mFileModel->refresTimer());
+ TimerHandler h(mFileModel->refreshTimer());
QStringList files = selectedFiles();
if(files.isEmpty()){
statusbarMessage(tr("Nothing selected."));
@@ -436,27 +432,6 @@ void FilesystemWidget::setWindowTitle(){
emit windowTitle(mWindowTitle);
}
-void FilesystemWidget::setupProgressDlg(int max){
- if(max <= 0){
- return;
- }
- if(!mProgressDlg){
- mProgressDlg = new QProgressDialog(this);
- mProgressDlg->setLabel(new QLabel(tr("Gathering data... please wait!")));
- }
- mProgressDlg->setMinimum(1);
- mProgressDlg->setMaximum(max);
- Helper::centerWidget(mProgressDlg);
- mProgressDlg->show();
-}
-
-void FilesystemWidget::progress(){
- mProgressDlg->setValue(mProgressDlg->value() + 1);
- if(mProgressDlg->value() >= mProgressDlg->maximum()){
- mProgressDlg->hide();
- }
-}
-
void FilesystemWidget::deleteRecursive(const QFileInfo &start){
if(start.isDir()){
QDir curDir = QDir(start.absoluteFilePath());;
diff --git a/filesystemwidget.h b/filesystemwidget.h
index b9f082d..e3a2597 100644
--- a/filesystemwidget.h
+++ b/filesystemwidget.h
@@ -8,8 +8,8 @@
#ifndef FILESYSTEMWIDGET_H
#define FILESYSTEMWIDGET_H
-#include <QtWidgets/QWidget>
-#include <QtWidgets/QFileSystemModel>
+#include <QWidget>
+#include <QFileSystemModel>
#include <QSqlDatabase>
#include <QDateTime>
@@ -18,7 +18,6 @@ class FilesystemDirProxy;
class FileView;
class FilesystemFileProxy;
class QLineEdit;
-class QProgressDialog;
class PictureViewer2;
class FileSystemModel;
class SheMovIconProvider;
@@ -60,8 +59,6 @@ class FilesystemWidget : public QWidget {
void moveToArchive();
void selectAllPV();
void setWindowTitle();
- void setupProgressDlg(int max);
- void progress();
private slots:
void dirExpanded(const QModelIndex &idx);
@@ -70,7 +67,6 @@ class FilesystemWidget : public QWidget {
void resizeFileView();
private:
-
void deleteRecursive(const QFileInfo &start);
void copyFiles(const QStringList &files, const QString &dest);
void moveFiles(const QStringList &files, const QString &dest);
@@ -86,7 +82,6 @@ class FilesystemWidget : public QWidget {
FilesystemDirProxy *mDirProxy;
FilesystemFileProxy *mFileProxy;
QLineEdit *mDirEdit;
- QProgressDialog *mProgressDlg;
QString mWindowTitle;
QString mTemplate;
qint64 mSize;
diff --git a/fileview.cpp b/fileview.cpp
index 80a81bd..cc636ad 100644
--- a/fileview.cpp
+++ b/fileview.cpp
@@ -103,8 +103,6 @@ void FileView::readConfig(){
mWhen = s.value("ui/grabframe", "00:00:00").toString();
mHoverWin->setWindowOpacity(s.value("ui/hoveropacity", 10).toFloat() / 10.0);
mCursorOffset = s.value("ui/cursoroffset").toInt();
- bool checkPresent = s.value("database/checkpresent").toBool();
- mModel->setCheckForPresent(checkPresent);
readHeaderConfig();
}
@@ -117,7 +115,7 @@ void FileView::closeEditor(QWidget *editor, QAbstractItemDelegate::EndEditHint h
QSortFilterProxyModel *proxy = qobject_cast<QSortFilterProxyModel*>(model());
QModelIndex sourceIdx = proxy->mapToSource(currentIndex());
emit editorClosed(sourceIdx);
- mModel->refresTimer()->start();
+ mModel->refreshTimer()->start();
}
void FileView::contextMenuEvent(QContextMenuEvent *e){
diff --git a/helper.cpp b/helper.cpp
index cff490c..102e0f3 100644
--- a/helper.cpp
+++ b/helper.cpp
@@ -305,9 +305,9 @@ namespace Helper {
}
QVariant picSize(const QString &path){
- QPixmap pm(path);
- if(!pm.isNull()){
- QString retval = QString("%1x%2").arg(QString::number(pm.width())).arg(QString::number(pm.height()));
+ QImage img(path);
+ if(!img.isNull()){
+ QString retval = QString("%1x%2").arg(QString::number(img.width())).arg(QString::number(img.height()));
return retval;
}
return QVariant();
diff --git a/shemov.pro b/shemov.pro
index e909328..90ccd98 100644
--- a/shemov.pro
+++ b/shemov.pro
@@ -4,7 +4,7 @@ CONFIG += warn_on \
qt \
debug
CONFIG -= release
-QT += core gui widgets sql
+QT += core gui widgets sql concurrent
SOURCES = main.cpp \
filesystemdirproxy.cpp \
filesystemwidget.cpp \
diff --git a/smdirmodel.cpp b/smdirmodel.cpp
index 6a7ac39..6c84784 100644
--- a/smdirmodel.cpp
+++ b/smdirmodel.cpp
@@ -16,6 +16,7 @@
#include "helper.h"
SmDirModel::SmDirModel(const QStringList &headers, QObject *parent) : SmTreeModel(headers, parent), mHeaders(headers){
+ mDb = QSqlDatabase::database("treedb");
mWatch = new SmDirWatcher(NumFields, this);
connect(mWatch, SIGNAL(needRefresh()), this, SLOT(refresh()));
mRunTimer = new QTimer(this);
@@ -25,9 +26,12 @@ SmDirModel::SmDirModel(const QStringList &headers, QObject *parent) : SmTreeMode
mRefreshTimer = new QTimer(this);
readSettings();
- mCollector = mWatch->collector();
- connect(mCollector, SIGNAL(population(SmTreeItem*)), this, SLOT(populate(SmTreeItem*)));
- connect(mCollector, SIGNAL(newData(QList<QVariant>,int)), this, SLOT(dirEvent(QList<QVariant>,int)), Qt::BlockingQueuedConnection);
+ connect(this, SIGNAL(modelReset()), mWatch, SLOT(startAsyncJobs()));
+ connect(mWatch, SIGNAL(population(SmTreeItem*)), this, SLOT(populate(SmTreeItem*)));
+ connect(mWatch, SIGNAL(setMd5Sum(QString,QString)), this, SLOT(setMd5Sum(QString,QString)));
+ connect(mWatch, SIGNAL(setFfmpeg(QString,QVariantMap)), this, SLOT(setFfmpeg(QString,QVariantMap)));
+ connect(mWatch, SIGNAL(setPicSize(QString,QVariant)), this, SLOT(setPicSize(QString,QVariant)));
+ connect(mWatch, SIGNAL(newData(QList<QVariant>,int)), this, SLOT(dirEvent(QList<QVariant>,int)));
}
SmDirModel::~SmDirModel(){
@@ -127,7 +131,6 @@ QFileInfo SmDirModel::fileInfo(const QModelIndex &idx) const {
void SmDirModel::setDir(const QString &dir){
mCurrentDir = dir;
- mCollector->start();
mWatch->setDir(mCurrentDir);
}
@@ -135,9 +138,11 @@ void SmDirModel::dirEvent(const QList<QVariant> &data, int e){
if(e == SmDirWatcher::Added){
/* for some reason SmTreeModel::addRow() doesn't work,
* couldn't figure it out in 5 hours, so customize it
- * and reset the model
- */
+ * and reset the model... gatherAsync is done by
+ * modelReset();
+ */
addFile(data);
+ return;
}
QModelIndex idx = find(data.at(Name), Name, rootIndex());
if(!idx.isValid()){
@@ -146,10 +151,13 @@ void SmDirModel::dirEvent(const QList<QVariant> &data, int e){
if(e == SmDirWatcher::Deleted){
removeRow(idx.row());
}
- if(e == SmDirWatcher::Modified){
+ if(e == SmDirWatcher::Modified || e == SmDirWatcher::CloseWrite){
for(int i = 0; i < mHeaders.count(); ++i){
QModelIndex c = index(idx.row(), i, QModelIndex());
setData(c, data.at(i), Qt::EditRole);
+ if(e == SmDirWatcher::CloseWrite){
+ mWatch->gatherAsync(data.at(FullPath).toString());
+ }
}
}
emit needResize();
@@ -175,8 +183,53 @@ void SmDirModel::refresh(){
setDir(mCurrentDir);
}
-void SmDirModel::setCheckForPresent(bool check){
- mCollector->setCheckForPresent(check);
+void SmDirModel::setMd5Sum(QString path, QString md5){
+ QModelIndex idx = find(path, FullPath);
+ if(idx.isValid()){
+ QModelIndex md5Idx = createIndex(idx.column(), Md5sum, idx.internalPointer());
+ setData(md5Idx, md5, Qt::EditRole);
+ QString mimeType = idx.data(TypeRole).toString();
+ int present = 0;
+ QSqlQuery presentQ(mDb);
+ if(mimeType.startsWith("video")){
+ presentQ.prepare("SELECT COUNT(*) FROM files WHERE cmd5sum = :md5");
+ }else if(mimeType.startsWith("image")){
+ presentQ.prepare("SELECT COUNT(*) FROM pics WHERE cmd5sum = :md5");
+ }else{
+ goto out;
+ }
+ presentQ.bindValue(":md5", md5);
+ presentQ.exec();
+ while(presentQ.next()){
+ present = presentQ.value(0).toInt();
+ }
+ if(present){
+ QModelIndex presentIdx = createIndex(idx.column(), Present, idx.internalPointer());
+ setData(presentIdx, present, Qt::EditRole);
+ }
+ }
+ out:
+ emit needResize();
+}
+
+void SmDirModel::setFfmpeg(QString path, QVariantMap data){
+ QModelIndex idx = find(path, FullPath);
+ if(idx.isValid()){
+ QModelIndex durIdx = createIndex(idx.column(), DurSize, idx.internalPointer());
+ setData(durIdx, data["duration"].toDouble(), Qt::EditRole);
+ QModelIndex bitrateIdx = createIndex(idx.column(), Bitrate, idx.internalPointer());
+ setData(bitrateIdx, data["bit_rate"], Qt::EditRole);
+ }
+ emit needResize();
+}
+
+void SmDirModel::setPicSize(QString path, QVariant data){
+ QModelIndex idx = find(path, FullPath);
+ if(idx.isValid()){
+ QModelIndex psIdx = createIndex(idx.column(), DurSize, idx.internalPointer());
+ setData(psIdx, data, Qt::EditRole);
+ }
+ emit needResize();
}
void SmDirModel::populate(SmTreeItem *root){
diff --git a/smdirmodel.h b/smdirmodel.h
index 02ad608..26f34cf 100644
--- a/smdirmodel.h
+++ b/smdirmodel.h
@@ -9,6 +9,7 @@
#define SMDIRMODEL_H
#include <QDir>
+#include <QSqlDatabase>
#include <smtreemodel.h>
#include <smdirwatcher.h>
@@ -31,17 +32,18 @@ class SmDirModel : public SmTreeModel {
virtual QVariant data(const QModelIndex &index, int role) const;
virtual bool setData(const QModelIndex &index, const QVariant &value, int role);
bool isDir(const QModelIndex &idx) const;
- SmDataColletor *collector() const { return mCollector; }
QDir dir() const;
QFileInfo fileInfo(const QModelIndex &idx) const;
- QTimer *refresTimer() { return mRefreshTimer; }
+ QTimer *refreshTimer() { return mRefreshTimer; }
public slots:
void setDir(const QString &dir);
void dirEvent(const QList<QVariant> &data, int e);
void readSettings();
void refresh();
- void setCheckForPresent(bool check);
+ void setMd5Sum(QString path, QString md5);
+ void setFfmpeg(QString path, QVariantMap data);
+ void setPicSize(QString path, QVariant data);
private slots:
void populate(SmTreeItem *root);
@@ -56,12 +58,10 @@ class SmDirModel : public SmTreeModel {
SmDirWatcher *mWatch;
QStringList mHeaders;
QString mCurrentDir;
- QString mCur;
QTimer *mRunTimer;
QTimer *mRefreshTimer;
QMap<QString, QIcon> mIcons;
- QMutex *mCollectorMx;
- SmDataColletor *mCollector;
+ QSqlDatabase mDb;
};
class TimerHandler {
diff --git a/smdirwatcher.cpp b/smdirwatcher.cpp
index 2b03179..d825c2c 100644
--- a/smdirwatcher.cpp
+++ b/smdirwatcher.cpp
@@ -5,56 +5,105 @@
2 of the License, or (at your option) any later version.
*/
-#include <QVarLengthArray>
-#include <QMutexLocker>
#include <QDateTime>
#include <QDir>
-#include <QSemaphore>
#include <QImage>
#include <sys/inotify.h>
-#include <stropts.h>
-#include <sys/ioctl.h>
#include <unistd.h>
-#include <errno.h>
+#include "smdirmodel.h"
#include "smdirwatcher.h"
#include "smtreeitem.h"
#include "helper.h"
-extern int errno;
-
-SmDirWatcher::SmDirWatcher(int numFields, QObject *parent) : QThread(parent), mFd(0), mDescr(0) {
+SmDirWatcher::SmDirWatcher(int numFields, QObject *parent) : QThread(parent), mFd(0), mDescr(0), mNumFields(numFields) {
mBufLen = 1024 * (sizeof(struct inotify_event) + 16);
mINdata = new char[mBufLen];
mFd = inotify_init();
-
- mCollector = new SmDataColletor(numFields, this);
- mSemFree = new QSemaphore(1024);
- mSemUsed = new QSemaphore;
- mQueueMx = new QMutex;
- mDataQueue = new QQueue<QPair<QString, DWEvent> >();
- mCollector->init(mSemFree, mSemUsed, mDataQueue, mQueueMx);
- mCollector->start();
+ mAsyncPool = new QThreadPool(this);
}
void SmDirWatcher::setDir(const QString &dir){
if(mDescr){
inotify_rm_watch(mFd, mDescr); //generates IN_IGNORE ???
}
+ foreach(AsyncTask *s, mAsyncTasks){
+ s->skipMe();
+ }
+ mAsyncPool->waitForDone();
+ foreach(AsyncTask *s, mAsyncTasks){
+ s->deleteLater();
+ }
+ mAsyncTasks.clear();
+ mCurrent = dir;
+ QDir d(mCurrent);
+ SmTreeItem *rootItem = new SmTreeItem(mNumFields);
+ foreach(QFileInfo fi, d.entryInfoList()){
+ if(fi.fileName() == "." || fi.fileName() == ".."){
+ continue;
+ }
+ QList<QVariant> data = generalData(fi.absoluteFilePath());
+ QString mime = data.at(SmDirModel::Type).toString();
+ SmTreeItem *newItem = new SmTreeItem(data, rootItem);
+ rootItem->appendChild(newItem);
+ Md5Summer *s = new Md5Summer(fi.absoluteFilePath());
+ s->setAutoDelete(false);
+ connect(s, SIGNAL(md5sumDone(QString,QString)), this, SIGNAL(setMd5Sum(QString,QString)));
+ mAsyncTasks.append(s);
+ if(mime.startsWith("video")){
+ FfmpegGatherer *g = new FfmpegGatherer(fi.absoluteFilePath());
+ g->setAutoDelete(false);
+ connect(g, SIGNAL(ffmpegDone(QString,QVariantMap)), this, SIGNAL(setFfmpeg(QString,QVariantMap)));
+ mAsyncTasks.append(g);
+ }else if(mime.startsWith("image")){
+ PicSizeGatherer *pg = new PicSizeGatherer(fi.absoluteFilePath());
+ pg->setAutoDelete(false);
+ connect(pg, SIGNAL(picSizeDone(QString,QVariant)), this, SIGNAL(setPicSize(QString,QVariant)));
+ mAsyncTasks.append(pg);
+ }
+ }
+ emit population(rootItem);
/* mask rationale:
* IN_DELETE_SELF cannot happen since we're only
* watching one directory at all time.
* We don't care about the other events
*/
mDescr = inotify_add_watch(mFd, qPrintable(dir), IN_CLOSE_WRITE | IN_CREATE | IN_DELETE | IN_MODIFY | IN_MOVED_FROM | IN_MOVED_TO);
- mCurrent = dir;
- mSemFree->acquire();
- QPair<QString, DWEvent> c = qMakePair(dir, Populate);
- mQueueMx->lock();
- mDataQueue->enqueue(c);
- mQueueMx->unlock();
- mSemUsed->release();
+}
+
+void SmDirWatcher::startAsyncJobs(){
+ foreach(AsyncTask *s, mAsyncTasks){
+ mAsyncPool->start(s);
+ }
+}
+
+void SmDirWatcher::gatherAsync(const QString &path){
+ QString mimeType = Helper::mimeType(path);
+ Md5Summer *s = new Md5Summer(path);
+ connect(s, SIGNAL(md5sumDone(QString,QString)), this, SIGNAL(setMd5Sum(QString,QString)));
+ mAsyncPool->start(s);
+ if(mimeType.startsWith("video")){
+ FfmpegGatherer *g = new FfmpegGatherer(path);
+ connect(g, SIGNAL(ffmpegDone(QString,QVariantMap)), this, SIGNAL(setFfmpeg(QString,QVariantMap)));
+ mAsyncPool->start(g);
+ }else if(mimeType.startsWith("image")){
+ PicSizeGatherer *ps = new PicSizeGatherer(path);
+ connect(ps, SIGNAL(picSizeDone(QString,QVariant)), this, SIGNAL(setPicSize(QString,QVariant)));
+ mAsyncPool->start(ps);
+ }
+}
+
+QList<QVariant> SmDirWatcher::generalData(const QString &path){
+ QFileInfo fi(path);
+ QList<QVariant> data;
+ data << fi.fileName() << fi.size();
+ QString mime = Helper::mimeType(fi.absoluteFilePath());
+ data << mime;
+ data << fi.lastModified();
+ data << QVariant() << QVariant() << QVariant();
+ data << fi.absoluteFilePath() << 0;
+ return data;
}
void SmDirWatcher::run(){
@@ -69,142 +118,74 @@ void SmDirWatcher::run(){
i += sizeof(inotify_event) + e->len;
continue;
}
- mSemFree->acquire();
quint32 mask = e->mask;
QString name = QString("%1/%2").arg(mCurrent).arg(e->name);
- DWEvent curEvent = None;
- QPair<QString, DWEvent> c;
+ QList<QVariant> d = generalData(name);
if(mask & IN_CREATE || mask & IN_MOVED_TO){
- curEvent = Added;
+ emit newData(d, Added);
}else if(mask & IN_DELETE || mask & IN_MOVED_FROM){
- curEvent = Deleted;
- }else if(mask & IN_CLOSE_WRITE || e->mask & IN_MODIFY){
- curEvent = Modified;
- }else{
- goto out;
+ emit newData(d, Deleted);
+ }else if(mask & IN_MODIFY){
+ emit newData(d, Modified);
+ }else if(mask & IN_CLOSE_WRITE){
+ emit newData(d, CloseWrite);
}
- c = qMakePair(name, curEvent);
- mQueueMx->lock();
- mDataQueue->enqueue(c);
- mQueueMx->unlock();
- out:
- mSemUsed->release();
i += sizeof(inotify_event) + e->len;
}
}
void SmDirWatcher::stop(){
- mSemFree->acquire();
- mCollector->stop();
- mSemUsed->release();
- if(mCollector->isRunning()){
- mCollector->wait();
- }
quit();
}
-SmDataColletor::SmDataColletor(const int numFields, QObject *parent) : QThread(parent), mSemFree(0), mSemUsed(0), mDataQueue(0), mNumFields(numFields), mCheckForPresent(true), mCancel(false) {
- QSqlDatabase db = QSqlDatabase::cloneDatabase(QSqlDatabase::database("treedb"), "collectordb");
- db.open();
- mPicPresentQ = new QSqlQuery(db);
- mPicPresentQ->prepare("SELECT COUNT(cmd5sum) FROM pics WHERE cmd5sum = :md5");
- mMovPresentQ = new QSqlQuery(db);
- mMovPresentQ->prepare("SELECT COUNT(cmd5sum) FROM files WHERE cmd5sum = :md5");
-}
+AsyncTask::AsyncTask(const QString &path) : mSkip(false), mPath(path) {}
-void SmDataColletor::init(QSemaphore *set, QSemaphore *get, QQueue<QPair<QString, SmDirWatcher::DWEvent> > *data, QMutex *queueMx){
- mSemFree = set;
- mSemUsed = get;
- mDataQueue = data;
- mQueueMx = queueMx;
+bool AsyncTask::skipMe(){
+ if(mStatusMx.tryLock()){
+ mSkip = true;
+ mStatusMx.unlock();
+ return true;
+ }
+ return false;
}
-void SmDataColletor::setCheckForPresent(bool present){
- QMutexLocker l(&mCheckForPresentMx);
- mCheckForPresent = present;
-}
+#include <QDebug>
-void SmDataColletor::run(){
- forever {
- mSemUsed->acquire();
- if(mCancel){
- QSqlDatabase::database("collectordb").close();
- mSemFree->release();
- break;
- }
- mQueueMx->lock();
- QPair<QString, SmDirWatcher::DWEvent> cur = mDataQueue->dequeue();
- mQueueMx->unlock();
- if(cur.second == SmDirWatcher::Populate){
- SmTreeItem *i = populate(cur.first);
- SmTreeItem *copy = new SmTreeItem(*i);
- emit population(copy);
- mSemFree->release();
- continue;
+Md5Summer::Md5Summer(const QString &path) : AsyncTask(path) {}
- }
- QFileInfo fi(cur.first);
- QList<QVariant> fd = fileData(fi);
- emit newData(fd, cur.second);
- mSemFree->release();
+void Md5Summer::run(){
+ mStatusMx.lock();
+ bool skip = mSkip;
+ mStatusMx.unlock();
+ if(skip){
+ return;
}
- quit();
+ QString md5 = Helper::md5Sum(mPath);
+ emit md5sumDone(mPath, md5);
}
-SmTreeItem * SmDataColletor::populate(const QString &dir){
- SmTreeItem *retval = new SmTreeItem(mNumFields);
- QDir d = QDir(dir);
- emit totalFiles(d.entryInfoList().size());
- foreach(QFileInfo fi, d.entryInfoList()){
- emit progress();
- if(fi.fileName() == "."){
- continue;
- }
- QList<QVariant> data = fileData(fi);
- SmTreeItem *newItem = new SmTreeItem(data, retval);
- retval->appendChild(newItem);
+FfmpegGatherer::FfmpegGatherer(const QString &path) : AsyncTask(path) {}
+
+void FfmpegGatherer::run(){
+ mStatusMx.lock();
+ bool skip = mSkip;
+ mStatusMx.unlock();
+ if(skip){
+ return;
}
- return retval;
+ QVariantMap retval = Helper::ffmpegData(mPath);
+ emit ffmpegDone(mPath, retval);
}
-const QList<QVariant> SmDataColletor::fileData(const QFileInfo &fi){
- QList<QVariant> data;
- data << fi.fileName() << fi.size();
- QString mime = Helper::mimeType(fi.absoluteFilePath());
- data << mime;
- data << fi.lastModified();
- QList<QVariant> si = QList<QVariant>() << QVariant() << QVariant();
- if(mime.startsWith("video")){
- QVariantMap ffData = Helper::ffmpegData(fi.absoluteFilePath());
- si[0] = ffData.value("duration").toDouble();
- si[1] = ffData.value("bit_rate").toInt();
- }else if(mime.startsWith("image")){
- si[0] = Helper::picSize(fi.absoluteFilePath());
- }
- data << Helper::md5Sum(fi.absoluteFilePath());
- data << si << fi.absoluteFilePath();
- data << 0;
- mCheckForPresentMx.lock();
- bool p = mCheckForPresent;
- mCheckForPresentMx.unlock();
- if(p){
- QSqlQuery *curQuery = 0;
- if(mime.startsWith("video")){
- curQuery = mMovPresentQ;
- }
- if(mime.startsWith("image")){
- curQuery = mPicPresentQ;
- }
- if(curQuery){
- curQuery->bindValue(":md5", data.at(4));
- if(curQuery->exec()){
- QVariant res;
- while(curQuery->next()){
- res = curQuery->value(0);
- }
- data[8] = res;
- }
- }
+PicSizeGatherer::PicSizeGatherer(const QString &path) : AsyncTask(path) {}
+
+void PicSizeGatherer::run(){
+ mStatusMx.lock();
+ bool skip = mSkip;
+ mStatusMx.unlock();
+ if(skip){
+ return;
}
- return data;
+ QVariant retval = Helper::picSize(mPath);
+ emit picSizeDone(mPath, retval);
}
diff --git a/smdirwatcher.h b/smdirwatcher.h
index fccc1ed..9ec9181 100644
--- a/smdirwatcher.h
+++ b/smdirwatcher.h
@@ -1,4 +1,4 @@
- /*
+/*
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
@@ -16,73 +16,96 @@
#include <QMutex>
#include <QSqlDatabase>
#include <QSqlQuery>
+#include <QThreadPool>
+#include <QRunnable>
class SmTreeItem;
class QSemaphore;
class SmDataColletor;
+class AsyncTask;
+class Md5Summer;
class SmDirWatcher : public QThread {
Q_OBJECT
public:
- enum DWEvent { None, Added, Deleted, Modified, Populate };
+ enum DWEvent { None, Added, Deleted, Modified, Populate, CloseWrite };
explicit SmDirWatcher(int numFields, QObject *parent = 0);
- SmDataColletor *collector() { return mCollector; }
signals:
void dwEvent(const QString& file, int event);
+ void setMd5Sum(QString path, QString md5);
+ void setFfmpeg(QString path, QVariantMap data);
+ void setPicSize(QString path, QVariant size);
void needRefresh();
+ void population(SmTreeItem*);
+ void newData(const QList<QVariant>,int);
public slots:
void run();
void stop();
void setDir(const QString &dir);
+ void startAsyncJobs();
+ void gatherAsync(const QString &path);
private:
+ QList<QVariant> generalData(const QString &path);
int mFd;
int mDescr;
QString mCurrent;
- SmDataColletor *mCollector;
- QSemaphore *mSemFree;
- QSemaphore *mSemUsed;
- QQueue<QPair<QString, DWEvent> > *mDataQueue;
- QMutex *mQueueMx;
char *mINdata;
int mBufLen;
+ QThreadPool *mAsyncPool;
+ int mNumFields;
+ QList<AsyncTask*> mAsyncTasks;
};
-class SmDataColletor : public QThread {
+class AsyncTask : public QObject, public QRunnable {
Q_OBJECT
public:
- explicit SmDataColletor(const int numFields, QObject *parent = 0);
- void init(QSemaphore *set, QSemaphore *get, QQueue<QPair<QString, SmDirWatcher::DWEvent> > *data, QMutex *queueMx);
+ explicit AsyncTask(const QString &path = QString());
+ bool skipMe();
- public slots:
- void setCheckForPresent(bool present);
- void run();
- void stop() { mCancel = true; }
+ protected:
+ virtual void run() = 0;
+ bool mSkip;
+ QMutex mStatusMx;
+ const QString mPath;
+};
+
+class Md5Summer : public AsyncTask {
+ Q_OBJECT
+ public:
+ explicit Md5Summer(const QString &path);
signals:
- void newData(const QList<QVariant>,int);
- void population(SmTreeItem*);
- void needRefresh();
- void totalFiles(int numFiles);
- void progress();
+ void md5sumDone(QString, QString);
- private:
- SmTreeItem *populate(const QString &dir);
- const QList<QVariant> fileData(const QFileInfo &fi);
- QString mCurrent;
- QSemaphore *mSemFree;
- QSemaphore *mSemUsed;
- QMutex *mQueueMx;
- QQueue<QPair<QString, SmDirWatcher::DWEvent> > *mDataQueue;
- int mMode;
- const int mNumFields;
- bool mCheckForPresent;
- bool mCancel;
- QMutex mCheckForPresentMx;
- QSqlQuery *mPicPresentQ;
- QSqlQuery *mMovPresentQ;
+ protected:
+ virtual void run();
+};
+
+class FfmpegGatherer : public AsyncTask {
+ Q_OBJECT
+ public:
+ explicit FfmpegGatherer(const QString &path);
+
+ signals:
+ void ffmpegDone(QString, QVariantMap);
+
+ protected:
+ virtual void run();
+};
+
+class PicSizeGatherer : public AsyncTask {
+ Q_OBJECT
+ public:
+ explicit PicSizeGatherer(const QString &path);
+
+ signals:
+ void picSizeDone(QString, QVariant);
+
+ protected:
+ virtual void run();
};
#endif // SMDIRWATCHER_H