Commit 50728bb8 authored by Martin Höher's avatar Martin Höher

Watch Libraries without sync

Watch the directories of libraries which do not have a synchronizer set
up for changes.

This closes #193.
parent 702c0a83
Pipeline #34608913 passed with stages
in 11 minutes and 34 seconds
......@@ -62,8 +62,6 @@ Pane {
delegate: Column {
id: librarySection
Component.onCompleted: console.warn(library)
width: parent.width
LibrarySideBarButton {
......
......@@ -32,6 +32,7 @@
#include "sync/webdavsynchronizer.h"
#include "utils/jsonutils.h"
#include "utils/keystore.h"
#include "utils/directorywatcher.h"
static Q_LOGGING_CATEGORY(log, "OpenTodoList.Application", QtDebugMsg)
......@@ -50,7 +51,8 @@ Application::Application(QObject *parent) :
QCoreApplication::applicationName(), this)),
m_cache(new Cache(this)),
m_keyStore(new KeyStore(this)),
m_secrets()
m_secrets(),
m_watchedDirectories()
{
initialize();
}
......@@ -68,7 +70,8 @@ Application::Application(QString applicationDir, QObject *parent) :
QSettings::IniFormat, this)),
m_cache(new Cache(this)),
m_keyStore(new KeyStore(this)),
m_secrets()
m_secrets(),
m_watchedDirectories()
{
initialize(applicationDir);
}
......@@ -202,6 +205,29 @@ void Application::syncLibrariesWithCache(
}
}
template<typename T>
void Application::watchLibraryForChanges(T library)
{
QScopedPointer<Synchronizer> sync(library->createSynchronizer());
if (sync == nullptr && library->isValid()) {
auto watcher = new DirectoryWatcher(this);
auto directory = library->directory();
auto uid = library->uid();
watcher->setDirectory(library->directory());
m_watchedDirectories[library->directory()] = watcher;
connect(watcher, &DirectoryWatcher::directoryChanged,
[=]() {
auto loader = new LibraryLoader();
loader->setCache(m_cache);
loader->setDirectory(directory);
loader->setLibraryId(uid);
connect(loader, &LibraryLoader::scanFinished,
loader, &LibraryLoader::deleteLater);
loader->scan();
});
}
}
/**
* @brief Destructor.
......@@ -292,12 +318,17 @@ Library *Application::addLibrary(const QVariantMap &parameters)
emit secretsKeysChanged();
delete sync;
}
} else {
watchLibraryForChanges(result);
}
auto q = new InsertOrUpdateItemsQuery();
q->add(result);
m_cache->run(q);
syncLibrary(result);
result->setCache(m_cache);
auto libs = librariesFromConfig();
libs << QSharedPointer<Library>(Library::decache(result->encache()));
librariesToConfig(libs);
}
return result;
}
......@@ -314,10 +345,16 @@ Library *Application::addLibrary(const QVariantMap &parameters)
void Application::deleteLibrary(Library *library)
{
if (library != nullptr) {
auto watcher = m_watchedDirectories.value(
library->directory(), nullptr);
if (m_directoriesWithRunningSync.contains(library->directory())) {
qCWarning(log) << "Cannot delete a library which is syncing.";
return;
}
if (watcher != nullptr) {
delete watcher;
m_watchedDirectories.remove(library->directory());
}
auto q = new DeleteItemsQuery();
q->deleteLibrary(library, library->isInDefaultLocation());
m_cache->run(q);
......@@ -753,6 +790,7 @@ void Application::loadLibraries()
m_keyStore->loadCredentials(key);
}
}
watchLibraryForChanges(library);
}
}
......@@ -792,6 +830,18 @@ void Application::onLibrarySyncFinished(QString directory)
auto dirs = directoriesWithRunningSync();
dirs.removeAll(directory);
setDirectoriesWithRunningSync(dirs);
auto libs = librariesFromConfig();
for (auto lib : libs) {
if (lib->directory() == directory) {
auto loader = new LibraryLoader();
loader->setCache(m_cache);
loader->setLibraryId(lib->uid());
loader->setDirectory(directory);
connect(loader, &LibraryLoader::scanFinished,
loader, &LibraryLoader::deleteLater);
loader->scan();
}
}
}
}
......
......@@ -13,16 +13,15 @@
#include <QVector>
class KeyStore;
class Cache;
class Note;
class DirectoryWatcher;
class Image;
class TodoList;
class Todo;
class KeyStore;
class Note;
class Task;
class Todo;
class TodoList;
// TODO: Watch libraries w/o synchronizer for changes on disk -> DirectoryWatcher
// TODO: Listen for changes and trigger sync automatically.
/**
* @brief The main class of the application
......@@ -31,6 +30,10 @@ class Task;
* as contained class and provides references to other objects. Basically, the Application class
* models the application, i.e. it is created when the application starts and destroyed once
* the application is to be closed.
*
* @todo Watch libraries w/o synchronizer for changes on disk -> DirectoryWatcher
*
* @todo Listen for changes and trigger sync automatically.
*/
class Application : public QObject
{
......@@ -113,6 +116,8 @@ private:
QVariantMap m_secrets;
QStringList m_directoriesWithRunningSync;
QVariantMap m_syncErrors;
QMap<QString, DirectoryWatcher*>
m_watchedDirectories;
void saveLibraries();
void loadLibraries();
......@@ -129,6 +134,9 @@ private:
template<typename T>
void runSyncForLibrary(T library);
template<typename T>
void watchLibraryForChanges(T library);
private slots:
void onLibrarySyncFinished(QString directory);
......
......@@ -56,7 +56,7 @@ void Image::setImage(const QString &image)
{
if (m_image != image) {
if (!isValid()) {
// TODO: Probably related to https://gitlab.com/rpdev/opentodolist/issues/202
// @todo Probably related to https://gitlab.com/rpdev/opentodolist/issues/202
m_image = image;
save();
emit imageChanged();
......
......@@ -372,7 +372,7 @@ QUuid Library::uid() const
*/
QStringList Library::tags() const
{
// TODO: Implement differently
// @todo Implement differently
QSet<QString> tags;
// for (int i = 0; i < m_topLevelItems.count(); ++i) {
// auto item = qSharedPointerDynamicCast<TopLevelItem>(m_topLevelItems.item(i));
......
......@@ -99,7 +99,7 @@ void Todo::setTodoListUid(const QUuid& todoListUid)
*/
int Todo::percentageDone() const
{
// TODO: Implement me
// @todo Implement me
// auto uid = this->uid();
// int totalTasks = 0;
// int completeTasks = 0;
......
......@@ -23,7 +23,7 @@ class DirectoryWatcher : public QObject
{
Q_OBJECT
public:
explicit DirectoryWatcher(QObject *parent = 0);
explicit DirectoryWatcher(QObject *parent = nullptr);
virtual ~DirectoryWatcher();
signals:
......
......@@ -31,7 +31,7 @@ Component.prototype.createOperations = function()
"Categories=Utility;");
}
// todo: What should we do on Mac?
// @todo What should we do on Mac?
if (installer.value("os") === "mac") {
}
......
......@@ -65,7 +65,7 @@ void LibraryTest::testProperties()
void LibraryTest::testTags()
{
// TODO: Implement me
// @todo Implement me
// Library lib;
// auto note1 = lib.addNote();
// auto note2 = lib.addNote();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment