summaryrefslogtreecommitdiffstats
path: root/desktop-widgets/plugins/facebook/facebookconnectwidget.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'desktop-widgets/plugins/facebook/facebookconnectwidget.cpp')
-rw-r--r--desktop-widgets/plugins/facebook/facebookconnectwidget.cpp421
1 files changed, 0 insertions, 421 deletions
diff --git a/desktop-widgets/plugins/facebook/facebookconnectwidget.cpp b/desktop-widgets/plugins/facebook/facebookconnectwidget.cpp
deleted file mode 100644
index 7a497e218..000000000
--- a/desktop-widgets/plugins/facebook/facebookconnectwidget.cpp
+++ /dev/null
@@ -1,421 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#include "facebookconnectwidget.h"
-
-#include <QJsonDocument>
-#include <QJsonArray>
-#include <QJsonObject>
-#include <QNetworkReply>
-#include <QNetworkRequest>
-#include <QNetworkAccessManager>
-#include <QNetworkCookieJar>
-
-#include <QUrlQuery>
-#include <QHttpMultiPart>
-#include <QFile>
-#include <QBuffer>
-#include <QDebug>
-#include <QMessageBox>
-#include <QInputDialog>
-#include <QLoggingCategory>
-#ifdef USE_WEBENGINE
-#include <QWebEngineView>
-#else
-#include <QWebView>
-#endif
-#include "mainwindow.h"
-#include "profile-widget/profilewidget2.h"
-
-#include "core/pref.h"
-#include "core/qthelper.h"
-#include "core/settings/qPrefFacebook.h"
-
-#include "ui_socialnetworksdialog.h"
-#include "ui_facebookconnectwidget.h"
-
-Q_LOGGING_CATEGORY(lcFacebook, "subsurface.facebook")
-
-FacebookManager *FacebookManager::instance()
-{
- static FacebookManager *self = new FacebookManager();
- return self;
-}
-
-FacebookManager::FacebookManager(QObject *parent) :
- QObject(parent),
- manager(new QNetworkAccessManager(this))
-{
- // log only in verbose mode
- QLoggingCategory::setFilterRules(QStringLiteral("subsurface.facebook=%1").arg(verbose ? "true" : "false"));
- connect(this, &FacebookManager::albumIdReceived, this, &FacebookManager::sendDiveToAlbum);
-}
-
-static QString graphApi = QStringLiteral("https://graph.facebook.com/v2.10/");
-
-QUrl FacebookManager::albumListUrl()
-{
- return QUrl("https://graph.facebook.com/me/albums?access_token=" + QString(prefs.facebook.access_token));
-}
-
-QUrl FacebookManager::connectUrl() {
- return QUrl("https://www.facebook.com/dialog/oauth?"
- "client_id=427722490709000"
- "&redirect_uri=https://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::tryLogin(const QUrl& loginResponse)
-{
- qCDebug(lcFacebook) << "Current url call" << loginResponse;
- QString result = loginResponse.toString();
- if (!result.contains("access_token")) {
- qCDebug(lcFacebook) << "Response without access token!";
- return;
- }
-
- if (result.contains("denied_scopes=publish_actions") || result.contains("denied_scopes=user_photos")) {
- qCDebug(lcFacebook) << "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);
-
- qPrefFacebook::set_access_token(securityToken);
- qCDebug(lcFacebook) << "Got securityToken" << securityToken;
- requestUserId();
-}
-
-void FacebookManager::logout()
-{
- qPrefFacebook::set_access_token(QString());
- qPrefFacebook::set_user_id(QString());
- qPrefFacebook::set_album_id(QString());
- emit justLoggedOut(true);
-}
-
-void FacebookManager::requestAlbumId()
-{
- qCDebug(lcFacebook) << "Starting to request the album id" << albumListUrl();
- QNetworkReply *reply = manager->get(QNetworkRequest(albumListUrl()));
- connect(reply, &QNetworkReply::finished, this, &FacebookManager::albumListReceived);
-}
-
-void FacebookManager::albumListReceived()
-{
- qCDebug(lcFacebook) << "Reply for the album id";
- QNetworkReply *reply = qobject_cast<QNetworkReply*>(sender());
- QJsonDocument albumsDoc = QJsonDocument::fromJson(reply->readAll());
- QJsonArray albumObj = albumsDoc.object().value("data").toArray();
-
- reply->deleteLater();
- foreach(const QJsonValue &v, albumObj){
- QJsonObject obj = v.toObject();
- if (obj.value("name").toString() == fbInfo.albumName) {
- qPrefFacebook::set_album_id(obj.value("id").toString());
- qCDebug(lcFacebook) << "Album" << fbInfo.albumName << "already exists, using id" << obj.value("id").toString();
- emit albumIdReceived(qPrefFacebook::album_id());
- return;
- }
- }
-
- // No album with the name we requested, create a new one.
- createFacebookAlbum();
-}
-
-void FacebookManager::createFacebookAlbum()
-{
- qCDebug(lcFacebook) << "Album with name" << fbInfo.albumName << "doesn't exists, creating it.";
- QUrlQuery params;
- params.addQueryItem("name", fbInfo.albumName );
- params.addQueryItem("description", "Subsurface Album");
- params.addQueryItem("privacy", "{'value': 'SELF'}");
-
- QNetworkRequest request(albumListUrl());
- request.setHeader(QNetworkRequest::ContentTypeHeader, "application/octet-stream");
-
- QNetworkReply *reply = manager->post(request, params.query().toUtf8());
- connect(reply, &QNetworkReply::finished, this, &FacebookManager::facebookAlbumCreated);
-}
-
-void FacebookManager::facebookAlbumCreated()
-{
- QNetworkReply *reply = qobject_cast<QNetworkReply*>(sender());
- QJsonDocument albumsDoc = QJsonDocument::fromJson(reply->readAll());
- QJsonObject album = albumsDoc.object();
-
- reply->deleteLater();
-
- if (album.contains("id")) {
- qCDebug(lcFacebook) << "Album" << fbInfo.albumName << "created successfully with id" << album.value("id").toString();
- qPrefFacebook::set_album_id(album.value("id").toString());
- emit albumIdReceived(qPrefFacebook::album_id());
- return;
- } else {
- qCDebug(lcFacebook) << "It was not possible to create the album with name" << fbInfo.albumName;
- qCDebug(lcFacebook).noquote() << "Reply was: " << QString(albumsDoc.toJson(QJsonDocument::Indented));
- // FIXME: we are lacking 'user_photos' facebook permission to create an album,
- // but we are able to upload the image to Facebook (album will be named 'Subsurface Photos')
- qCDebug(lcFacebook) << "But we are still able to upload data. Album name will be 'Subsurface Photos'";
- emit albumIdReceived(qPrefFacebook::album_id());
- }
-}
-
-void FacebookManager::requestUserId()
-{
- qCDebug(lcFacebook) << "Requesting user id";
- QUrl userIdRequest("https://graph.facebook.com/me?fields=id&access_token=" + QString(prefs.facebook.access_token));
- QNetworkReply *reply = manager->get(QNetworkRequest(userIdRequest));
-
- connect(reply, &QNetworkReply::finished, this, &FacebookManager::userIdReceived);
-}
-
-void FacebookManager::userIdReceived()
-{
- QNetworkReply *reply = qobject_cast<QNetworkReply*>(sender());
- QJsonDocument jsonDoc = QJsonDocument::fromJson(reply->readAll());
- QJsonObject obj = jsonDoc.object();
- if (obj.keys().contains("id")) {
- qCDebug(lcFacebook) << "User id requested successfully:" << obj.value("id").toString();
- qPrefFacebook::set_user_id(obj.value("id").toString());
- emit sendMessage(tr("Facebook logged in successfully"));
- emit justLoggedIn(true);
- } else {
- emit sendMessage(tr("Error, unknown user id, cannot login."));
- qCDebug(lcFacebook) << "Error, unknown user id, cannot login.";
- }
- reply->deleteLater();
-}
-
-QPixmap FacebookManager::grabProfilePixmap()
-{
- qCDebug(lcFacebook) << "Grabbing Dive Profile pixmap";
- ProfileWidget2 *profile = MainWindow::instance()->graphics;
-
- QSize size = fbInfo.profileSize == FacebookInfo::SMALL ? QSize(800,600) :
- fbInfo.profileSize == FacebookInfo::MEDIUM ? QSize(1024,760) :
- fbInfo.profileSize == FacebookInfo::BIG ? QSize(1280,1024) : QSize();
-
- auto currSize = profile->size();
- profile->resize(size);
- profile->setToolTipVisibile(false);
- QPixmap pix = profile->grab();
- profile->setToolTipVisibile(true);
- profile->resize(currSize);
-
- return pix;
-}
-
-
-/* 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::sendDiveInit()
-{
- qCDebug(lcFacebook) << "Starting to upload the dive to facebook";
-
- SocialNetworkDialog dialog(qApp->activeWindow());
- if (dialog.exec() != QDialog::Accepted) {
- qCDebug(lcFacebook) << "User cancelled.";
- return;
- }
-
- fbInfo.bodyText = dialog.text();
- fbInfo.profileSize = dialog.profileSize();
- fbInfo.profileData = grabProfilePixmap();
- fbInfo.albumName = dialog.album();
- fbInfo.albumId = QString(); // request Album Id wil handle that.
-
- // will emit albumIdReceived, that's connected to sendDiveToAlbum
- requestAlbumId();
-}
-
-void FacebookManager::sendDiveToAlbum(const QString& albumId)
-{
- qCDebug(lcFacebook) << "Starting to upload the dive to album" << fbInfo.albumName << "id" << albumId;
- QUrl url(graphApi + albumId + "/photos?" +
- "&access_token=" + QString(prefs.facebook.access_token) +
- "&source=image" +
- "&message=" + fbInfo.bodyText.replace("&quot;", "%22"));
-
- QNetworkRequest request(url);
-
- QString bound="margin";
-
- //according to rfc 1867 we need to put this string here:
- QByteArray data(QString("--" + bound + "\r\n").toUtf8());
- data.append("Content-Disposition: form-data; name=\"action\"\r\n\r\n");
- data.append(graphApi + "\r\n");
- data.append("--" + bound + "\r\n"); //according to rfc 1867
-
- //name of the input is "uploaded" in my form, next one is a file name.
- data.append("Content-Disposition: form-data; name=\"uploaded\"; filename=\"" + QString::number(qrand()) + ".png\"\r\n");
- data.append("Content-Type: image/jpeg\r\n\r\n"); //data type
-
- QByteArray bytes;
- QBuffer buffer(&bytes);
- buffer.open(QIODevice::WriteOnly);
- fbInfo.profileData.save(&buffer, "PNG");
-
- 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(QByteArray("Content-Type"),QString("multipart/form-data; boundary=" + bound).toUtf8());
- request.setRawHeader(QByteArray("Content-Length"), QString::number(data.length()).toUtf8());
- QNetworkReply *reply = manager->post(request,data);
-
- connect(reply, &QNetworkReply::finished, this, &FacebookManager::uploadFinished);
-}
-
-void FacebookManager::uploadFinished()
-{
- qCDebug(lcFacebook) << "Upload finish";
- auto reply = qobject_cast<QNetworkReply*>(sender());
- QByteArray response = reply->readAll();
- QJsonDocument jsonDoc = QJsonDocument::fromJson(response);
- QJsonObject obj = jsonDoc.object();
-
- reply->deleteLater();
-
- if (obj.keys().contains("id")){
- emit sendMessage(tr("Dive uploaded successfully to Facebook"));
- } else {
- emit sendMessage(tr("Dive upload failed. Please see debug output and send to Subsurface mailing list"));
- qCDebug(lcFacebook) << "Dive upload failed" << response;
- }
-
- emit sendDiveFinished();
-}
-
-void FacebookConnectWidget::showEvent(QShowEvent *event)
-{
- if (FacebookManager::instance()->loggedIn()) {
- facebookLoggedIn();
- } else {
- facebookDisconnect();
- }
- return QDialog::showEvent(event);
-}
-
-FacebookConnectWidget::FacebookConnectWidget(QWidget *parent) : QDialog(parent), ui(new Ui::FacebookConnectWidget) {
- ui->setupUi(this);
- FacebookManager *fb = FacebookManager::instance();
-#ifdef USE_WEBENGINE
- facebookWebView = new QWebEngineView(this);
-#else
- facebookWebView = new QWebView(this);
-#endif
- ui->fbWebviewContainer->layout()->addWidget(facebookWebView);
-#ifdef USE_WEBENGINE
- connect(facebookWebView, &QWebEngineView::urlChanged, fb, &FacebookManager::tryLogin);
-#else
- connect(facebookWebView, &QWebView::urlChanged, fb, &FacebookManager::tryLogin);
-#endif
- connect(fb, &FacebookManager::justLoggedIn, this, &FacebookConnectWidget::facebookLoggedIn);
- connect(fb, &FacebookManager::justLoggedOut, this, &FacebookConnectWidget::facebookDisconnect);
-}
-
-void FacebookConnectWidget::facebookLoggedIn()
-{
- ui->fbWebviewContainer->hide();
- ui->fbWebviewContainer->setEnabled(false);
- ui->FBLabel->setText(tr("To disconnect Subsurface from your Facebook account, use the 'Share on' menu entry."));
- close();
-}
-
-void FacebookConnectWidget::facebookDisconnect()
-{
- qCDebug(lcFacebook) << "Disconnecting from facebook";
- // 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) {
-#ifdef USE_WEBENGINE
- //FIX ME
-#else
- facebookWebView->page()->networkAccessManager()->setCookieJar(new QNetworkCookieJar());
-#endif
- facebookWebView->setUrl(FacebookManager::instance()->connectUrl());
- }
-}
-
-SocialNetworkDialog::SocialNetworkDialog(QWidget *parent) :
- QDialog(parent),
- ui( new Ui::SocialnetworksDialog())
-{
- ui->setupUi(this);
- ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
- connect(ui->date, &QCheckBox::clicked, this, &SocialNetworkDialog::selectionChanged);
- connect(ui->duration, &QCheckBox::clicked, this, &SocialNetworkDialog::selectionChanged);
- connect(ui->Buddy, &QCheckBox::clicked, this, &SocialNetworkDialog::selectionChanged);
- connect(ui->Divemaster, &QCheckBox::clicked, this, &SocialNetworkDialog::selectionChanged);
- connect(ui->Location, &QCheckBox::clicked, this, &SocialNetworkDialog::selectionChanged);
- connect(ui->Notes, &QCheckBox::clicked, this, &SocialNetworkDialog::selectionChanged);
- connect(ui->album, &QLineEdit::textChanged, this, &SocialNetworkDialog::albumChanged);
-}
-
-FacebookInfo::Size SocialNetworkDialog::profileSize() const
-{
- QString currText = ui->profileSize->currentText();
- return currText.startsWith(tr("Small")) ? FacebookInfo::SMALL :
- currText.startsWith(tr("Medium")) ? FacebookInfo::MEDIUM :
- /* currText.startsWith(tr("Big")) ? */ FacebookInfo::BIG;
-}
-
-
-void SocialNetworkDialog::albumChanged()
-{
- QAbstractButton *button = ui->buttonBox->button(QDialogButtonBox::Ok);
- button->setEnabled(!ui->album->text().isEmpty());
-}
-
-void SocialNetworkDialog::selectionChanged()
-{
- struct dive *d = current_dive;
- QString fullText;
-
- if (!d)
- return;
-
- if (ui->date->isChecked()) {
- fullText += tr("Dive date: %1 \n").arg(get_short_dive_date_string(d->when));
- }
- if (ui->duration->isChecked()) {
- fullText += tr("Duration: %1 \n").arg(get_dive_duration_string(d->duration.seconds,
- tr("h", "abbreviation for hours"),
- tr("min", "abbreviation for minutes")));
- }
- if (ui->Location->isChecked()) {
- fullText += tr("Dive location: %1 \n").arg(get_dive_location(d));
- }
- if (ui->Buddy->isChecked()) {
- fullText += tr("Buddy: %1 \n").arg(d->buddy);
- }
- if (ui->Divemaster->isChecked()) {
- fullText += tr("Divemaster: %1 \n").arg(d->divemaster);
- }
- if (ui->Notes->isChecked()) {
- fullText += tr("\n%1").arg(d->notes);
- }
- ui->text->setPlainText(fullText);
-}
-
-QString SocialNetworkDialog::text() const {
- return ui->text->toPlainText().toHtmlEscaped();
-}
-
-QString SocialNetworkDialog::album() const {
- return ui->album->text().toHtmlEscaped();
-}
-
-