]> Some of my projects - localmylist.git/commitdiff
Add DirectoryWatcher
authorAPTX <marek321@gmail.com>
Tue, 19 Jun 2012 20:58:33 +0000 (22:58 +0200)
committerAPTX <marek321@gmail.com>
Tue, 19 Jun 2012 20:58:33 +0000 (22:58 +0200)
13 files changed:
localmylist/addfiletask.h
localmylist/database.cpp
localmylist/database.h
localmylist/directoryscantask.cpp
localmylist/directorywatcher.cpp [new file with mode: 0644]
localmylist/directorywatcher.h [new file with mode: 0644]
localmylist/localmylist.pro
localmylist/mylist.cpp
localmylist/mylist.h
localmylist/share/schema/schema.sql
management-gui/mainwindow.cpp
management-gui/mainwindow.h
management-gui/mainwindow.ui

index 95e8eb770039f09a6dc7e13035af2657b0545951..0af9ce446b997c7f8b79eb2c76c1a1662673b7c9 100644 (file)
@@ -39,11 +39,6 @@ public slots:
        
 private slots:
        void hashingFinished();
-
-       // File data is handled via requests
-       // not just any task
-//     void fileDataRecieved(bool success);
-
        
 private:
        QFileInfo m_file;
index 277af1d3938474fd38178544be5a83ea42912759..c6daa68c9ea354e176ae182c9c1e6191c0e00a6b 100644 (file)
@@ -685,7 +685,7 @@ UnknownFile Database::getUnknownFile(const QByteArray &ed2k, qint64 size)
        return f;
 }
 
-UnknownFile Database::getUnknownFilebyPath(const QString &path)
+UnknownFile Database::getUnknownFileByPath(const QString &path)
 {
        d->getUnknownFileByPathQuery.bindValue(":path", path);
 
@@ -859,6 +859,24 @@ bool Database::clearPendingMyListUpdate(const PendingMyListUpdate &request)
        return exec(d->clearPendingMyListUpdateQuery);
 }
 
+QStringList Database::getWatchedDirectories(int hostId)
+{
+       QSqlQuery q(d->db);
+       q.prepare("SELECT directory FROM watched_directory WHERE host_id = :hostId");
+       q.bindValue(":hostId", hostId);
+
+       if (!exec(q))
+               return QStringList();
+
+       QStringList ret;
+
+       while (q.next())
+       {
+               ret << q.value(0).toString();
+       }
+       return ret;
+}
+
 bool Database::clearStartedPendingRequests()
 {
        return exec(
@@ -1100,6 +1118,8 @@ void Database::prepareQueries()
 
        d->getUnknownFileQuery = QSqlQuery(d->db);
        d->getUnknownFileQuery.prepare("SELECT ed2k, size, host_id, path FROM unknown_file WHERE ed2k = :ed2k AND size = :size");
+
+       d->getUnknownFileByPathQuery = QSqlQuery(d->db);
        d->getUnknownFileByPathQuery.prepare("SELECT ed2k, size, host_id, path FROM unknown_file WHERE path = :path");
 
        d->removeUnknownFileQuery = QSqlQuery(d->db);
index c791b8f18565f1689411e09cb930b419c94144c0..f86c4f265106a81eb45029b197e87b39d69db198 100644 (file)
@@ -246,7 +246,7 @@ public:
 
        bool addUnknownFile(const UnknownFile &file);
        UnknownFile getUnknownFile(const QByteArray &ed2k, qint64 size);
-       UnknownFile getUnknownFilebyPath(const QString &path);
+       UnknownFile getUnknownFileByPath(const QString &path);
        bool removeUnknownFile(const QByteArray &ed2k, qint64 size);
 
        bool addRequest(const PendingRequest &request);
@@ -258,6 +258,8 @@ public:
        QList<PendingMyListUpdate> getPendingMyListUpdateBatch(int limit = 10);
        bool clearPendingMyListUpdate(const PendingMyListUpdate &request);
 
+       QStringList getWatchedDirectories(int hostId);
+
        bool clearStartedPendingRequests();
        bool clearStartedMyListUpdateRequests();
        bool clearFileRenames();
index 6f59515fe17b22fdcc656cf426670b6982d398fe..db05bedfaff53ed3c25363a71dbc34e8d5eaa201 100644 (file)
@@ -93,7 +93,7 @@ void DirectoryScanTask::workUnit()
                                        if (f.fid)
                                                continue;
 
-                                       UnknownFile uf = db->getUnknownFilebyPath(entry.canonicalFilePath());
+                                       UnknownFile uf = db->getUnknownFileByPath(entry.canonicalFilePath());
                                        if (!uf.ed2k.isEmpty() && uf.size)
                                                continue;
                                }
diff --git a/localmylist/directorywatcher.cpp b/localmylist/directorywatcher.cpp
new file mode 100644 (file)
index 0000000..3216cd8
--- /dev/null
@@ -0,0 +1,90 @@
+#include "directorywatcher.h"
+
+#include "mylist.h"
+#include "database.h"
+#include "settings.h"
+
+#include <QFileSystemWatcher>
+#include <QDir>
+#include <QFileInfo>
+#include <QMetaObject>
+
+#include <QDebug>
+
+namespace LocalMyList {
+
+DirectoryWatcher::DirectoryWatcher(Database *db, Settings *settings, QObject *parent) :
+       QObject(parent)
+{
+       this->db = db;
+       this->settings = settings;
+
+       watcher = new QFileSystemWatcher();
+       connect(watcher, SIGNAL(directoryChanged(QString)), this, SLOT(watchedDirectoryChanged(QString)), Qt::QueuedConnection);
+
+       setWatchedDirectories();
+}
+
+DirectoryWatcher::~DirectoryWatcher()
+{
+       delete watcher;
+}
+
+void DirectoryWatcher::setWatchedDirectories()
+{
+       QStringList currentEntries = watcher->directories();
+       if (!currentEntries.isEmpty())
+               watcher->removePaths(currentEntries);
+
+       currentEntries = watcher->files();
+       if (!currentEntries.isEmpty())
+               watcher->removePaths(currentEntries);
+
+       QStringList watchedDirectories = db->getWatchedDirectories(MyList::instance()->hostId());
+       watcher->addPaths(watchedDirectories);
+
+       qDebug() << "Watching" << watchedDirectories;
+}
+
+void DirectoryWatcher::watchedDirectoryChanged(const QString &path)
+{
+       qDebug() << path << "changed!";
+
+       QDir dir(path);
+
+       QStringList currentEntries = dir.entryList(QDir::Files);
+       QSet<QString> currentSet = currentEntries.toSet();
+       QSet<QString> oldEntries = previousEntries.value(path);
+       QSet<QString> newEntries = currentSet - oldEntries;
+
+       qDebug() << newEntries;
+
+       foreach (const QString &entry, newEntries)
+       {
+               QFileInfo fileInfo(path + "/" + entry);
+
+               if (!fileInfo.exists())
+                       continue;
+
+               if (!fileInfo.isFile())
+                       continue;
+
+               qDebug() << "Potential file to add" << fileInfo.canonicalFilePath();
+
+               UnknownFile uf = db->getUnknownFileByPath(fileInfo.canonicalFilePath());
+               if (!uf.ed2k.isEmpty() && uf.size)
+                       continue;
+
+               File f = db->getFileByPath(fileInfo.canonicalFilePath());
+               if (f.fid)
+                       continue;
+
+               qDebug() << "New file to add" << fileInfo.canonicalFilePath();
+               QMetaObject::invokeMethod(MyList::instance(), "addFile", Qt::QueuedConnection, Q_ARG(QFileInfo, fileInfo));
+
+       }
+
+       previousEntries.insert(path, currentSet);
+}
+
+} // namespace LocalMyList
diff --git a/localmylist/directorywatcher.h b/localmylist/directorywatcher.h
new file mode 100644 (file)
index 0000000..0f96bec
--- /dev/null
@@ -0,0 +1,40 @@
+#ifndef DIRECTORYWATCHER_H
+#define DIRECTORYWATCHER_H
+
+#include "localmylist_global.h"
+#include <QObject>
+#include <QMap>
+#include <QSet>
+
+class QFileSystemWatcher;
+
+namespace LocalMyList {
+
+class Database;
+class Settings;
+
+class LOCALMYLISTSHARED_EXPORT DirectoryWatcher : public QObject
+{
+       Q_OBJECT
+public:
+       explicit DirectoryWatcher(Database *db, Settings *settings, QObject *parent = 0);
+       ~DirectoryWatcher();
+
+signals:
+       
+public slots:
+       void setWatchedDirectories();
+
+       void watchedDirectoryChanged(const QString &path);
+
+private:
+       Database *db;
+       Settings *settings;
+
+       QFileSystemWatcher *watcher;
+       QMap<QString, QSet<QString> > previousEntries;
+};
+
+} // namespace LocalMyList
+
+#endif // DIRECTORYWATCHER_H
index 998b4c48c46f56b1b14b04bc8ab89c9c8bc13a57..c41ab2e164b4793032842811c52a58968259c648 100644 (file)
@@ -24,7 +24,8 @@ SOURCES += \
        settings.cpp \
        renamehandler.cpp \
        unknownfilelookuptask.cpp \
-       renameutils.cpp
+       renameutils.cpp \
+       directorywatcher.cpp
 
 HEADERS += \
        localmylist_global.h \
@@ -42,7 +43,8 @@ HEADERS += \
        settings.h \
        renamehandler.h \
        unknownfilelookuptask.h \
-       renameutils.h
+       renameutils.h \
+       directorywatcher.h
 
 CONV_HEADERS += \
        include/LocalMyList/AbstractTask \
index 9cf532e8a9af81dbfcbdfc4d7a62b25ef5dcc7e1..1c0c871cda14ff718dc881eed79eb6bc7d6fd6ff 100644 (file)
@@ -12,6 +12,7 @@
 #include "workthread.h"
 #include "requesthandler.h"
 #include "renamehandler.h"
+#include "directorywatcher.h"
 #include <AniDBUdpClient/Client>
 
 namespace LocalMyList {
@@ -22,6 +23,7 @@ MyList::MyList()
 
        m_requestHandler = 0;
        m_renameHandler = 0;
+       m_directoryWatcher = 0;
        workThread = 0;
 
        db = new Database("main");
@@ -105,7 +107,7 @@ void MyList::setupUdpClient()
 
 void MyList::setupRequestHandler()
 {
-       if (m_requestHandler)
+       if (m_requestHandler || !db->isConnected())
                return;
 
        m_requestHandler = new RequestHandler(db, this);
@@ -124,6 +126,14 @@ void MyList::setupRenameHandler()
        m_renameHandler->moveToThread(workThread);
 }
 
+void MyList::setupDirectoryWatcher()
+{
+       if (m_directoryWatcher || !db->isConnected())
+               return;
+
+       m_directoryWatcher = new DirectoryWatcher(db, m_settings);
+}
+
 void MyList::setupWorkThread()
 {
        if (workThread)
@@ -143,6 +153,8 @@ void MyList::setupHostInfo()
                qWarning("Unknown host!");
        }
        qDebug() << "host id" << hostId();
+
+       setupDirectoryWatcher();
 }
 
 void MyList::loadLocalSettings(QSettings &s)
index 6f687df3515dab5035b5be673abcde52ff3781cf..58a813f3850e6495df537b9d5ff263f447c42c49 100644 (file)
@@ -18,6 +18,7 @@ class AbstractTask;
 class WorkThread;
 class RequestHandler;
 class RenameHandler;
+class DirectoryWatcher;
 
 class LOCALMYLISTSHARED_EXPORT MyList : public QObject {
        Q_OBJECT
@@ -51,6 +52,7 @@ public slots:
        void setupUdpClient();
        void setupRequestHandler();
        void setupRenameHandler();
+       void setupDirectoryWatcher();
        void setupWorkThread();
        void setupHostInfo();
 
@@ -72,6 +74,7 @@ private:
        WorkThread *workThread;
        RequestHandler *m_requestHandler;
        RenameHandler *m_renameHandler;
+       DirectoryWatcher *m_directoryWatcher;
        Settings *m_settings;
 
        HostInfo hostInfo;
index 9ebf364cf2b6eac3bb27210119aa05cf8c91190d..e3259469af6e25d2ec1dcf41cec55c0e8e33108a 100644 (file)
@@ -179,6 +179,13 @@ CREATE TABLE host (
        CONSTRAINT host_unique_name UNIQUE (name)
 );
 
+CREATE TABLE watched_directory
+(
+       host_id integer NOT NULL,
+       directory text NOT NULL,
+       CONSTRAINT watched_directory_pk PRIMARY KEY (host_id, directory)
+);
+
 CREATE TABLE log (
        log_id serial NOT NULL,
        type integer,
index a82b1014e3c99bd7d1800c2d03ed5ed3d49cf941..83ea3f8104f47878de6d41b278a45092fcff2ab6 100644 (file)
@@ -286,3 +286,8 @@ void MainWindow::on_actionRenameScript_triggered()
 {
        openRenameScriptEditor(0);
 }
+
+void MainWindow::on_actionStartDirectoryWatcher_triggered()
+{
+       MyList::instance()->setupDirectoryWatcher();
+}
index 602a827ddb2476da7d1b099f03ddac88be65e069..b83b375c7d8852f11d1fcc7b7a7ce2b07aab070f 100644 (file)
@@ -57,6 +57,7 @@ private slots:
        void on_actionRemoveKnownUnknownFiles_triggered();
        void on_refreshButton_clicked();
        void on_actionRenameScript_triggered();
+       void on_actionStartDirectoryWatcher_triggered();
 
 private:
        Ui::MainWindow *ui;
index ee3e12399d6334d15c7fd09cb62e2b78a30a5ebf..ed4d657c05ea765b3be97541d51e319842f237f5 100644 (file)
@@ -60,6 +60,7 @@
     <addaction name="actionConnect"/>
     <addaction name="actionDisconnect"/>
     <addaction name="separator"/>
+    <addaction name="actionStartDirectoryWatcher"/>
     <addaction name="actionStartRenameHandler"/>
     <addaction name="actionStartUDPCLient"/>
     <addaction name="separator"/>
     <string>Rename Script...</string>
    </property>
   </action>
+  <action name="actionStartDirectoryWatcher">
+   <property name="text">
+    <string>Start Directory Watcher</string>
+   </property>
+  </action>
  </widget>
  <layoutdefault spacing="6" margin="11"/>
  <customwidgets>