blob: 86c0f800ce38de92fd62a66498e4256f0f802374 [file] [log] [blame]
Alexander Afanasyev9e5a4702013-01-24 13:15:23 -08001/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
2/*
3 * Copyright (c) 2012-2013 University of California, Los Angeles
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Author: Jared Lindblom <lindblom@cs.ucla.edu>
19 * Alexander Afanasyev <alexander.afanasyev@ucla.edu>
20 * Zhenkai Zhu <zhenkai@cs.ucla.edu>
21 */
22
23#include "fs-watcher.h"
24#include "logging.h"
25
26#include <boost/bind.hpp>
27
28#include <QDirIterator>
29#include <QRegExp>
30
31using namespace std;
32using namespace boost;
33
34INIT_LOGGER ("FsWatcher");
35
36FsWatcher::FsWatcher (QString dirPath, QObject* parent)
37 : QObject(parent)
38 , m_watcher (new QFileSystemWatcher())
39 , m_executor (1)
40 , m_dirPath (dirPath)
41{
42 _LOG_DEBUG ("Monitor dir: " << m_dirPath.toStdString ());
43 // add main directory to monitor
44 m_watcher->addPath (m_dirPath);
45
46 // register signals (callback functions)
47 connect (m_watcher, SIGNAL (directoryChanged (QString)), this, SLOT (DidDirectoryChanged (QString)));
48 connect (m_watcher, SIGNAL (fileChanged (QString)), this, SLOT (DidFileChanged (QString)));
49
50 m_executor.execute (bind (&FsWatcher::ScanDirectory_Notify_Execute, this, m_dirPath));
Alexander Afanasyev5e140872013-01-24 23:58:10 -080051 m_executor.start ();
Alexander Afanasyev9e5a4702013-01-24 13:15:23 -080052}
53
54FsWatcher::~FsWatcher()
55{
Alexander Afanasyev5e140872013-01-24 23:58:10 -080056 m_executor.shutdown ();
Alexander Afanasyev9e5a4702013-01-24 13:15:23 -080057 delete m_watcher;
58}
59
60void
61FsWatcher::DidDirectoryChanged (QString dirPath)
62{
63 _LOG_DEBUG ("Triggered DirPath: " << dirPath.toStdString ());
64
65 m_executor.execute (bind (&FsWatcher::ScanDirectory_Notify_Execute, this, dirPath));
66}
67
68void
69FsWatcher::DidFileChanged (QString filePath)
70{
71 _LOG_DEBUG ("Triggered FilePath: " << filePath.toStdString ());
72}
73
74
75void FsWatcher::DidDirectoryChanged_Execute (QString dirPath)
76{
77// // scan directory and populate file list
78// QHash<QString, qint64> currentState = scanDirectory(dirPath);
79
80// // reconcile directory and report changes
81// std::vector<sEventInfo> dirChanges = reconcileDirectory(currentState, dirPath);
82// #ifdef _DEBUG
83// // DEBUG: Print Changes
84// printChanges(dirChanges);
85// #endif
86// // emit the signal if not empty
87// if(!dirChanges.empty())
88// emit dirEventSignal(dirChanges);
89}
90
91void
92FsWatcher::ScanDirectory_Notify_Execute (QString dirPath)
93{
94 QRegExp exclude ("^(\\.|\\.\\.|\\.chronoshare)$");
95
96 QDirIterator dirIterator (dirPath,
97 QDir::Dirs | QDir::Files | QDir::Hidden | QDir::NoSymLinks | QDir::NoDotAndDotDot,
98 QDirIterator::Subdirectories); // directory iterator (recursive)
99
100 // iterate through directory recursively
101 while (dirIterator.hasNext ())
102 {
103 dirIterator.next ();
104
105 // Get FileInfo
106 QFileInfo fileInfo = dirIterator.fileInfo ();
107
108 QString name = fileInfo.fileName ();
109
110 if (!exclude.exactMatch (name))
111 {
112 // _LOG_DEBUG ("Not excluded file/dir: " << fileInfo.absoluteFilePath ().toStdString ());
113 QString absFilePath = fileInfo.absoluteFilePath ();
114
115 // _LOG_DEBUG ("Attempt to add path to watcher: " << absFilePath.toStdString ());
116 m_watcher->addPath (absFilePath);
117
118 if (fileInfo.isFile ())
119 {
120 DidFileChanged (absFilePath);
121 }
122 // // if this is a directory
123 // if(fileInfo.isDir())
124 // {
125 // QStringList dirList = m_watcher->directories();
126
127 // // if the directory is not already being watched
128 // if (absFilePath.startsWith(m_dirPath) && !dirList.contains(absFilePath))
129 // {
130 // _LOG_DEBUG ("Add new dir to watchlist: " << absFilePath.toStdString ());
131 // // add this directory to the watch list
132 // m_watcher->addPath(absFilePath);
133 // }
134 // }
135 // else
136 // {
137 // _LOG_DEBUG ("Found file: " << absFilePath.toStdString ());
138 // // add this file to the file list
139 // // currentState.insert(absFilePath, fileInfo.created().toMSecsSinceEpoch());
140 // }
141 }
142 else
143 {
144 // _LOG_DEBUG ("Excluded file/dir: " << fileInfo.filePath ().toStdString ());
145 }
146 }
147}
148
149// std::vector<sEventInfo> FsWatcher::reconcileDirectory(QHash<QString, qint64> currentState, QString dirPath)
150// {
151// // list of files changed
152// std::vector<sEventInfo> dirChanges;
153
154// // compare result (database/stored snapshot) to fileList (current snapshot)
155// QMutableHashIterator<QString, qint64> i(m_storedState);
156
157// while(i.hasNext())
158// {
159// i.next();
160
161// QString absFilePath = i.key();
162// qint64 storedCreated = i.value();
163
164// // if this file is in a level higher than
165// // this directory, ignore
166// if(!absFilePath.startsWith(dirPath))
167// {
168// continue;
169// }
170
171// // check file existence
172// if(currentState.contains(absFilePath))
173// {
174// qint64 currentCreated = currentState.value(absFilePath);
175
176// if(storedCreated != currentCreated)
177// {
178// // update stored state
179// i.setValue(currentCreated);
180
181// // this file has been modified
182// sEventInfo eventInfo;
183// eventInfo.event = MODIFIED;
184// eventInfo.absFilePath = absFilePath.toStdString();
185// dirChanges.push_back(eventInfo);
186// }
187
188// // delete this file from fileList we have processed it
189// currentState.remove(absFilePath);
190// }
191// else
192// {
193// // delete from stored state
194// i.remove();
195
196// // this file has been deleted
197// sEventInfo eventInfo;
198// eventInfo.event = DELETED;
199// eventInfo.absFilePath = absFilePath.toStdString();
200// dirChanges.push_back(eventInfo);
201// }
202// }
203
204// // any files left in fileList have been added
205// for(QHash<QString, qint64>::iterator i = currentState.begin(); i != currentState.end(); ++i)
206// {
207// QString absFilePath = i.key();
208// qint64 currentCreated = i.value();
209
210// m_storedState.insert(absFilePath, currentCreated);
211
212// // this file has been added
213// sEventInfo eventInfo;
214// eventInfo.event = ADDED;
215// eventInfo.absFilePath = absFilePath.toStdString();
216// dirChanges.push_back(eventInfo);
217// }
218
219// return dirChanges;
220// }
221
222// QByteArray FsWatcher::calcChecksum(QString absFilePath)
223// {
224// // initialize checksum
225// QCryptographicHash crypto(QCryptographicHash::Md5);
226
227// // open file
228// QFile file(absFilePath);
229// file.open(QFile::ReadOnly);
230
231// // calculate checksum
232// while(!file.atEnd())
233// {
234// crypto.addData(file.read(8192));
235// }
236
237// return crypto.result();
238// }
239
240// void FsWatcher::printChanges(std::vector<sEventInfo> dirChanges)
241// {
242// if(!dirChanges.empty())
243// {
244// for(size_t i = 0; i < dirChanges.size(); i++)
245// {
246// QString tempString;
247
248// eEvent event = dirChanges[i].event;
249// QString absFilePath = QString::fromStdString(dirChanges[i].absFilePath);
250
251// switch(event)
252// {
253// case ADDED:
254// tempString.append("ADDED: ");
255// break;
256// case MODIFIED:
257// tempString.append("MODIFIED: ");
258// break;
259// case DELETED:
260// tempString.append("DELETED: ");
261// break;
262// }
263
264// tempString.append(absFilePath);
265
266// _LOG_DEBUG ("\t" << tempString.toStdString ());
267// }
268// }
269// else
270// {
271// _LOG_DEBUG ("\t[EMPTY]");
272// }
273// }
274
275#if WAF
276#include "fs-watcher.moc"
277#include "fs-watcher.cc.moc"
278#endif