Commit db483f37 authored by Stefan Staeglich's avatar Stefan Staeglich Committed by Sandro Knauß

A new akonadi resource: Notes sharing via Tomboy REST API

CHANGELOG: A new Akondi resource for sharing notes via Tomboy REST API
Differential Revision: https://phabricator.kde.org/D2038
parent 408b78da
......@@ -85,6 +85,8 @@ find_package( SharedMimeInfo REQUIRED )
# QT5 package
find_package(Qt5 ${QT_REQUIRED_VERSION} CONFIG REQUIRED Network Widgets Test XmlPatterns DBus)
find_package(Qt5 OPTIONAL_COMPONENTS WebEngineWidgets REQUIRED)
find_package(Qt5 OPTIONAL_COMPONENTS TextToSpeech)
if (NOT Qt5TextToSpeech_FOUND)
message(STATUS "Qt5TextToSpeech not found, speech feature will be disabled")
......
......@@ -83,5 +83,4 @@ add_subdirectory( vcarddir )
add_subdirectory( icaldir )
add_subdirectory( vcard )
add_subdirectory( folderarchivesettings )
add_subdirectory( tomboynotes )
remove_definitions(-DQT_NO_URL_CAST_FROM_STRING
-DQT_NO_CAST_FROM_BYTEARRAY
-DQT_NO_CAST_FROM_ASCII
-DQT_NO_CAST_TO_ASCII
-DQT_USE_QSTRINGBUILDER
-DQT_USE_FAST_OPERATOR_PLUS
)
########### next target ###############
set(tomboynotesresource_SRCS
configdialog.cpp
tomboynotesresource.cpp
tomboycollectionsdownloadjob.cpp
tomboyitemdownloadjob.cpp
tomboyitemuploadjob.cpp
tomboyitemsdownloadjob.cpp
tomboyjobbase.cpp
tomboyserverauthenticatejob.cpp
o1tomboy.cpp
o2/o0settingsstore.cpp
o2/o0baseauth.cpp
o2/o0abstractstore.h
o2/o0globals.h
o2/o1.cpp
o2/o1requestor.cpp
o2/o1timedreply.cpp
o2/o2.cpp
o2/o2reply.cpp
o2/o2replyserver.cpp
o2/o2requestor.cpp
o2/o2simplecrypt.cpp
)
ecm_qt_declare_logging_category(tomboynotesresource_SRCS
HEADER debug.h
IDENTIFIER log_tomboynotesresource
CATEGORY_NAME log_tomboynotesresource
)
ki18n_wrap_ui(tomboynotesresource_SRCS configdialog.ui)
kconfig_add_kcfg_files(tomboynotesresource_SRCS
${CMAKE_CURRENT_SOURCE_DIR}/settings.kcfgc
)
kcfg_generate_dbus_interface(
${CMAKE_CURRENT_SOURCE_DIR}/tomboynotesresource.kcfg
org.kde.Akonadi.TomboyNotes.Settings
)
qt5_add_dbus_adaptor(tomboynotesresource_SRCS
${CMAKE_CURRENT_BINARY_DIR}/org.kde.Akonadi.TomboyNotes.Settings.xml
${CMAKE_CURRENT_BINARY_DIR}/settings.h
Settings
)
add_executable(akonadi_tomboynotes_resource ${tomboynotesresource_SRCS})
target_link_libraries(akonadi_tomboynotes_resource
Qt5::DBus
Qt5::Gui
Qt5::Network
Qt5::WebEngineWidgets
KF5::AkonadiAgentBase
KF5::AkonadiNotes
KF5::ConfigCore
KF5::ConfigWidgets
KF5::I18n
KF5::KIOCore
KF5::KIOFileWidgets
KF5::KIONTLM
KF5::KIOWidgets
KF5::Mime
KF5::WindowSystem
)
install(TARGETS akonadi_tomboynotes_resource ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})
install(FILES tomboynotesresource.desktop
DESTINATION "${KDE_INSTALL_DATAROOTDIR}/share/akonadi/agents"
)
#! /usr/bin/env bash
$EXTRACTRC `find . -name \*.ui` `find . -name \*.kcfg` >> rc.cpp || exit 11
$XGETTEXT *.cpp -o $podir/akonadi_tomboynotes_resource.pot
rm -f rc.cpp
==== What's this ? ====
This is an Akonadi resource for Tomboy-compatible note servers like Grauphel.
==== Usage ====
For this resource you need only the URL of your service,
e.g. https://fqdn/index.php/apps/grauphel
It is the same URL that you have used in Tomboy.
For the registration process it will open a web page where you can log in
with your username and password of your account of the note server.
==== Tested with ====
Today it's tested only with Grauphel. So it may be incompatible with
other server implemantations (e.g. Rainy). But you are free to test it
and to report your experiences.
==== Depends on ====
the OAuth library o2. At the moment it is shipped with the resource code
in the subfolder o2. You can find the licence in the file o2/LICENSE.
The shipped version is based on this last commit:
https://github.com/pipacs/o2/commit/0d39396e06fc54dfef9433497f78567944519602
I changed only the o2 includes and the code style. The changes are documented
in o2/changes.patch.
/*
Copyright (c) 2016 Stefan Stäglich <sstaeglich@kdemail.net>
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 "configdialog.h"
#include "ui_configdialog.h"
#include "settings.h"
#include <kconfigdialogmanager.h>
#include <klocalizedstring.h>
ConfigDialog::ConfigDialog(Settings *settings, QWidget *parent) :
QDialog(parent),
ui(new Ui::ConfigDialog),
mSettings(settings)
{
// Create window
setWindowTitle(i18n("Select a Tomboy server"));
QWidget *mainWidget = new QWidget(this);
QVBoxLayout *mainLayout = new QVBoxLayout;
setLayout(mainLayout);
mainLayout->addWidget(mainWidget);
ui->setupUi(mainWidget);
// KSettings stuff. Works not in the initialization list!
mManager = new KConfigDialogManager(this, settings);
mManager->updateWidgets();
// Set the button actions
connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &ConfigDialog::accept);
connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &ConfigDialog::reject);
// Load config dialog window size settings
KConfigGroup group(KSharedConfig::openConfig(), "ConfigDialog");
const QSize size = group.readEntry("Size", QSize(600, 400));
if (size.isValid()) {
resize(size);
}
ui->kcfg_ServerURL->setReadOnly(!mSettings->requestToken().isEmpty());
}
ConfigDialog::~ConfigDialog()
{
// Save config dialog window size
KConfigGroup group(KSharedConfig::openConfig(), "ConfigDialog");
group.writeEntry("Size", size());
group.sync();
delete ui;
}
void ConfigDialog::saveSettings()
{
if (ui->kcfg_ServerURL->text() != mSettings->serverURL()) {
mSettings->setRequestToken(QString());
mSettings->setRequestTokenSecret(QString());
}
if (ui->kcfg_collectionName->text().isEmpty()) {
ui->kcfg_collectionName->setText(i18n("Tomboy Notes %1", Settings::serverURL()));
}
mManager->updateSettings();
mSettings->save();
}
/*
Copyright (c) 2016 Stefan Stäglich <sstaeglich@kdemail.net>
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 CONFIGDIALOG_H
#define CONFIGDIALOG_H
#include <QDialog>
class KConfigDialogManager;
class Settings;
namespace Ui
{
class ConfigDialog;
}
class ConfigDialog : public QDialog
{
Q_OBJECT
public:
explicit ConfigDialog(Settings *settings, QWidget *parent = Q_NULLPTR);
~ConfigDialog();
void saveSettings();
private:
Ui::ConfigDialog *ui;
KConfigDialogManager *mManager;
Settings *mSettings;
};
#endif // CONFIGDIALOG_H
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<author>Till Adam &lt;adam@kde.org&gt;</author>
<class>ConfigDialog</class>
<widget class="QWidget" name="ConfigDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>290</height>
</rect>
</property>
<property name="windowTitle">
<string>Tomboy Server Settings</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="tab">
<attribute name="title">
<string>Tomboy</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Display name:</string>
</property>
</widget>
</item>
<item>
<widget class="KLineEdit" name="kcfg_collectionName">
<property name="showClearButton" stdset="0">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Type in the server URL:</string>
</property>
</widget>
</item>
<item>
<widget class="KLineEdit" name="kcfg_ServerURL">
<property name="toolTip">
<string>This value is not changeable after first setup</string>
</property>
<property name="showClearButton" stdset="0">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="kcfg_ReadOnly">
<property name="text">
<string>Open in read-only mode</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="kcfg_ignoreSslErrors">
<property name="text">
<string>Ignore SSL errors</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>141</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
<item>
<widget class="QLabel" name="statusLabel">
<property name="text">
<string/>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>KLineEdit</class>
<extends>QLineEdit</extends>
<header>klineedit.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
/*
Copyright (c) 2016 Stefan Stäglich <sstaeglich@kdemail.net>
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 "o1tomboy.h"
O1Tomboy::O1Tomboy(QObject *parent) : O1(parent)
{
}
void O1Tomboy::setBaseURL(const QString &value)
{
setRequestTokenUrl(QUrl(value + QStringLiteral("/oauth/request_token")));
setAuthorizeUrl(QUrl(value + QStringLiteral("/oauth/authorize")));
setAccessTokenUrl(QUrl(value + QStringLiteral("/oauth/access_token")));
setClientId("anyone");
setClientSecret("anyone");
}
QString O1Tomboy::getRequestToken() const
{
return requestToken_;
}
QString O1Tomboy::getRequestTokenSecret() const
{
return requestTokenSecret_;
}
void O1Tomboy::restoreAuthData(const QString &token, const QString &secret)
{
requestToken_ = token;
requestTokenSecret_ = secret;
setLinked(true);
}
/*
Copyright (c) 2016 Stefan Stäglich <sstaeglich@kdemail.net>
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 O1TOMBOY_H
#define O1TOMBOY_H
#include "o2/o1.h"
class O1Tomboy : public O1
{
Q_OBJECT
public:
explicit O1Tomboy(QObject *parent = Q_NULLPTR);
void setBaseURL(const QString &value);
QString getRequestToken() const;
QString getRequestTokenSecret() const;
void restoreAuthData(const QString &token, const QString &secret);
};
#endif // O1TOMBOY_H
# Change Log
## 1.0.0
* O1 and O2 to share a common base class
* Move common classes to the O0 name space
* Cleanups and bug fixes
## 0.1.0
* Add Sialis, a Qt Quick Twitter demo client
* Cleanups and bug fixes
## Pre-0.1.0
* Initial non-release
Copyright (c) 2012, Akos Polster
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# OAuth 1.0 and 2.0 for Qt
This library encapsulates the OAuth 1.0 and 2.0 client authentication flows, and the sending of authenticated HTTP requests.
The primary target is Qt Quick applications on embedded devices.
Notes to contributors:
* Please follow the coding style of the existing source
* Code contributions are released under Simplified BSD License, as specified in LICENSE. Do not contribute if this license does not suit your code
## Classes
Class | Header | Purpose
:-- | :-- | :--
O0AbstractStore | o0abstractstore.h | Base class of persistent stores
O0BaseAuth | o0baseauth.h | Base class of OAuth authenticators
O0SettingsStore | o2settingsstore.h | QSettings-based persistent store
O0SimpleCrypt | o0simplecrypt.h | Simple encryption and decryption by Andre Somers
O1 | o1.h | Generic OAuth 1.0 authenticator
O1Dropbox | o1dropbox.h | Dropbox OAuth specialization
O1Flickr | o1flickr.h | Flickr OAuth specialization
O1Freshbooks | o1freshbooks.h | Freshbooks OAuth specialization
O1Requestor | o1requestor.h | Makes authenticated OAuth 1.0 requests: GET, POST or PUT, handles timeouts
O1RequestParameter | o1.h | An extra request parameter participating in request signing
O1Twitter | o1twitter.h | Twitter OAuth specialization
O2 | o2.h | Generic OAuth 2.0 authenticator
O2Facebook | o2facebook.h | Facebook OAuth specialization
O2Gft | o2gft.h | Google Fusion Tables OAuth specialization
O2Hubic | o2hubic.h | Hubic OAuth specialization
O2Reply | o2reply.h | A network request/reply that can time out
O2ReplyServer | o2replyserver.h | HTTP server to process authentication responses
O2Requestor | o2requestor.h | Makes authenticated OAuth 2.0 requests (GET, POST or PUT), handles timeouts and token expiry
O2Skydrive | o2skydrive.h | OneDrive OAuth specialization
O2SurveyMonkey | o2surveymonkey.h | SurveyMonkey OAuth specialization
OXTwitter | oxtwitter.h | Twitter XAuth specialization
## Installation
Clone the Github repository, then add all files in *src* to your Qt project, by including *src/src.pri*.
## Basic Usage
This example assumes a hypothetical Twitter client that will post tweets. Twitter is using OAuth 1.0.
### Setup
Include the required header files, and have some member variables that will be used for authentication and sending requests:
#include "o1twitter.h"
#include "o1requestor.h"
O1Twitter *o1;
### Initialization
Instantiate one of the authenticator classes, like O1Twitter, set your application ID and application secret, and install the signal handlers:
o1 = new O1Twitter(this);
o1->setClientId(MY_CLIENT_ID);
o1->setClientSecret(MY_CLIENT_SECRET);
connect(o1, SIGNAL(linkedChanged()), this, SLOT(onLinkedChanged()));
connect(o1, SIGNAL(linkingFailed()), this, SLOT(onLinkingFailed()));
connect(o1, SIGNAL(linkingSucceeded()), this, SLOT(onLinkingSucceeded()));
connect(o1, SIGNAL(openBrowser(QUrl)), this, SLOT(onOpenBrowser(QUrl)));
connect(o1, SIGNAL(closeBrowser()), this, SLOT(onCloseBrowser()));
**Note:** For browserless Twitter authentication, you can use the OXTwitter specialized class which can do Twitter XAuth. You will need to additionally provide your Twitter login credentials (username & password) before calling *link()*.
### Handling Signals
O2 is an asynchronous library. It will send signals at various stages of authentication and request processing.
To handle these signals, implement the following slots in your code:
void onLinkedChanged() {
// Linking (login) state has changed.