2014-12-24 23:34:23 +00:00
# include "socialnetworks.h"
# include <QJsonDocument>
# include <QJsonArray>
# include <QJsonObject>
# include <QNetworkReply>
# include <QNetworkRequest>
# include <QNetworkAccessManager>
# include <QUrlQuery>
# include <QEventLoop>
2014-12-25 14:55:06 +00:00
# include <QHttpMultiPart>
2014-12-24 23:34:23 +00:00
# include <QSettings>
2014-12-25 14:55:06 +00:00
# include <QFile>
2014-12-25 19:22:06 +00:00
# include <QBuffer>
2014-12-24 23:34:23 +00:00
# include <QDebug>
2014-12-28 23:06:07 +00:00
# include <QMessageBox>
# include <QInputDialog>
2014-12-25 19:22:06 +00:00
# include "mainwindow.h"
# include "profile/profilewidget2.h"
2014-12-24 23:34:23 +00:00
# include "pref.h"
2014-12-29 19:14:34 +00:00
# include "helpers.h"
2014-12-28 23:43:38 +00:00
# include "ui_socialnetworksdialog.h"
2014-12-24 23:34:23 +00:00
# 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 ( ) ;
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 " ;
2014-12-28 23:06:07 +00:00
sync ( ) ;
2014-12-24 23:34:23 +00:00
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 ;
}
2014-12-25 14:55:06 +00:00
2014-12-25 19:22:06 +00:00
/* 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 . */
2014-12-28 23:06:07 +00:00
void FacebookManager : : sendDive ( )
2014-12-25 14:55:06 +00:00
{
2014-12-28 23:43:38 +00:00
SocialNetworkDialog dialog ( qApp - > activeWindow ( ) ) ;
if ( dialog . exec ( ) ! = QDialog : : Accepted )
2014-12-28 23:06:07 +00:00
return ;
2014-12-28 23:43:38 +00:00
setDesiredAlbumName ( dialog . album ( ) ) ;
2014-12-28 23:06:07 +00:00
requestAlbumId ( ) ;
2014-12-25 19:22:06 +00:00
ProfileWidget2 * profile = MainWindow : : instance ( ) - > graphics ( ) ;
QPixmap pix = QPixmap : : grabWidget ( profile ) ;
QByteArray bytes ;
QBuffer buffer ( & bytes ) ;
buffer . open ( QIODevice : : WriteOnly ) ;
pix . save ( & buffer , " PNG " ) ;
2014-12-25 14:55:06 +00:00
QUrl url ( " https://graph.facebook.com/v2.2/ " + QString ( prefs . facebook . album_id ) + " /photos? " +
" &access_token= " + QString ( prefs . facebook . access_token ) +
2014-12-28 23:06:07 +00:00
" &source=image " +
2014-12-28 23:43:38 +00:00
" &message= " + dialog . text ( ) ) ;
2014-12-25 14:55:06 +00:00
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
2014-12-25 19:22:06 +00:00
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.
2014-12-25 14:55:06 +00:00
data . append ( " Content-Type: image/jpeg \r \n \r \n " ) ; //data type
2014-12-25 19:22:06 +00:00
data . append ( bytes ) ; //let's read the file
2014-12-25 14:55:06 +00:00
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 ( ) ;
2014-12-28 23:43:38 +00:00
QByteArray response = reply - > readAll ( ) ;
QJsonDocument jsonDoc = QJsonDocument : : fromJson ( response ) ;
2014-12-28 23:06:07 +00:00
QJsonObject obj = jsonDoc . object ( ) ;
if ( obj . keys ( ) . contains ( " id " ) ) {
2014-12-28 23:43:38 +00:00
QMessageBox : : information ( qApp - > activeWindow ( ) ,
2015-01-25 15:03:18 +00:00
tr ( " Photo upload sucessfull " ) ,
2015-01-05 03:56:27 +00:00
tr ( " Your dive profile was updated to Facebook. " ) ,
2014-12-28 23:43:38 +00:00
QMessageBox : : Ok ) ;
2014-12-28 23:06:07 +00:00
} else {
2014-12-28 23:43:38 +00:00
QMessageBox : : information ( qApp - > activeWindow ( ) ,
2015-01-25 15:03:18 +00:00
tr ( " Photo upload failed " ) ,
2015-01-05 03:56:27 +00:00
tr ( " Your dive profile was not updated to Facebook, \n "
2014-12-28 23:43:38 +00:00
" please send the following to the developer. \n "
+ response ) ,
QMessageBox : : Ok ) ;
}
}
2014-12-28 23:06:07 +00:00
2014-12-28 23:43:38 +00:00
SocialNetworkDialog : : SocialNetworkDialog ( QWidget * parent ) : QDialog ( parent )
, ui ( new Ui : : SocialnetworksDialog ( ) )
{
ui - > setupUi ( this ) ;
2014-12-29 19:59:21 +00:00
ui - > buttonBox - > button ( QDialogButtonBox : : Ok ) - > setEnabled ( false ) ;
2014-12-28 23:43:38 +00:00
connect ( ui - > date , SIGNAL ( clicked ( ) ) , this , SLOT ( selectionChanged ( ) ) ) ;
2014-12-29 19:14:34 +00:00
connect ( ui - > duration , SIGNAL ( clicked ( ) ) , this , SLOT ( selectionChanged ( ) ) ) ;
2014-12-28 23:43:38 +00:00
connect ( ui - > Buddy , SIGNAL ( clicked ( ) ) , this , SLOT ( selectionChanged ( ) ) ) ;
connect ( ui - > Divemaster , SIGNAL ( clicked ( ) ) , this , SLOT ( selectionChanged ( ) ) ) ;
connect ( ui - > Location , SIGNAL ( clicked ( ) ) , this , SLOT ( selectionChanged ( ) ) ) ;
connect ( ui - > Notes , SIGNAL ( clicked ( ) ) , this , SLOT ( selectionChanged ( ) ) ) ;
2014-12-29 19:59:21 +00:00
connect ( ui - > album , SIGNAL ( textChanged ( QString ) ) , this , SLOT ( albumChanged ( ) ) ) ;
2014-12-28 23:43:38 +00:00
}
2014-12-29 19:59:21 +00:00
void SocialNetworkDialog : : albumChanged ( )
{
QAbstractButton * button = ui - > buttonBox - > button ( QDialogButtonBox : : Ok ) ;
button - > setEnabled ( ! ui - > album - > text ( ) . isEmpty ( ) ) ;
}
void SocialNetworkDialog : : selectionChanged ( )
{
2014-12-28 23:43:38 +00:00
struct dive * d = current_dive ;
QString fullText ;
if ( ui - > date - > isChecked ( ) ) {
2015-01-05 13:53:02 +00:00
fullText + = tr ( " Dive date: %1 \n " ) . arg ( get_short_dive_date_string ( d - > when ) ) ;
2014-12-29 19:14:34 +00:00
}
if ( ui - > duration - > isChecked ( ) ) {
fullText + = tr ( " Duration: %1 \n " ) . arg ( get_dive_duration_string ( d - > duration . seconds ,
tr ( " h: " , " abbreviation for hours plus separator " ) ,
tr ( " min " , " abbreviation for minutes " ) ) ) ;
}
if ( ui - > Location - > isChecked ( ) ) {
2015-01-05 13:53:02 +00:00
fullText + = tr ( " Dive location: %1 \n " ) . arg ( d - > location ) ;
2014-12-28 23:43:38 +00:00
}
if ( ui - > Buddy - > isChecked ( ) ) {
fullText + = tr ( " Buddy: %1 \n " ) . arg ( d - > buddy ) ;
2014-12-28 23:06:07 +00:00
}
2014-12-28 23:43:38 +00:00
if ( ui - > Divemaster - > isChecked ( ) ) {
fullText + = tr ( " Divemaster: %1 \n " ) . arg ( d - > divemaster ) ;
}
if ( ui - > Notes - > isChecked ( ) ) {
2014-12-29 19:59:21 +00:00
fullText + = tr ( " \n %1 " ) . arg ( d - > notes ) ;
2014-12-28 23:43:38 +00:00
}
ui - > text - > setPlainText ( fullText ) ;
}
QString SocialNetworkDialog : : text ( ) const {
return ui - > text - > toPlainText ( ) . toHtmlEscaped ( ) ;
}
QString SocialNetworkDialog : : album ( ) const {
return ui - > album - > text ( ) . toHtmlEscaped ( ) ;
2014-12-25 14:55:06 +00:00
}