From ee5d93e155ec58c82cb0f1225dc2f5b34f9e78ce Mon Sep 17 00:00:00 2001
From: Tomaz Canabrava <tomaz.canabrava@intel.com>
Date: Wed, 24 Dec 2014 21:34:23 -0200
Subject: [PATCH] Changed Facebook stuff to socialnetworks.h/cpp

All Facebook related stuff now is on SocialNetworks.h/cpp
this makes it much easier to implement things and looking
for bugs.

working:
- logging in
- getting user id
- getting album id ( or creating it )

*much* more testing is needed, of course.

Signed-off-by: Tomaz Canabrava <tomaz.canabrava@intel.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
---
 pref.h                   |   4 +-
 qt-ui/divelistview.cpp   |   4 +-
 qt-ui/preferences.cpp    | 102 ++++------------------
 qt-ui/preferences.h      |   3 +-
 qt-ui/preferences.ui     |   8 +-
 qt-ui/simplewidgets.cpp  |  46 ----------
 qt-ui/simplewidgets.h    |   9 --
 qt-ui/socialnetworks.cpp | 182 +++++++++++++++++++++++++++++++++++++++
 qt-ui/socialnetworks.h   |  31 +++++++
 subsurface.pro           |   6 +-
 subsurfacestartup.c      |   6 +-
 11 files changed, 247 insertions(+), 154 deletions(-)
 create mode 100644 qt-ui/socialnetworks.cpp
 create mode 100644 qt-ui/socialnetworks.h

diff --git a/pref.h b/pref.h
index 16336f22f..f43c32084 100644
--- a/pref.h
+++ b/pref.h
@@ -19,9 +19,9 @@ typedef struct
 } partial_pressure_graphs_t;
 
 typedef struct {
-	char *user_id;
 	char *access_token;
-	char *album_name;
+	char *user_id;
+	char *album_id;
 } facebook_prefs_t;
 
 struct preferences {
diff --git a/qt-ui/divelistview.cpp b/qt-ui/divelistview.cpp
index 65090e1e8..83d78c4c2 100644
--- a/qt-ui/divelistview.cpp
+++ b/qt-ui/divelistview.cpp
@@ -27,6 +27,7 @@
 #include <QFileDialog>
 #include <string>
 #include <iostream>
+#include "socialnetworks.h"
 #include "../qthelper.h"
 
 //                                #  Date  Rtg Dpth  Dur  Tmp Wght Suit  Cyl  Gas  SAC  OTU  CNS  Loc
@@ -842,8 +843,7 @@ void DiveListView::contextMenuEvent(QContextMenuEvent *event)
 
 void DiveListView::publishFacebook()
 {
-	FacebookManager manager;
-	manager.checkAlbumExists();
+	FacebookManager *fb = FacebookManager::instance();
 }
 
 void DiveListView::shiftTimes()
diff --git a/qt-ui/preferences.cpp b/qt-ui/preferences.cpp
index 9502c0c0f..c3ae3b5f7 100644
--- a/qt-ui/preferences.cpp
+++ b/qt-ui/preferences.cpp
@@ -11,14 +11,7 @@
 #include <QNetworkReply>
 #include <QWebView>
 #include <QJsonDocument>
-
-
-static QString facebookConnectUrl =
-		"https://www.facebook.com/dialog/oauth?"
-		"client_id=427722490709000"
-		"&redirect_uri=http://www.facebook.com/connect/login_success.html"
-		"&response_type=token"
-		"&scope=publish_actions,user_photos";
+#include "socialnetworks.h"
 
 PreferencesDialog *PreferencesDialog::instance()
 {
@@ -39,20 +32,18 @@ PreferencesDialog::PreferencesDialog(QWidget *parent, Qt::WindowFlags f) : QDial
 	ui.proxyType->setCurrentIndex(-1);
 
 	// Facebook stuff:
-
-	QSettings settings;
-	settings.beginGroup("WebApps");
-	settings.beginGroup("Facebook");
-	if(settings.allKeys().contains("ConnectToken")){
+	FacebookManager *fb = FacebookManager::instance();
+	if(fb->loggedIn()){
 		ui.facebookWebView->setHtml("You are connected on Facebook, yey.");
-		ui.fbConnected->show();
 	} else {
-		ui.facebookWebView->setUrl(QUrl(facebookConnectUrl));
-		ui.fbConnected->hide();
+		ui.facebookWebView->setUrl(fb->connectUrl());
 	}
-
-	connect(ui.facebookWebView, &QWebView::urlChanged, this, &PreferencesDialog::facebookLoginResponse);
-	connect(ui.btnDisconnectFacebook, &QPushButton::clicked, this, &PreferencesDialog::facebookDisconnect);
+	fb->setDesiredAlbumName(ui.facebookAlbum->text());
+	connect(ui.facebookAlbum, &QLineEdit::textChanged, fb, &FacebookManager::setDesiredAlbumName);
+	connect(ui.facebookWebView, &QWebView::urlChanged, fb, &FacebookManager::tryLogin);
+	connect(fb, &FacebookManager::justLoggedIn, this, &PreferencesDialog::facebookLoggedIn);
+	connect(ui.btnDisconnectFacebook, &QPushButton::clicked, fb, &FacebookManager::logout);
+	connect(fb, &FacebookManager::justLoggedOut, this, &PreferencesDialog::facebookDisconnect);
 
 	connect(ui.proxyType, SIGNAL(currentIndexChanged(int)), this, SLOT(proxyType_changed(int)));
 	connect(ui.buttonBox, SIGNAL(clicked(QAbstractButton *)), this, SLOT(buttonClicked(QAbstractButton *)));
@@ -67,55 +58,19 @@ PreferencesDialog::PreferencesDialog(QWidget *parent, Qt::WindowFlags f) : QDial
 	rememberPrefs();
 }
 
-void PreferencesDialog::facebookLoginResponse(const QUrl &url)
+void PreferencesDialog::facebookLoggedIn()
 {
-	QString result = url.toString();
-	if (result.contains("access_token")){ // Login Successfull.
-		int from = result.indexOf("access_token=") + strlen("access_token=");
-		int to = result.indexOf("&expires_in");
-		QString securityToken = result.mid(from, to-from);
-
-		QSettings settings;
-		settings.beginGroup("WebApps");
-		settings.beginGroup("Facebook");
-		settings.setValue("ConnectToken", securityToken);
-
-		QNetworkAccessManager *getUserID = new QNetworkAccessManager();
-		connect(getUserID, &QNetworkAccessManager::finished, this, &PreferencesDialog::facebookGetUserId);
-		getUserID->get(QNetworkRequest(QUrl("https://graph.facebook.com/me?fields=id&access_token=" + securityToken)));
-		ui.facebookWebView->setHtml("We need a better 'you re connected' page. but, YEY. ");
-		ui.fbConnected->show();
-
-		// only enable when we get the reply for the user_id.
-		setDisabled(true);
-	}
-}
-
-void PreferencesDialog::facebookGetUserId(QNetworkReply *reply)
-{
-	QJsonDocument jsonDoc = QJsonDocument::fromJson(reply->readAll());
-	QJsonObject obj = jsonDoc.object();
-	if (obj.keys().contains("id")){
-		QSettings s;
-		s.beginGroup("WebApps");
-		s.beginGroup("Facebook");
-		s.setValue("UserId", obj.value("id").toVariant());
-	}
-	setEnabled(true);
+	ui.facebookWebView->setHtml("We need a better 'you re connected' page. but, YEY. ");
+	ui.fbConnected->show();
 }
 
 void PreferencesDialog::facebookDisconnect()
 {
-		QSettings settings;
-		settings.beginGroup("WebApps");
-		settings.beginGroup("Facebook");
-		settings.remove("ConnectToken");
-		ui.facebookWebView->page()->networkAccessManager()->setCookieJar(new QNetworkCookieJar());
-		ui.facebookWebView->setUrl(QUrl(facebookConnectUrl));
-		ui.fbConnected->hide();
+	ui.facebookWebView->page()->networkAccessManager()->setCookieJar(new QNetworkCookieJar());
+	ui.facebookWebView->setUrl(FacebookManager::instance()->connectUrl());
+	ui.fbConnected->hide();
 }
 
-
 #define DANGER_GF (gf > 100) ? "* { color: red; }" : ""
 void PreferencesDialog::gflowChanged(int gf)
 {
@@ -211,15 +166,6 @@ void PreferencesDialog::setUiFromPrefs()
 	ui.proxyPassword->setText(prefs.proxy_pass);
 	ui.proxyType->setCurrentIndex(ui.proxyType->findData(prefs.proxy_type));
 	ui.btnUseDefaultFile->setChecked(prefs.use_default_file);
-
-	s.beginGroup("WebApps");
-	s.beginGroup("Facebook");
-	if(s.allKeys().contains("ConnectToken")){
-		ui.fbConnected->show();
-	} else {
-		ui.fbConnected->hide();
-	}
-	ui.facebookAlbum->setText(s.value("Album", "subsurface").toString());
 }
 
 void PreferencesDialog::restorePrefs()
@@ -365,13 +311,6 @@ void PreferencesDialog::syncSettings()
 	s.setValue("proxy_pass", ui.proxyPassword->text());
 	s.endGroup();
 
-	// Facebook
-	s.beginGroup("WebApps");
-	s.beginGroup("Facebook");
-	s.setValue("Album", ui.facebookAlbum->text());
-	s.endGroup();
-	s.endGroup();
-
 	loadSettings();
 	emit settingsChanged();
 }
@@ -476,15 +415,6 @@ void PreferencesDialog::loadSettings()
 	GET_TXT("proxy_user", proxy_user);
 	GET_TXT("proxy_pass", proxy_pass);
 	s.endGroup();
-
-	s.beginGroup("WebApps");
-	s.beginGroup("Facebook");
-	GET_TXT("UserId", facebook.user_id);
-	GET_TXT("ConnectToken", facebook.access_token);
-	GET_TXT("AlbumName", facebook.album_name);
-	s.endGroup();
-	s.endGroup();
-	qDebug() << prefs.facebook.user_id << prefs.facebook.access_token << prefs.facebook.album_name;
 }
 
 void PreferencesDialog::buttonClicked(QAbstractButton *button)
diff --git a/qt-ui/preferences.h b/qt-ui/preferences.h
index d455f536c..72c379181 100644
--- a/qt-ui/preferences.h
+++ b/qt-ui/preferences.h
@@ -30,9 +30,8 @@ slots:
 	void gfhighChanged(int gf);
 	void proxyType_changed(int idx);
 	void on_btnUseDefaultFile_toggled(bool toggle);
-	void facebookLoginResponse(const QUrl& url);
+	void facebookLoggedIn();
 	void facebookDisconnect();
-	void facebookGetUserId(QNetworkReply *reply);
 private:
 	explicit PreferencesDialog(QWidget *parent = 0, Qt::WindowFlags f = 0);
 	void setUiFromPrefs();
diff --git a/qt-ui/preferences.ui b/qt-ui/preferences.ui
index a89dde894..50fdd71a3 100644
--- a/qt-ui/preferences.ui
+++ b/qt-ui/preferences.ui
@@ -7,7 +7,7 @@
     <x>0</x>
     <y>0</y>
     <width>924</width>
-    <height>718</height>
+    <height>735</height>
    </rect>
   </property>
   <property name="windowTitle">
@@ -995,7 +995,11 @@
                </widget>
               </item>
               <item>
-               <widget class="QLineEdit" name="facebookAlbum"/>
+               <widget class="QLineEdit" name="facebookAlbum">
+                <property name="text">
+                 <string>subsurface</string>
+                </property>
+               </widget>
               </item>
               <item>
                <spacer name="horizontalSpacer_2">
diff --git a/qt-ui/simplewidgets.cpp b/qt-ui/simplewidgets.cpp
index 6263e5521..76400ef41 100644
--- a/qt-ui/simplewidgets.cpp
+++ b/qt-ui/simplewidgets.cpp
@@ -661,49 +661,3 @@ void MultiFilter::closeFilter()
 	MultiFilterSortModel::instance()->clearFilter();
 	hide();
 }
-
-FacebookManager::FacebookManager()
-{
-}
-
-bool FacebookManager::checkAlbumExists()
-{
-	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));
-
-	// Make this method synchronous.
-	QEventLoop loop;
-	connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
-	loop.exec();
-
-	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() == QString(prefs.facebook.album_name)) {
-			qDebug() << "Album already exists. Try to get the ID in the next commit.";
-			return false;
-		}
-	}
-
-	qDebug() << "Album doesn't exists, let's create it.";
-	QUrlQuery params;
-	params.addQueryItem("name", prefs.facebook.album_name );
-	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();
-
-	qDebug() << reply->readAll();
-
-}
-
-void FacebookManager::createAlbum()
-{
-
-}
diff --git a/qt-ui/simplewidgets.h b/qt-ui/simplewidgets.h
index 84f0349a4..8d5b4f73c 100644
--- a/qt-ui/simplewidgets.h
+++ b/qt-ui/simplewidgets.h
@@ -214,15 +214,6 @@ private:
 	Ui::FilterWidget ui;
 };
 
-class FacebookManager : public QObject {
-	Q_OBJECT
-public:
-	FacebookManager();
-	bool checkAlbumExists();
-	void createAlbum();
-signals:
-	void requestFinished(const QString& result);
-};
 bool isGnome3Session();
 QImage grayImage(const QImage &coloredImg);
 
diff --git a/qt-ui/socialnetworks.cpp b/qt-ui/socialnetworks.cpp
new file mode 100644
index 000000000..76a85566d
--- /dev/null
+++ b/qt-ui/socialnetworks.cpp
@@ -0,0 +1,182 @@
+#include "socialnetworks.h"
+
+#include <QJsonDocument>
+#include <QJsonArray>
+#include <QJsonObject>
+#include <QNetworkReply>
+#include <QNetworkRequest>
+#include <QNetworkAccessManager>
+#include <QUrlQuery>
+#include <QEventLoop>
+#include <QSettings>
+#include <QDebug>
+
+#include "pref.h"
+
+#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
+
+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"
+		"&scope=publish_actions,user_photos"
+	);
+}
+
+bool FacebookManager::loggedIn() {
+	return prefs.facebook.access_token != NULL;
+}
+
+void FacebookManager::sync()
+{
+	qDebug() << "Sync Active";
+	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);
+
+	qDebug() << "Connection Token" << prefs.facebook.access_token;
+	qDebug() << "User ID" << prefs.facebook.user_id;
+	qDebug() << "Album ID" << prefs.facebook.album_id;
+}
+
+void FacebookManager::tryLogin(const QUrl& loginResponse)
+{
+	qDebug() << "Trying to Login.";
+	QString result = loginResponse.toString();
+	if (!result.contains("access_token")) {
+		return;
+	}
+
+	qDebug() << "Login Sucessfull";
+	int from = result.indexOf("access_token=") + strlen("access_token=");
+	int to = result.indexOf("&expires_in");
+	QString securityToken = result.mid(from, to-from);
+
+	QSettings settings;
+	settings.beginGroup("WebApps");
+	settings.beginGroup("Facebook");
+	settings.setValue("ConnectToken", securityToken);
+	sync();
+	requestUserId();
+	sync();
+	requestAlbumId();
+	sync();
+	emit justLoggedIn();
+	qDebug() << "End try login";
+}
+
+void FacebookManager::logout()
+{
+	qDebug() << "Logging out";
+	QSettings settings;
+	settings.beginGroup("WebApps");
+	settings.beginGroup("Facebook");
+	settings.remove("ConnectToken");
+	settings.remove("UserId");
+	settings.remove("AlbumId");
+	sync();
+	emit justLoggedOut();
+}
+
+void FacebookManager::requestAlbumId()
+{
+	qDebug() << "Requesting Album ID";
+
+	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();
+
+	QSettings s;
+	s.beginGroup("WebApps");
+	s.beginGroup("Facebook");
+
+	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) {
+			qDebug() << "Album already Exists, using it's id";
+			s.setValue("AlbumId", obj.value("id").toString());
+			qDebug() << "Got album ID";
+			return;
+		}
+	}
+
+	qDebug() << "Album doesn't exists, creating one.";
+	QUrlQuery params;
+	qDebug() << "TRYING TO SET NAME" << albumName;
+	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")) {
+		s.setValue("AlbumId", album.value("id").toString());
+		qDebug() << "Got album ID";
+		return;
+	}
+
+	qDebug() << "Error getting album id" << album;
+}
+
+void FacebookManager::requestUserId()
+{
+	qDebug() << "trying to get user Id";
+	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")){
+		QSettings s;
+		s.beginGroup("WebApps");
+		s.beginGroup("Facebook");
+		s.setValue("UserId", obj.value("id").toVariant());
+		qDebug() << "Got user id.";
+		return;
+	}
+	qDebug() << "error getting user id" << obj;
+}
+
+void FacebookManager::setDesiredAlbumName(const QString& a)
+{
+	albumName = a;
+}
diff --git a/qt-ui/socialnetworks.h b/qt-ui/socialnetworks.h
new file mode 100644
index 000000000..ed7804afa
--- /dev/null
+++ b/qt-ui/socialnetworks.h
@@ -0,0 +1,31 @@
+#ifndef FACEBOOKMANAGER_H
+#define FACEBOOKMANAGER_H
+
+#include <QObject>
+#include <QUrl>
+
+class FacebookManager : public QObject
+{
+	Q_OBJECT
+public:
+	static FacebookManager *instance();
+	void requestAlbumId();
+	void requestUserId();
+	void sync();
+	QUrl connectUrl();
+	bool loggedIn();
+signals:
+	void justLoggedIn();
+	void justLoggedOut();
+
+public slots:
+	void tryLogin(const QUrl& loginResponse);
+	void logout();
+	void setDesiredAlbumName(const QString& albumName);
+
+private:
+	explicit FacebookManager(QObject *parent = 0);
+	QString albumName;
+};
+
+#endif // FACEBOOKMANAGER_H
diff --git a/subsurface.pro b/subsurface.pro
index 7d36f1cc3..fb0d9b7e4 100644
--- a/subsurface.pro
+++ b/subsurface.pro
@@ -103,7 +103,8 @@ HEADERS = \
 	qt-ui/statistics/statisticsbar.h \
 	qt-ui/statistics/yearstatistics.h \
 	qt-ui/diveshareexportdialog.h \
-	qt-ui/filtermodels.h
+	qt-ui/filtermodels.h \
+	qt-ui/socialnetworks.h
 
 android: HEADERS -= \
 	qt-ui/usermanual.h \
@@ -197,7 +198,8 @@ SOURCES =  \
 	qt-ui/statistics/statisticsbar.cpp \
 	qt-ui/statistics/monthstatistics.cpp \
 	qt-ui/diveshareexportdialog.cpp \
-	qt-ui/filtermodels.cpp
+	qt-ui/filtermodels.cpp \
+	qt-ui/socialnetworks.cpp
 
 android: SOURCES += android.cpp
 else: win32: SOURCES += windows.c
diff --git a/subsurfacestartup.c b/subsurfacestartup.c
index f63f4e7b2..48e258169 100644
--- a/subsurfacestartup.c
+++ b/subsurfacestartup.c
@@ -50,9 +50,9 @@ struct preferences default_prefs = {
 	.show_pictures_in_profile = true,
 	.tankbar = false,
 	.facebook = {
-		.user_id = "",
-		.album_name = "subsurface",
-		.access_token = ""
+		.user_id = NULL,
+		.album_id = NULL,
+		.access_token = NULL
 	}
 };