blob: 98f38571a822a8ecadab3ff8614a793aa8ebda44 [file] [log] [blame]
jareda9541812013-01-09 00:08:46 -08001#include "filesystemwatcher.h"
2#include "ui_filesystemwatcher.h"
3
Jared Lindblom4d1d00a2013-01-11 01:14:23 -08004FileSystemWatcher::FileSystemWatcher(QString dirPath, QWidget *parent) :
jareda9541812013-01-09 00:08:46 -08005 QMainWindow(parent),
Jared Lindblom4d1d00a2013-01-11 01:14:23 -08006 m_ui(new Ui::FileSystemWatcher),
jareda9541812013-01-09 00:08:46 -08007 m_watcher(new QFileSystemWatcher()),
8 m_listViewModel(new QStringListModel()),
9 m_listView(new QListView()),
10 m_dirPath(dirPath)
11{
12 // setup user interface
13 m_ui->setupUi(this);
14
15 // add main directory to monitor
16 m_watcher->addPath(m_dirPath);
17
18 // create the view
19 m_listView->setModel(m_listViewModel);
20 setCentralWidget(m_listView);
21
22 // set title
23 setWindowTitle("ChronoShare");
24
Jared Lindblom4d1d00a2013-01-11 01:14:23 -080025 // open database
26 m_db = QSqlDatabase::addDatabase("QSQLITE");
27 m_db.setDatabaseName("filesystem.db");
28
29 if(!m_db.open())
30 {
31 qDebug() << "Error: Could not open database.";
32 return;
33 }
34
35 if(!createFileTable())
36 {
37 qDebug() << "Error: Could not create table.";
38 return;
39 }
40
jareda9541812013-01-09 00:08:46 -080041 // register signals (callback functions)
Jared Lindblom4d1d00a2013-01-11 01:14:23 -080042 connect(m_watcher, SIGNAL(directoryChanged(QString)),this,SLOT(dirChangedSlot(QString)));
jareda9541812013-01-09 00:08:46 -080043
44 // bootstrap file list
45 dirChangedSlot(m_dirPath);
46}
47
Jared Lindblom4d1d00a2013-01-11 01:14:23 -080048FileSystemWatcher::~FileSystemWatcher()
jareda9541812013-01-09 00:08:46 -080049{
50 // clean up
51 delete m_ui;
52 delete m_watcher;
53 delete m_listViewModel;
54 delete m_listView;
Jared Lindblom4d1d00a2013-01-11 01:14:23 -080055
56 // close database
57 m_db.close();
jareda9541812013-01-09 00:08:46 -080058}
59
Jared Lindblom4d1d00a2013-01-11 01:14:23 -080060void FileSystemWatcher::dirChangedSlot(QString dirPath)
jareda9541812013-01-09 00:08:46 -080061{
Jared Lindblom4d1d00a2013-01-11 01:14:23 -080062 // scan directory and populate file list
63 QHash<QString, QFileInfo> fileList = scanDirectory(dirPath);
64
65 QStringList dirChanges = reconcileDirectory(fileList);
66
67 // update gui with list of changes in this directory
68 m_listViewModel->setStringList(dirChanges);
jareda9541812013-01-09 00:08:46 -080069}
70
Jared Lindblom4d1d00a2013-01-11 01:14:23 -080071QHash<QString, QFileInfo> FileSystemWatcher::scanDirectory(QString dirPath)
jareda9541812013-01-09 00:08:46 -080072{
73 // list of files in directory
Jared Lindblom4d1d00a2013-01-11 01:14:23 -080074 QHash<QString, QFileInfo> fileList;
jareda9541812013-01-09 00:08:46 -080075
76 // directory iterator (recursive)
Jared Lindblom4d1d00a2013-01-11 01:14:23 -080077 QDirIterator dirIterator(dirPath, QDirIterator::Subdirectories |
jareda9541812013-01-09 00:08:46 -080078 QDirIterator::FollowSymlinks);
79
80 // iterate through directory recursively
81 while(dirIterator.hasNext())
82 {
83 // Get Next File/Dir
84 dirIterator.next();
85
86 // Get FileInfo
87 QFileInfo fileInfo = dirIterator.fileInfo();
88
89 // if not this directory or previous directory
90 if(fileInfo.absoluteFilePath() != ".." && fileInfo.absoluteFilePath() != ".")
91 {
92 // if this is a directory
93 if(fileInfo.isDir())
94 {
95 QStringList dirList = m_watcher->directories();
96
97 // if the directory is not already being watched
98 if (!dirList.contains(fileInfo.absoluteFilePath()))
99 {
100 // add this directory to the watch list
101 m_watcher->addPath(fileInfo.absoluteFilePath());
102 }
103 }
104 else
105 {
106 // add this file to the file list
Jared Lindblom4d1d00a2013-01-11 01:14:23 -0800107 fileList.insert(fileInfo.absoluteFilePath(), fileInfo);
jareda9541812013-01-09 00:08:46 -0800108 }
109 }
110 }
111
Jared Lindblom4d1d00a2013-01-11 01:14:23 -0800112 return fileList;
113}
114
115QStringList FileSystemWatcher::reconcileDirectory(QHash<QString, QFileInfo> fileList)
116{
117 QStringList dirChanges;
118
119 // setup database query
120 QSqlQuery storedRecord(m_db);
121
122 // query database for list of files
123 storedRecord.exec("SELECT absFilePath, lastModified FROM files");
124
125 // Debug
126 qDebug() << storedRecord.lastQuery();
127
128 // compare result (database/stored snapshot) to fileList (current snapshot)
129 while(storedRecord.next())
130 {
131 QString absFilePath = storedRecord.value(0).toString();
132 qint64 lMStored = storedRecord.value(1).toLongLong();
133
134 // debug
135 qDebug() << absFilePath << ", " << lMStored;
136
137 // check file existence
138 /*if(fileList.contains(absFilePath))
139 {
140 QFileInfo fileInfo = fileList.value(absFilePath);
141
142 // last Modified
143 qint64 lMCurrent = fileInfo.lastModified().currentMSecsSinceEpoch();
144
145 if(lMStored != lMCurrent)
146 {
147 storedRecord.prepare("UPDATE files SET lastModified = :lastModified "
148 "WHERE absFilePath= :absFilePath");
149 storedRecord.bindValue(":lastModified", lMCurrent);
150 storedRecord.bindValue(":absFilePath", absFilePath);
151 storedRecord.exec();
152
153 // Debug
154 qDebug() << storedRecord.lastQuery();
155
156 // this file has been modified
157 dirChanges.append(absFilePath);
158 }
159
160 // delete this file from fileList, we have processed it
161 fileList.remove(absFilePath);
162 }
163 else
164 {
165 storedRecord.prepare("DELETE FROM files WHERE absFilePath= :absFilePath");
166 storedRecord.bindValue(":absFilePath", absFilePath);
167 storedRecord.exec();
168
169 // Debug
170 qDebug() << storedRecord.lastQuery();
171
172 // this file has been deleted
173 dirChanges.append(absFilePath);
174 }*/
175 }
176
177 /*storedRecord.prepare("INSERT INTO files (absFilePath, lastModified) "
178 "VALUES (:absFilePath, :lastModified)");
179
180 // any files left in fileList have been added
181 for(QHash<QString, QFileInfo>::iterator i = fileList.begin(); i != fileList.end(); ++i)
182 {
183 QString absFilePath = i.key();
184 qint64 lastModified = i.value().lastModified().currentMSecsSinceEpoch();
185
186 storedRecord.bindValue(":absFilePath", absFilePath);
187 storedRecord.bindValue(":lastModified", lastModified);
188 storedRecord.exec();
189
190 // this file has been added
191 dirChanges.append(absFilePath);
192 }*/
193
194 // close query
195 storedRecord.finish();
196
197 return dirChanges;
198}
199
200bool FileSystemWatcher::createFileTable()
201{
202 bool success = false;
203
204 if(m_db.isOpen())
205 {
206 if(m_db.tables().contains("files"))
207 {
208 success = true;
209 }
210 else
211 {
212 QSqlQuery query(m_db);
213
214 // create file table
215 success = query.exec("CREATE TABLE files "
216 "(absFilePath TEXT primary key, "
217 "lastModified UNSIGNED BIG INT, "
218 "fileSize UNSIGNED BIG INT)");
219
220 // Debug
221 qDebug() << query.lastQuery();
222
223 query.finish();
224 }
225 }
226
227 return success;
jareda9541812013-01-09 00:08:46 -0800228}
Alexander Afanasyevff731962013-01-09 17:16:28 -0800229
230#if WAF
231#include "filesystemwatcher.moc"
232#include "filesystemwatcher.cpp.moc"
233#endif