diff --git a/resources/tomboynotes/configdialog.ui b/resources/tomboynotes/configdialog.ui
index 9f9987dbf..caf01ab7c 100644
--- a/resources/tomboynotes/configdialog.ui
+++ b/resources/tomboynotes/configdialog.ui
@@ -1,123 +1,136 @@
Till Adam <adam@kde.org>
ConfigDialog
0
0
400
- 290
+ 314
Tomboy Server Settings
0
0
0
0
-
0
Tomboy
-
Display name:
-
true
-
Type in the server URL:
-
This value is not changeable after first setup
true
+ -
+
+
+
-
+
+
+ Update interval:
+
+
+
+ -
+
+
+ -
+
+
+ minutes
+
+
+
+
+
+
-
Open in read-only mode
-
Ignore SSL errors
-
Qt::Vertical
20
141
- -
-
-
-
-
-
- true
-
-
-
KLineEdit
QLineEdit
diff --git a/resources/tomboynotes/tomboycollectionsdownloadjob.cpp b/resources/tomboynotes/tomboycollectionsdownloadjob.cpp
index 12eba1e1d..85e76b860 100644
--- a/resources/tomboynotes/tomboycollectionsdownloadjob.cpp
+++ b/resources/tomboynotes/tomboycollectionsdownloadjob.cpp
@@ -1,78 +1,88 @@
/*
Copyright (c) 2016 Stefan Stäglich
This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
*/
#include "tomboycollectionsdownloadjob.h"
#include "debug.h"
#include
+#include
#include
#include
#include
-TomboyCollectionsDownloadJob::TomboyCollectionsDownloadJob(const QString &collectionName, KIO::AccessManager *manager, QObject *parent)
+TomboyCollectionsDownloadJob::TomboyCollectionsDownloadJob(const QString &collectionName, KIO::AccessManager *manager, int refreshInterval, QObject *parent)
: TomboyJobBase(manager, parent),
mCollectionName(collectionName)
{
+ mRefreshInterval = refreshInterval;
}
Akonadi::Collection::List TomboyCollectionsDownloadJob::collections() const
{
return mResultCollections;
}
void TomboyCollectionsDownloadJob::start()
{
// Get user informations
QNetworkRequest request = QNetworkRequest(QUrl(mContentURL));
mReply = mRequestor->get(request, QList());
connect(mReply, &QNetworkReply::finished, this, &TomboyCollectionsDownloadJob::onRequestFinished);
qCDebug(TOMBOYNOTESRESOURCE_LOG) << "TomboyCollectionsDownloadJob: Start network request";
}
void TomboyCollectionsDownloadJob::onRequestFinished()
{
qCDebug(TOMBOYNOTESRESOURCE_LOG) << "TomboyCollectionsDownloadJob: Network request finished";
checkReplyError();
if (error() != TomboyJobError::NoError) {
setErrorText(mReply->errorString());
emitResult();
return;
}
// Parse received data as JSON
const QJsonDocument document = QJsonDocument::fromJson(mReply->readAll(), nullptr);
const QJsonObject jo = document.object();
qCDebug(TOMBOYNOTESRESOURCE_LOG) << "TomboyCollectionsDownloadJob: " << jo;
const QJsonValue collectionRevision = jo[QLatin1String("latest-sync-revision")];
qCDebug(TOMBOYNOTESRESOURCE_LOG) << "TomboyCollectionsDownloadJob: " << collectionRevision;
Akonadi::Collection c;
c.setParentCollection(Akonadi::Collection::root());
c.setRemoteId(mContentURL);
c.setName(mCollectionName);
c.setRemoteRevision(QString::number(collectionRevision.toInt()));
qCDebug(TOMBOYNOTESRESOURCE_LOG) << "TomboyCollectionsDownloadJob: Sync revision " << collectionRevision.toString();
+ Akonadi::CachePolicy cachePolicy;
+ cachePolicy.setInheritFromParent(false);
+ cachePolicy.setSyncOnDemand(false);
+ cachePolicy.setCacheTimeout(-1);
+ cachePolicy.setIntervalCheckTime(mRefreshInterval);
+ cachePolicy.setLocalParts(QStringList() << QStringLiteral("ALL"));
+ c.setCachePolicy(cachePolicy);
+
c.setContentMimeTypes({ Akonadi::NoteUtils::noteMimeType() });
mResultCollections << c;
emitResult();
}
diff --git a/resources/tomboynotes/tomboycollectionsdownloadjob.h b/resources/tomboynotes/tomboycollectionsdownloadjob.h
index 9f11eae0a..829fc51fb 100644
--- a/resources/tomboynotes/tomboycollectionsdownloadjob.h
+++ b/resources/tomboynotes/tomboycollectionsdownloadjob.h
@@ -1,47 +1,48 @@
/*
Copyright (c) 2016 Stefan Stäglich
This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
*/
#ifndef TOMBOYCOLLECTIONSDOWNLOADJOB_H
#define TOMBOYCOLLECTIONSDOWNLOADJOB_H
#include "tomboyjobbase.h"
#include
class TomboyCollectionsDownloadJob : public TomboyJobBase
{
Q_OBJECT
public:
// ctor
- explicit TomboyCollectionsDownloadJob(const QString &collectionName, KIO::AccessManager *manager, QObject *parent = nullptr);
+ explicit TomboyCollectionsDownloadJob(const QString &collectionName, KIO::AccessManager *manager, int refreshInterval, QObject *parent = nullptr);
// returns the parsed results wrapped in Akonadi::Collection::List, see bellow
Akonadi::Collection::List collections() const;
// automatically called by KJob
void start() override;
private Q_SLOTS:
// This will be called once the request is finished.
void onRequestFinished();
private:
Akonadi::Collection::List mResultCollections;
QString mCollectionName;
+ int mRefreshInterval;
};
#endif // TOMBOYCOLLECTIONSDOWNLOADJOB_H
diff --git a/resources/tomboynotes/tomboynotesresource.cpp b/resources/tomboynotes/tomboynotesresource.cpp
index e4747e25e..b287da9f7 100644
--- a/resources/tomboynotes/tomboynotesresource.cpp
+++ b/resources/tomboynotes/tomboynotesresource.cpp
@@ -1,331 +1,336 @@
/*
Copyright (c) 2016 Stefan Stäglich
This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
*/
#include "tomboynotesresource.h"
#include "debug.h"
#include "configdialog.h"
#include "settings.h"
#include "settingsadaptor.h"
#include "tomboyserverauthenticatejob.h"
#include "tomboycollectionsdownloadjob.h"
#include "tomboyitemdownloadjob.h"
#include "tomboyitemsdownloadjob.h"
#include "tomboyitemuploadjob.h"
#include
#include
#include
#include
#include
#include
#include
using namespace Akonadi;
TomboyNotesResource::TomboyNotesResource(const QString &id)
: ResourceBase(id)
{
new SettingsAdaptor(Settings::self());
QDBusConnection::sessionBus().registerObject(QStringLiteral("/Settings"),
Settings::self(),
QDBusConnection::ExportAdaptors);
// Akonadi:Item should always provide the payload
changeRecorder()->itemFetchScope().fetchFullPayload(true);
// Status message stuff
mStatusMessageTimer = new QTimer(this);
mStatusMessageTimer->setSingleShot(true);
connect(mStatusMessageTimer, &QTimer::timeout, [ = ]() {
Q_EMIT status(Akonadi::AgentBase::Idle, QString());
});
connect(this, &AgentBase::error, this, &TomboyNotesResource::showError);
mUploadJobProcessRunning = false;
mManager = new KIO::AccessManager(this);
connect(mManager, &KIO::AccessManager::sslErrors, this, &TomboyNotesResource::onSslError);
qCDebug(TOMBOYNOTESRESOURCE_LOG) << "Resource started";
}
TomboyNotesResource::~TomboyNotesResource()
{
}
void TomboyNotesResource::retrieveCollections()
{
qCDebug(TOMBOYNOTESRESOURCE_LOG) << "Retrieving collections started";
if (configurationNotValid()) {
cancelTask(i18n("Resource configuration is not valid"));
return;
}
- auto job = new TomboyCollectionsDownloadJob(Settings::collectionName(), mManager, this);
+ int refreshInterval = Settings::self()->refreshInterval();
+ if (refreshInterval == 0) {
+ refreshInterval = -1;
+ }
+
+ auto job = new TomboyCollectionsDownloadJob(Settings::collectionName(), mManager, refreshInterval, this);
job->setAuthentication(Settings::requestToken(), Settings::requestTokenSecret());
job->setServerURL(Settings::serverURL(), Settings::userURL());
// connect to its result() signal
connect(job, &KJob::result, this, &TomboyNotesResource::onCollectionsRetrieved);
job->start();
qCDebug(TOMBOYNOTESRESOURCE_LOG) << "Retriving collections job started";
}
void TomboyNotesResource::retrieveItems(const Akonadi::Collection &collection)
{
if (configurationNotValid()) {
cancelTask(i18n("Resource configuration is not valid"));
return;
}
// create the job
auto job = new TomboyItemsDownloadJob(collection.id(), mManager, this);
job->setAuthentication(Settings::requestToken(), Settings::requestTokenSecret());
job->setServerURL(Settings::serverURL(), Settings::contentURL());
// connect to its result() signal
connect(job, &KJob::result, this, &TomboyNotesResource::onItemsRetrieved);
job->start();
qCDebug(TOMBOYNOTESRESOURCE_LOG) << "Retriving items job started";
}
bool TomboyNotesResource::retrieveItem(const Akonadi::Item &item, const QSet &parts)
{
Q_UNUSED(parts);
if (configurationNotValid()) {
cancelTask(i18n("Resource configuration is not valid"));
return false;
}
// this method is called when Akonadi wants more data for a given item.
auto job = new TomboyItemDownloadJob(item, mManager, this);
job->setAuthentication(Settings::requestToken(), Settings::requestTokenSecret());
job->setServerURL(Settings::serverURL(), Settings::contentURL());
// connect to its result() signal
connect(job, &KJob::result, this, &TomboyNotesResource::onItemRetrieved);
job->start();
qCDebug(TOMBOYNOTESRESOURCE_LOG) << "Retriving item data job started";
return true;
}
void TomboyNotesResource::onAuthorizationFinished(KJob *kjob)
{
// Saves the received client authentication data in the settings
qCDebug(TOMBOYNOTESRESOURCE_LOG) << "Authorization job finished";
auto job = qobject_cast(kjob);
if (job->error() == TomboyJobError::NoError) {
Settings::setRequestToken(job->getRequestToken());
Settings::setRequestTokenSecret(job->getRequestTokenSecret());
Settings::setContentURL(job->getContentUrl());
Settings::setUserURL(job->getUserURL());
Settings::self()->save();
synchronizeCollectionTree();
synchronize();
} else {
showError(job->errorText());
}
}
void TomboyNotesResource::onCollectionsRetrieved(KJob *kjob)
{
auto job = qobject_cast(kjob);
if (job->error() != TomboyJobError::NoError) {
cancelTask();
showError(job->errorText());
return;
}
collectionsRetrieved(job->collections());
}
void TomboyNotesResource::onItemChangeCommitted(KJob *kjob)
{
auto job = qobject_cast(kjob);
mUploadJobProcessRunning = false;
switch (job->error()) {
case TomboyJobError::PermanentError:
cancelTask();
showError(job->errorText());
return;
case TomboyJobError::TemporaryError:
retryAfterFailure(job->errorString());
return;
case TomboyJobError::NoError:
changeCommitted(job->item());
// The data should be actualized for the next UploadJob
synchronize();
return;
}
}
void TomboyNotesResource::onItemRetrieved(KJob *kjob)
{
auto job = qobject_cast(kjob);
if (job->error() != TomboyJobError::NoError) {
cancelTask();
showError(job->errorText());
return;
}
itemRetrieved(job->item());
qCDebug(TOMBOYNOTESRESOURCE_LOG) << "Retriving item data job with remoteId " << job->item().remoteId() << " finished";
}
void TomboyNotesResource::onItemsRetrieved(KJob *kjob)
{
auto job = qobject_cast(kjob);
if (job->error() != TomboyJobError::NoError) {
cancelTask();
showError(job->errorText());
return;
}
itemsRetrieved(job->items());
qCDebug(TOMBOYNOTESRESOURCE_LOG) << "Retriving items job finished";
}
void TomboyNotesResource::onSslError(QNetworkReply *reply, const QList &errors)
{
Q_UNUSED(errors);
if (Settings::ignoreSslErrors()) {
reply->ignoreSslErrors();
}
}
void TomboyNotesResource::aboutToQuit()
{
// TODO: any cleanup you need to do while there is still an active
// event loop. The resource will terminate after this method returns
}
void TomboyNotesResource::configure(WId windowId)
{
qCDebug(TOMBOYNOTESRESOURCE_LOG) << "Resource configuration started";
ConfigDialog dialog(Settings::self());
if (windowId) {
KWindowSystem::setMainWindow(&dialog, windowId);
}
// Run the configuration dialog an save settings if accepted
if (dialog.exec() != QDialog::Accepted) {
Q_EMIT configurationDialogRejected();
return;
}
dialog.saveSettings();
setAgentName(Settings::collectionName());
if (configurationNotValid()) {
auto job = new TomboyServerAuthenticateJob(mManager, this);
job->setServerURL(Settings::serverURL(), QString());
connect(job, &KJob::result, this, &TomboyNotesResource::onAuthorizationFinished);
job->start();
qCDebug(TOMBOYNOTESRESOURCE_LOG) << "Authorization job started";
} else {
synchronize();
}
Q_EMIT configurationDialogAccepted();
}
void TomboyNotesResource::itemAdded(const Akonadi::Item &item, const Akonadi::Collection &collection)
{
Q_UNUSED(collection);
if (Settings::readOnly() || configurationNotValid()) {
cancelTask(i18n("Resource is read-only"));
return;
}
if (mUploadJobProcessRunning) {
retryAfterFailure(QString());
return;
}
auto job = new TomboyItemUploadJob(item, JobType::AddItem, mManager, this);
job->setAuthentication(Settings::requestToken(), Settings::requestTokenSecret());
job->setServerURL(Settings::serverURL(), Settings::contentURL());
connect(job, &KJob::result, this, &TomboyNotesResource::onItemChangeCommitted);
mUploadJobProcessRunning = true;
job->start();
}
void TomboyNotesResource::itemChanged(const Akonadi::Item &item, const QSet &parts)
{
Q_UNUSED(parts);
if (Settings::readOnly() || configurationNotValid()) {
cancelTask(i18n("Resource is read-only"));
return;
}
if (mUploadJobProcessRunning) {
retryAfterFailure(QString());
return;
}
auto job = new TomboyItemUploadJob(item, JobType::ModifyItem, mManager, this);
job->setAuthentication(Settings::requestToken(), Settings::requestTokenSecret());
job->setServerURL(Settings::serverURL(), Settings::contentURL());
connect(job, &KJob::result, this, &TomboyNotesResource::onItemChangeCommitted);
mUploadJobProcessRunning = true;
job->start();
}
void TomboyNotesResource::itemRemoved(const Akonadi::Item &item)
{
if (Settings::readOnly() || configurationNotValid()) {
cancelTask(i18n("Resource is read-only"));
return;
}
if (mUploadJobProcessRunning) {
retryAfterFailure(QString());
return;
}
auto job = new TomboyItemUploadJob(item, JobType::DeleteItem, mManager, this);
job->setAuthentication(Settings::requestToken(), Settings::requestTokenSecret());
job->setServerURL(Settings::serverURL(), Settings::contentURL());
connect(job, &KJob::result, this, &TomboyNotesResource::onItemChangeCommitted);
mUploadJobProcessRunning = true;
job->start();
}
bool TomboyNotesResource::configurationNotValid() const
{
return Settings::requestToken().isEmpty() || Settings::contentURL().isEmpty();
}
void TomboyNotesResource::retryAfterFailure(const QString &errorMessage)
{
Q_EMIT status(Broken, errorMessage);
deferTask();
setTemporaryOffline(Settings::self()->refreshInterval() <= 0 ? 300 : Settings::self()->refreshInterval() * 60);
}
void TomboyNotesResource::showError(const QString &errorText)
{
Q_EMIT status(Akonadi::AgentBase::Idle, errorText);
mStatusMessageTimer->start(1000 * 10);
}
AKONADI_RESOURCE_MAIN(TomboyNotesResource)
#include "moc_tomboynotesresource.cpp"