diff options
author | Tomaz Canabrava <tomaz.canabrava@intel.com> | 2015-11-08 10:33:29 -0200 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2015-11-08 09:43:35 -0800 |
commit | 70e6840d51d876b4d906f3af0a4be71bd3233e48 (patch) | |
tree | f260b0f9d454099ea12202255e8a1e726bb187a4 | |
parent | 440423ff6476119e090798ae2d59dc59d5253a0a (diff) | |
download | subsurface-70e6840d51d876b4d906f3af0a4be71bd3233e48.tar.gz |
Convert most of the old code for FacebookPlugin to the new System
It should still not work correctly - but the plugin should be almost
ready - I'll do some papercuts on the next few commits.
Signed-off-by: Tomaz Canabrava <tomaz.canabrava@intel.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
-rw-r--r-- | desktop-widgets/plugins/facebook/CMakeLists.txt | 3 | ||||
-rw-r--r-- | desktop-widgets/plugins/facebook/facebookconnectwidget.cpp | 328 | ||||
-rw-r--r-- | desktop-widgets/plugins/facebook/facebookconnectwidget.h | 61 | ||||
-rw-r--r-- | desktop-widgets/plugins/facebook/facebookconnectwidget.ui | 104 | ||||
-rw-r--r-- | desktop-widgets/plugins/facebook/socialnetworksdialog.ui (renamed from desktop-widgets/socialnetworksdialog.ui) | 0 |
5 files changed, 495 insertions, 1 deletions
diff --git a/desktop-widgets/plugins/facebook/CMakeLists.txt b/desktop-widgets/plugins/facebook/CMakeLists.txt index 8628bd070..82a6c7799 100644 --- a/desktop-widgets/plugins/facebook/CMakeLists.txt +++ b/desktop-widgets/plugins/facebook/CMakeLists.txt @@ -1,4 +1,5 @@ -set(FACEBOOK_PLUGIN_SRCS facebook_integration.cpp) +set(FACEBOOK_PLUGIN_SRCS facebook_integration.cpp facebookconnectwidget.cpp) +include_directories(${CMAKE_CURRENT_BINARY_DIR}) add_library(facebook_integration SHARED ${FACEBOOK_PLUGIN_SRCS}) diff --git a/desktop-widgets/plugins/facebook/facebookconnectwidget.cpp b/desktop-widgets/plugins/facebook/facebookconnectwidget.cpp new file mode 100644 index 000000000..1f2e1b09d --- /dev/null +++ b/desktop-widgets/plugins/facebook/facebookconnectwidget.cpp @@ -0,0 +1,328 @@ +#include "facebookconnectwidget.h" + +#include <QJsonDocument> +#include <QJsonArray> +#include <QJsonObject> +#include <QNetworkReply> +#include <QNetworkRequest> +#include <QNetworkAccessManager> +#include <QNetworkCookieJar> + +#include <QUrlQuery> +#include <QEventLoop> +#include <QHttpMultiPart> +#include <QSettings> +#include <QFile> +#include <QBuffer> +#include <QDebug> +#include <QMessageBox> +#include <QInputDialog> +#include <QWebView> + +#include "mainwindow.h" +#include "profile-widget/profilewidget2.h" +#include "pref.h" +#include "helpers.h" +#include "ui_socialnetworksdialog.h" +#include "ui_facebookconnectwidget.h" + +#if SAVE_FB_CREDENTIALS +#define GET_TXT(name, field) \ + v = s.value(QString(name)); \ + if (v.isValid()) \ + prefs.field = strdup(v.toString().toUtf8().constData()); \ + else \ + prefs.field = default_prefs.field +#endif + +FacebookManager *FacebookManager::instance() +{ + static FacebookManager *self = new FacebookManager(); + return self; +} + +FacebookManager::FacebookManager(QObject *parent) : QObject(parent) +{ + sync(); +} + +QUrl FacebookManager::connectUrl() { + return QUrl("https://www.facebook.com/dialog/oauth?" + "client_id=427722490709000" + "&redirect_uri=http://www.facebook.com/connect/login_success.html" + "&response_type=token,granted_scopes" + "&display=popup" + "&scope=publish_actions,user_photos" + ); +} + +bool FacebookManager::loggedIn() { + return prefs.facebook.access_token != NULL; +} + +void FacebookManager::sync() +{ +#if SAVE_FB_CREDENTIALS + QSettings s; + s.beginGroup("WebApps"); + s.beginGroup("Facebook"); + + QVariant v; + GET_TXT("ConnectToken", facebook.access_token); + GET_TXT("UserId", facebook.user_id); + GET_TXT("AlbumId", facebook.album_id); +#endif +} + +void FacebookManager::tryLogin(const QUrl& loginResponse) +{ + QString result = loginResponse.toString(); + if (!result.contains("access_token")) + return; + + if (result.contains("denied_scopes=publish_actions") || result.contains("denied_scopes=user_photos")) { + qDebug() << "user did not allow us access" << result; + return; + } + int from = result.indexOf("access_token=") + strlen("access_token="); + int to = result.indexOf("&expires_in"); + QString securityToken = result.mid(from, to-from); + +#if SAVE_FB_CREDENTIALS + QSettings settings; + settings.beginGroup("WebApps"); + settings.beginGroup("Facebook"); + settings.setValue("ConnectToken", securityToken); + sync(); +#else + prefs.facebook.access_token = copy_string(securityToken.toUtf8().data()); +#endif + requestUserId(); + sync(); + emit justLoggedIn(true); +} + +void FacebookManager::logout() +{ +#if SAVE_FB_CREDENTIALS + QSettings settings; + settings.beginGroup("WebApps"); + settings.beginGroup("Facebook"); + settings.remove("ConnectToken"); + settings.remove("UserId"); + settings.remove("AlbumId"); + sync(); +#else + free(prefs.facebook.access_token); + free(prefs.facebook.album_id); + free(prefs.facebook.user_id); + prefs.facebook.access_token = NULL; + prefs.facebook.album_id = NULL; + prefs.facebook.user_id = NULL; +#endif + emit justLoggedOut(true); +} + +void FacebookManager::requestAlbumId() +{ + QUrl albumListUrl("https://graph.facebook.com/me/albums?access_token=" + QString(prefs.facebook.access_token)); + QNetworkAccessManager *manager = new QNetworkAccessManager(); + QNetworkReply *reply = manager->get(QNetworkRequest(albumListUrl)); + + QEventLoop loop; + connect(reply, SIGNAL(finished()), &loop, SLOT(quit())); + loop.exec(); + +#if SAVE_FB_CREDENTIALS + QSettings s; + s.beginGroup("WebApps"); + s.beginGroup("Facebook"); +#endif + + QJsonDocument albumsDoc = QJsonDocument::fromJson(reply->readAll()); + QJsonArray albumObj = albumsDoc.object().value("data").toArray(); + foreach(const QJsonValue &v, albumObj){ + QJsonObject obj = v.toObject(); + if (obj.value("name").toString() == albumName) { +#if SAVE_FB_CREDENTIALS + s.setValue("AlbumId", obj.value("id").toString()); +#else + prefs.facebook.album_id = copy_string(obj.value("id").toString().toUtf8().data()); +#endif + return; + } + } + + QUrlQuery params; + params.addQueryItem("name", albumName ); + params.addQueryItem("description", "Subsurface Album"); + params.addQueryItem("privacy", "{'value': 'SELF'}"); + + QNetworkRequest request(albumListUrl); + request.setHeader(QNetworkRequest::ContentTypeHeader, "application/octet-stream"); + reply = manager->post(request, params.query().toLocal8Bit()); + connect(reply, SIGNAL(finished()), &loop, SLOT(quit())); + loop.exec(); + + albumsDoc = QJsonDocument::fromJson(reply->readAll()); + QJsonObject album = albumsDoc.object(); + if (album.contains("id")) { +#if SAVE_FB_CREDENTIALS + s.setValue("AlbumId", album.value("id").toString()); +#else + prefs.facebook.album_id = copy_string(album.value("id").toString().toUtf8().data()); +#endif + sync(); + return; + } +} + +void FacebookManager::requestUserId() +{ + QUrl userIdRequest("https://graph.facebook.com/me?fields=id&access_token=" + QString(prefs.facebook.access_token)); + QNetworkAccessManager *getUserID = new QNetworkAccessManager(); + QNetworkReply *reply = getUserID->get(QNetworkRequest(userIdRequest)); + + QEventLoop loop; + connect(reply, SIGNAL(finished()), &loop, SLOT(quit())); + loop.exec(); + + QJsonDocument jsonDoc = QJsonDocument::fromJson(reply->readAll()); + QJsonObject obj = jsonDoc.object(); + if (obj.keys().contains("id")){ +#if SAVE_FB_CREDENTIALS + QSettings s; + s.beginGroup("WebApps"); + s.beginGroup("Facebook"); + s.setValue("UserId", obj.value("id").toVariant()); +#else + prefs.facebook.user_id = copy_string(obj.value("id").toString().toUtf8().data()); +#endif + return; + } +} + +void FacebookManager::setDesiredAlbumName(const QString& a) +{ + albumName = a; +} + +/* to be changed to export the currently selected dive as shown on the profile. + * Much much easier, and its also good to people do not select all the dives + * and send erroniously *all* of them to facebook. */ +void FacebookManager::sendDive() +{ + SocialNetworkDialog dialog(qApp->activeWindow()); + if (dialog.exec() != QDialog::Accepted) + return; + + setDesiredAlbumName(dialog.album()); + requestAlbumId(); + + ProfileWidget2 *profile = MainWindow::instance()->graphics(); + profile->setToolTipVisibile(false); + QPixmap pix = QPixmap::grabWidget(profile); + profile->setToolTipVisibile(true); + QByteArray bytes; + QBuffer buffer(&bytes); + buffer.open(QIODevice::WriteOnly); + pix.save(&buffer, "PNG"); + QUrl url("https://graph.facebook.com/v2.2/" + QString(prefs.facebook.album_id) + "/photos?" + + "&access_token=" + QString(prefs.facebook.access_token) + + "&source=image" + + "&message=" + dialog.text().replace(""", "%22")); + + QNetworkAccessManager *am = new QNetworkAccessManager(this); + QNetworkRequest request(url); + + QString bound="margin"; + + //according to rfc 1867 we need to put this string here: + QByteArray data(QString("--" + bound + "\r\n").toLocal8Bit()); + data.append("Content-Disposition: form-data; name=\"action\"\r\n\r\n"); + data.append("https://graph.facebook.com/v2.2/\r\n"); + data.append("--" + bound + "\r\n"); //according to rfc 1867 + data.append("Content-Disposition: form-data; name=\"uploaded\"; filename=\"" + QString::number(qrand()) + ".png\"\r\n"); //name of the input is "uploaded" in my form, next one is a file name. + data.append("Content-Type: image/jpeg\r\n\r\n"); //data type + data.append(bytes); //let's read the file + data.append("\r\n"); + data.append("--" + bound + "--\r\n"); //closing boundary according to rfc 1867 + + request.setRawHeader(QString("Content-Type").toLocal8Bit(),QString("multipart/form-data; boundary=" + bound).toLocal8Bit()); + request.setRawHeader(QString("Content-Length").toLocal8Bit(), QString::number(data.length()).toLocal8Bit()); + QNetworkReply *reply = am->post(request,data); + + QEventLoop loop; + connect(reply, SIGNAL(finished()), &loop, SLOT(quit())); + loop.exec(); + + QByteArray response = reply->readAll(); + QJsonDocument jsonDoc = QJsonDocument::fromJson(response); + QJsonObject obj = jsonDoc.object(); + if (obj.keys().contains("id")){ + QMessageBox::information(qApp->activeWindow(), + tr("Photo upload sucessfull"), + tr("Your dive profile was updated to Facebook."), + QMessageBox::Ok); + } else { + QMessageBox::information(qApp->activeWindow(), + tr("Photo upload failed"), + tr("Your dive profile was not updated to Facebook, \n " + "please send the following to the developer. \n" + + response), + QMessageBox::Ok); + } +} + +FacebookConnectWidget::FacebookConnectWidget(QWidget *parent) : QDialog(parent), ui(new Ui::FacebookConnectWidget) { + FacebookManager *fb = FacebookManager::instance(); + facebookWebView = new QWebView(this); + ui->fbWebviewContainer->layout()->addWidget(facebookWebView); + if (fb->loggedIn()) { + facebookLoggedIn(); + } else { + facebookDisconnect(); + } + connect(facebookWebView, &QWebView::urlChanged, fb, &FacebookManager::tryLogin); + connect(fb, &FacebookManager::justLoggedIn, this, &FacebookConnectWidget::facebookLoggedIn); +} + +void FacebookConnectWidget::facebookLoggedIn() +{ + ui->fbWebviewContainer->hide(); + ui->fbWebviewContainer->setEnabled(false); + ui->FBLabel->setText(tr("To disconnect Subsurface from your Facebook account, use the button below")); +} + +void FacebookConnectWidget::facebookDisconnect() +{ + // remove the connect/disconnect button + // and instead add the login view + ui->fbWebviewContainer->show(); + ui->fbWebviewContainer->setEnabled(true); + ui->FBLabel->setText(tr("To connect to Facebook, please log in. This enables Subsurface to publish dives to your timeline")); + if (facebookWebView) { + facebookWebView->page()->networkAccessManager()->setCookieJar(new QNetworkCookieJar()); + facebookWebView->setUrl(FacebookManager::instance()->connectUrl()); + } +} + +SocialNetworkDialog::SocialNetworkDialog(QWidget* parent, Qt::WindowFlags f): QDialog(parent, f) +{ + +} + +QString SocialNetworkDialog::name() const +{ + return _name; +} + +QString SocialNetworkDialog::album() const +{ + return _album; +} + +QString SocialNetworkDialog::text() const +{ + return _text; +} diff --git a/desktop-widgets/plugins/facebook/facebookconnectwidget.h b/desktop-widgets/plugins/facebook/facebookconnectwidget.h new file mode 100644 index 000000000..4802b9f63 --- /dev/null +++ b/desktop-widgets/plugins/facebook/facebookconnectwidget.h @@ -0,0 +1,61 @@ +#ifndef FACEBOOKCONNECTWIDGET_H +#define FACEBOOKCONNECTWIDGET_H + +#include <QDialog> +class QWebView; +namespace Ui { + class FacebookConnectWidget; +} + +class FacebookManager : public QObject +{ + Q_OBJECT +public: + static FacebookManager *instance(); + void requestAlbumId(); + void requestUserId(); + void sync(); + QUrl connectUrl(); + bool loggedIn(); +signals: + void justLoggedIn(bool triggererd); + void justLoggedOut(bool triggered); + +public slots: + void tryLogin(const QUrl& loginResponse); + void logout(); + void setDesiredAlbumName(const QString& albumName); + void sendDive(); + +private: + explicit FacebookManager(QObject *parent = 0); + QString albumName; +}; + + +class FacebookConnectWidget : public QDialog { + Q_OBJECT +public: + explicit FacebookConnectWidget(QWidget* parent = 0); + void facebookLoggedIn(); + void facebookDisconnect(); +private: + Ui::FacebookConnectWidget *ui; + QWebView *facebookWebView; +}; + +class SocialNetworkDialog : public QDialog { + Q_OBJECT +public: + explicit SocialNetworkDialog(QWidget* parent = 0, Qt::WindowFlags f = 0); + QString album() const; + QString name() const; + QString text() const; + +private: + QString _album; + QString _name; + QString _text; +}; + +#endif
\ No newline at end of file diff --git a/desktop-widgets/plugins/facebook/facebookconnectwidget.ui b/desktop-widgets/plugins/facebook/facebookconnectwidget.ui new file mode 100644 index 000000000..e34dfb198 --- /dev/null +++ b/desktop-widgets/plugins/facebook/facebookconnectwidget.ui @@ -0,0 +1,104 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>FacebookConnectWidget</class> + <widget class="QDialog" name="FacebookConnectWidget"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>835</width> + <height>698</height> + </rect> + </property> + <property name="windowTitle"> + <string>Preferences</string> + </property> + <property name="windowIcon"> + <iconset> + <normalon>:/subsurface-icon</normalon> + </iconset> + </property> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <property name="leftMargin"> + <number>5</number> + </property> + <property name="topMargin"> + <number>5</number> + </property> + <property name="rightMargin"> + <number>5</number> + </property> + <property name="bottomMargin"> + <number>5</number> + </property> + <item> + <layout class="QHBoxLayout" name="mainHorizontalLayout"> + <item> + <widget class="QStackedWidget" name="stackedWidget"> + <property name="sizePolicy"> + <sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="currentIndex"> + <number>0</number> + </property> + <widget class="QWidget" name="facebook_page"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <layout class="QVBoxLayout" name="fbLayout" stretch="0"> + <property name="spacing"> + <number>5</number> + </property> + <property name="leftMargin"> + <number>5</number> + </property> + <property name="topMargin"> + <number>5</number> + </property> + <property name="rightMargin"> + <number>5</number> + </property> + <property name="bottomMargin"> + <number>5</number> + </property> + <item> + <widget class="QWidget" name="widget" native="true"> + <layout class="QVBoxLayout" name="verticalLayout_9"> + <item> + <widget class="QLabel" name="FBLabel"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Connect to facebook text placeholder</string> + </property> + </widget> + </item> + <item> + <widget class="QWidget" name="fbWebviewContainer" native="true"> + <layout class="QVBoxLayout" name="verticalLayout_10"/> + </widget> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> diff --git a/desktop-widgets/socialnetworksdialog.ui b/desktop-widgets/plugins/facebook/socialnetworksdialog.ui index e8953d1c7..e8953d1c7 100644 --- a/desktop-widgets/socialnetworksdialog.ui +++ b/desktop-widgets/plugins/facebook/socialnetworksdialog.ui |