summaryrefslogtreecommitdiffstats
path: root/examples
diff options
context:
space:
mode:
authorJesus Fernandez <jesus.fernandez@qt.io>2016-10-24 00:41:17 +0200
committerJani Heikkinen <jani.heikkinen@qt.io>2016-12-07 05:57:08 +0000
commita493cacda6365ba29e5d3e1cf373c61329c00d77 (patch)
tree0168c8e4a9eb34bb58d2cf547d57ba1c794ef925 /examples
parent35291fa676359588fedd9b821328e91fff8511e6 (diff)
Twitter Client Example
Basic Twitter client which shows the user timeline in a QTableView. Also add documentation for the example, and the examples group page for this module. Change-Id: I54bf0eb3385d3fa2befec1b0b84246237c13f597 Reviewed-by: Topi Reiniƶ <topi.reinio@qt.io>
Diffstat (limited to 'examples')
-rw-r--r--examples/examples.pro2
-rw-r--r--examples/oauth/oauth.pro2
-rw-r--r--examples/oauth/twittertimeline/doc/images/twittertimeline-example.pngbin0 -> 24972 bytes
-rw-r--r--examples/oauth/twittertimeline/doc/src/qtnetworkauth-twittertimeline.qdoc44
-rw-r--r--examples/oauth/twittertimeline/main.cpp115
-rw-r--r--examples/oauth/twittertimeline/twitter.cpp82
-rw-r--r--examples/oauth/twittertimeline/twitter.h62
-rw-r--r--examples/oauth/twittertimeline/twitterdialog.ui73
-rw-r--r--examples/oauth/twittertimeline/twittertimeline.pro18
-rw-r--r--examples/oauth/twittertimeline/twittertimelinemodel.cpp188
-rw-r--r--examples/oauth/twittertimeline/twittertimelinemodel.h80
11 files changed, 666 insertions, 0 deletions
diff --git a/examples/examples.pro b/examples/examples.pro
new file mode 100644
index 0000000..ec4fa52
--- /dev/null
+++ b/examples/examples.pro
@@ -0,0 +1,2 @@
+TEMPLATE = subdirs
+SUBDIRS += oauth
diff --git a/examples/oauth/oauth.pro b/examples/oauth/oauth.pro
new file mode 100644
index 0000000..06a388d
--- /dev/null
+++ b/examples/oauth/oauth.pro
@@ -0,0 +1,2 @@
+TEMPLATE = subdirs
+SUBDIRS += twittertimeline
diff --git a/examples/oauth/twittertimeline/doc/images/twittertimeline-example.png b/examples/oauth/twittertimeline/doc/images/twittertimeline-example.png
new file mode 100644
index 0000000..99d66c9
--- /dev/null
+++ b/examples/oauth/twittertimeline/doc/images/twittertimeline-example.png
Binary files differ
diff --git a/examples/oauth/twittertimeline/doc/src/qtnetworkauth-twittertimeline.qdoc b/examples/oauth/twittertimeline/doc/src/qtnetworkauth-twittertimeline.qdoc
new file mode 100644
index 0000000..7346f55
--- /dev/null
+++ b/examples/oauth/twittertimeline/doc/src/qtnetworkauth-twittertimeline.qdoc
@@ -0,0 +1,44 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \example twittertimeline
+ \title Twitter Timeline Example
+ \ingroup examples-qtnetworkauth
+ \brief Demonstrates authenticating with OAuth to access a Twitter timeline.
+
+ \image twittertimeline-example.png Screenshot of the example
+
+ The \e {Twitter Timeline} example uses OAuth, as supported by
+ \l {Qt Network Authorization}, to sign in to Twitter and display a timeline
+ of tweets (in text format) associated with the authenticated user.
+
+ To use this example, a consumer key and secret from Twitter are needed.
+ To register the application visit https://apps.twitter.com.
+
+ \include examples-run.qdocinc
+*/
diff --git a/examples/oauth/twittertimeline/main.cpp b/examples/oauth/twittertimeline/main.cpp
new file mode 100644
index 0000000..da8a69e
--- /dev/null
+++ b/examples/oauth/twittertimeline/main.cpp
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "ui_twitterdialog.h"
+#include "twittertimelinemodel.h"
+
+#include <functional>
+
+#include <QUrl>
+#include <QProcess>
+#include <QApplication>
+#include <QNetworkReply>
+#include <QNetworkRequest>
+#include <QCommandLineParser>
+#include <QCommandLineOption>
+
+int main(int argc, char **argv)
+{
+ QApplication app(argc, argv);
+
+ app.setApplicationName("Twitter Timeline");
+ app.setApplicationDisplayName("Twitter Timeline");
+ app.setOrganizationDomain("qt.io");
+ app.setOrganizationName("The Qt Company");
+
+ QCommandLineParser parser;
+ QCommandLineOption token(QStringList() << "k" << "consumer-key",
+ "Application consumer key", "key");
+ QCommandLineOption secret(QStringList() << "s" << "consumer-secret",
+ "Application consumer secret", "secret");
+ QCommandLineOption connect(QStringList() << "c" << "connect",
+ "Connects to twitter. Requires consumer-key and consumer-secret");
+
+ parser.addOptions({ token, secret, connect });
+ parser.process(app);
+
+ struct TwitterDialog : QDialog, Ui::TwitterDialog {
+ TwitterTimelineModel model;
+
+ TwitterDialog()
+ : QDialog()
+ {
+ setupUi(this);
+ view->setModel(&model);
+ view->horizontalHeader()->hideSection(0);
+ view->horizontalHeader()->hideSection(1);
+ }
+ } twitterDialog;
+
+ const auto authenticate = [&]() {
+ const auto clientIdentifier = twitterDialog.clientIdLineEdit->text();
+ const auto clientSharedSecret = twitterDialog.clientSecretLineEdit->text();
+ twitterDialog.model.authenticate(qMakePair(clientIdentifier, clientSharedSecret));
+ };
+ const auto buttonSlot = [&]() {
+ if (twitterDialog.model.status() == Twitter::Status::Granted)
+ twitterDialog.model.updateTimeline();
+ else
+ authenticate();
+ };
+
+ twitterDialog.clientIdLineEdit->setText(parser.value(token));
+ twitterDialog.clientSecretLineEdit->setText(parser.value(secret));
+ if (parser.isSet(connect)) {
+ if (parser.value(token).isEmpty() || parser.value(secret).isEmpty()) {
+ parser.showHelp();
+ } else {
+ authenticate();
+ twitterDialog.view->setFocus();
+ }
+ }
+
+ QObject::connect(twitterDialog.pushButton, &QPushButton::clicked, buttonSlot);
+ QObject::connect(&twitterDialog.model, &TwitterTimelineModel::authenticated,
+ std::bind(&QPushButton::setText, twitterDialog.pushButton, "&Update"));
+
+ twitterDialog.show();
+ return app.exec();
+}
diff --git a/examples/oauth/twittertimeline/twitter.cpp b/examples/oauth/twittertimeline/twitter.cpp
new file mode 100644
index 0000000..04a6a46
--- /dev/null
+++ b/examples/oauth/twittertimeline/twitter.cpp
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "twitter.h"
+
+#include <QtGui>
+#include <QtCore>
+#include <QtNetwork>
+
+Twitter::Twitter(QObject *parent) :
+ Twitter(QString(), qMakePair(QString(), QString()), parent)
+{}
+
+Twitter::Twitter(const QPair<QString, QString> &clientCredentials, QObject *parent) :
+ Twitter(QString(), clientCredentials, parent)
+{}
+
+Twitter::Twitter(const QString &screenName,
+ const QPair<QString, QString> &clientCredentials,
+ QObject *parent) :
+ QOAuth1(clientCredentials.first, clientCredentials.second, nullptr, parent)
+{
+ replyHandler = new QOAuthHttpServerReplyHandler(this);
+ setReplyHandler(replyHandler);
+ setTemporaryCredentialsUrl(QUrl("https://api.twitter.com/oauth/request_token"));
+ setAuthorizationUrl(QUrl("https://api.twitter.com/oauth/authenticate"));
+ setTokenCredentialsUrl(QUrl("https://api.twitter.com/oauth/access_token"));
+
+ connect(this, &QAbstractOAuth::authorizeWithBrowser, [=](QUrl url) {
+ QUrlQuery query(url);
+
+ // Forces the user to enter their credentials to authorize the correct
+ // user account
+ query.addQueryItem("force_login", "true");
+
+ if (!screenName.isEmpty())
+ query.addQueryItem("screen_name", screenName);
+ url.setQuery(query);
+ QDesktopServices::openUrl(url);
+ });
+
+ connect(this, &QOAuth1::granted, this, &Twitter::authenticated);
+
+ if (!clientCredentials.first.isEmpty() && !clientCredentials.second.isEmpty())
+ grant();
+}
diff --git a/examples/oauth/twittertimeline/twitter.h b/examples/oauth/twittertimeline/twitter.h
new file mode 100644
index 0000000..74dfc72
--- /dev/null
+++ b/examples/oauth/twittertimeline/twitter.h
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore>
+#include <QtNetwork>
+#include <QtNetworkAuth>
+
+class Twitter : public QOAuth1
+{
+ Q_OBJECT
+
+public:
+ Twitter(QObject *parent = nullptr);
+ Twitter(const QPair<QString, QString> &clientCredentials, QObject *parent = nullptr);
+ Twitter(const QString &screenName,
+ const QPair<QString, QString> &clientCredentials,
+ QObject *parent = nullptr);
+
+signals:
+ void authenticated();
+
+private:
+ Q_DISABLE_COPY(Twitter)
+
+ QOAuthHttpServerReplyHandler *replyHandler = nullptr;
+};
diff --git a/examples/oauth/twittertimeline/twitterdialog.ui b/examples/oauth/twittertimeline/twitterdialog.ui
new file mode 100644
index 0000000..d8be245
--- /dev/null
+++ b/examples/oauth/twittertimeline/twitterdialog.ui
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>TwitterDialog</class>
+ <widget class="QDialog" name="TwitterDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>800</width>
+ <height>600</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Twitter Timeline</string>
+ </property>
+ <layout class="QFormLayout" name="formLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="clientIdLabel">
+ <property name="text">
+ <string>C&amp;lient Id:</string>
+ </property>
+ <property name="buddy">
+ <cstring>clientIdLineEdit</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="clientIdLineEdit"/>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="clientSecretLabel">
+ <property name="text">
+ <string>Client &amp;secret:</string>
+ </property>
+ <property name="buddy">
+ <cstring>clientSecretLineEdit</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="clientSecretLineEdit"/>
+ </item>
+ <item row="2" column="0" colspan="2">
+ <widget class="QPushButton" name="pushButton">
+ <property name="text">
+ <string>&amp;Connect</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0" colspan="2">
+ <widget class="QTableView" name="view">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>1</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="selectionMode">
+ <enum>QAbstractItemView::NoSelection</enum>
+ </property>
+ <attribute name="horizontalHeaderStretchLastSection">
+ <bool>true</bool>
+ </attribute>
+ <attribute name="verticalHeaderVisible">
+ <bool>false</bool>
+ </attribute>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/examples/oauth/twittertimeline/twittertimeline.pro b/examples/oauth/twittertimeline/twittertimeline.pro
new file mode 100644
index 0000000..4448979
--- /dev/null
+++ b/examples/oauth/twittertimeline/twittertimeline.pro
@@ -0,0 +1,18 @@
+QT = core widgets network networkauth
+CONFIG -= app_bundle
+
+HEADERS += \
+ twitter.h \
+ twittertimelinemodel.h
+
+SOURCES += \
+ main.cpp \
+ twitter.cpp \
+ twittertimelinemodel.cpp
+
+FORMS += \
+ twitterdialog.ui
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/oauth/twittertimeline
+INSTALLS += target
diff --git a/examples/oauth/twittertimeline/twittertimelinemodel.cpp b/examples/oauth/twittertimeline/twittertimelinemodel.cpp
new file mode 100644
index 0000000..6aa4ef2
--- /dev/null
+++ b/examples/oauth/twittertimeline/twittertimelinemodel.cpp
@@ -0,0 +1,188 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "twittertimelinemodel.h"
+
+#include <QtGui>
+#include <QtCore>
+#include <QtWidgets>
+
+TwitterTimelineModel::TwitterTimelineModel(QObject *parent) : QAbstractTableModel(parent)
+{
+ connect(&twitter, &Twitter::authenticated, this, &TwitterTimelineModel::authenticated);
+ connect(&twitter, &Twitter::authenticated, this, &TwitterTimelineModel::updateTimeline);
+}
+
+int TwitterTimelineModel::rowCount(const QModelIndex &parent) const
+{
+#if defined(QT_DEBUG)
+ Q_ASSERT(!parent.isValid());
+#else
+ Q_UNUSED(parent)
+#endif
+ return tweets.size();
+}
+
+QVariant TwitterTimelineModel::data(const QModelIndex &index, int role) const
+{
+ if (role != Qt::DisplayRole)
+ return QVariant();
+
+ auto it = tweets.begin();
+ std::advance(it, index.row());
+ switch (index.column())
+ {
+ case 0:
+ return QString::number(it->id);
+ case 1:
+ return it->createdAt.toString(Qt::SystemLocaleShortDate);
+ case 2:
+ return it->user;
+ case 3:
+ return it->text;
+ }
+ return QVariant();
+}
+
+int TwitterTimelineModel::columnCount(const QModelIndex &) const
+{
+ return 4;
+}
+
+QVariant TwitterTimelineModel::headerData(int section, Qt::Orientation orientation, int role) const
+{
+ if (role != Qt::DisplayRole)
+ return QVariant();
+
+ if (orientation == Qt::Horizontal) {
+ switch (section) {
+ case 0:
+ return QStringLiteral("Id");
+ case 1:
+ return QStringLiteral("Created at");
+ case 2:
+ return QStringLiteral("User");
+ case 3:
+ return QStringLiteral("Text");
+ }
+ }
+ return section;
+}
+
+void TwitterTimelineModel::authenticate(const QPair<QString, QString> &clientCredentials)
+{
+ twitter.setClientCredentials(clientCredentials);
+ twitter.grant();
+}
+
+QAbstractOAuth::Status TwitterTimelineModel::status() const
+{
+ return twitter.status();
+}
+
+void TwitterTimelineModel::updateTimeline()
+{
+ if (twitter.status() != Twitter::Status::Granted)
+ QMessageBox::warning(nullptr, qApp->applicationName(), "Not authenticated");
+
+ QUrl url("https://api.twitter.com/1.1/statuses/home_timeline.json");
+ QUrlQuery query;
+ if (tweets.size()) {
+ // Tweets are time-ordered, newest first. Pass the most recent
+ // ID we have to request everything more recent than it:
+ query.addQueryItem("since_id", QString::number(tweets.first().id));
+ // From https://dev.twitter.com/rest/reference/get/search/tweets:
+ // Returns results with an ID greater than (that is, more recent than)
+ // the specified ID. There are limits to the number of Tweets which can
+ // be accessed through the API. If the limit of Tweets has occurred
+ // since the since_id, the since_id will be forced to the oldest ID
+ // available.
+ }
+ url.setQuery(query);
+ QNetworkReply *reply = twitter.get(url);
+ connect(reply, &QNetworkReply::finished, this, &TwitterTimelineModel::parseJson);
+}
+
+void TwitterTimelineModel::parseJson()
+{
+ QJsonParseError parseError;
+ auto reply = qobject_cast<QNetworkReply*>(sender());
+ Q_ASSERT(reply);
+ const auto data = reply->readAll();
+ const auto document = QJsonDocument::fromJson(data, &parseError);
+ if (parseError.error) {
+ qCritical() << "TwitterTimelineModel::parseJson. Error at:" << parseError.offset
+ << parseError.errorString();
+ return;
+ } else if (document.isObject()) {
+ // Error received :(
+ const auto object = document.object();
+ const auto errorArray = object.value("errors").toArray();
+ Q_ASSERT_X(errorArray.size(), "parse", data);
+ QStringList errors;
+ for (const auto error : errorArray) {
+ Q_ASSERT(error.isObject());
+ Q_ASSERT(error.toObject().contains("message"));
+ errors.append(error.toObject().value("message").toString());
+ }
+ QMessageBox::warning(nullptr, qApp->applicationName(), errors.join("<br />"));
+ return;
+ }
+
+ Q_ASSERT_X(document.isArray(), "parse", data);
+ const auto array = document.array();
+ if (array.size()) {
+ beginInsertRows(QModelIndex(), 0, array.size() - 1);
+ auto before = tweets.begin();
+ for (const auto &value : array) {
+ Q_ASSERT(value.isObject());
+ const auto object = value.toObject();
+ const auto createdAt = QDateTime::fromString(object.value("created_at").toString(),
+ "ddd MMM dd HH:mm:ss +0000 yyyy");
+ before = tweets.insert(before, Tweet{
+ object.value("id").toVariant().toULongLong(),
+ createdAt,
+ object.value("user").toObject().value("name").toString(),
+ object.value("text").toString()
+ });
+ std::advance(before, 1);
+ }
+ endInsertRows();
+ }
+}
diff --git a/examples/oauth/twittertimeline/twittertimelinemodel.h b/examples/oauth/twittertimeline/twittertimelinemodel.h
new file mode 100644
index 0000000..63ba0a4
--- /dev/null
+++ b/examples/oauth/twittertimeline/twittertimelinemodel.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "twitter.h"
+
+#include <QtCore>
+#include <QtNetwork>
+
+class TwitterTimelineModel : public QAbstractTableModel
+{
+ Q_OBJECT
+
+public:
+ TwitterTimelineModel(QObject *parent = nullptr);
+
+ int rowCount(const QModelIndex &parent) const override;
+ QVariant data(const QModelIndex &index, int role) const override;
+ int columnCount(const QModelIndex &parent) const override;
+ QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
+
+ void authenticate(const QPair<QString, QString> &clientCredentials);
+ QAbstractOAuth::Status status() const;
+
+public slots:
+ void updateTimeline();
+
+signals:
+ void authenticated();
+
+private:
+ Q_DISABLE_COPY(TwitterTimelineModel)
+
+ void parseJson();
+
+ struct Tweet {
+ quint64 id;
+ QDateTime createdAt;
+ QString user;
+ QString text;
+ };
+
+ QList<Tweet> tweets;
+ Twitter twitter;
+};