fbApi.cpp 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. /*
  2. * From: https://github.com/netogallo/FrameBook/
  3. * heavily modified for Project PhotoBunny
  4. *
  5. * 2014 Gwilyn Saunders
  6. */
  7. #include "fbApi.h"
  8. #include <QtCore>
  9. #include <QUrl>
  10. #include <QUrlQuery>
  11. #include <QNetworkAccessManager>
  12. #include <QNetworkReply>
  13. #include <QVariantMap>
  14. #include <QDir>
  15. #include <QFile>
  16. #include <QWebPage>
  17. #include <QWebFrame>
  18. #include <QWebElement>
  19. #include <QJsonDocument>
  20. #include <QSettings>
  21. FbApi::FbApi(const char* id, QObject *parent)
  22. : QObject(parent) {
  23. //housekeeping
  24. net = new QNetworkAccessManager(this);
  25. page = new QWebPage(this);
  26. //defaults
  27. appID = QString(id);
  28. token = "";
  29. imgCount = 0;
  30. loginStatus = false;
  31. tmpPath = QDir::tempPath().append("/%1").arg(app_str);
  32. if (!QDir().exists(tmpPath)) {
  33. QDir().mkdir(tmpPath);
  34. }
  35. //get settings
  36. st = new QSettings(company_str, app_str);
  37. userName = new QString(st->value("user").toString());
  38. highRes = st->value("hd").toBool();
  39. caching = st->value("cache").toBool();
  40. //events
  41. connect(page, SIGNAL(loadFinished(bool)), this, SLOT(doAuthentication(bool)));
  42. }
  43. FbApi::~FbApi() {
  44. st->setValue("hd", highRes);
  45. st->setValue("cache", caching);
  46. }
  47. QString FbApi::getTempPath() {
  48. return QString(tmpPath);
  49. }
  50. QString FbApi::user() {
  51. if (!userName->isEmpty())
  52. return QString(*userName);
  53. else
  54. return "";
  55. }
  56. bool FbApi::loggedIn() {
  57. return loginStatus;
  58. }
  59. void FbApi::selectAlbums(QStringList ids) {
  60. albumIDs = ids;
  61. }
  62. QList<QVariantMap> FbApi::allAlbums() {
  63. return albumList;
  64. }
  65. QStringList FbApi::pictures() {
  66. return picList;
  67. }
  68. void FbApi::authenticate(QString userName, QString password) {
  69. qDebug() << "authenticating";
  70. this->userName = new QString(userName);
  71. this->password = new QString(password);
  72. st->setValue("user", userName);
  73. page->mainFrame()->load(QUrl(getLoginUrl()));
  74. }
  75. void FbApi::doAuthentication(bool stat) {
  76. if (stat) {
  77. if (SENSITIVE_DEBUG) qDebug() << page->mainFrame()->url().toString(); //SENSITIVE_DEBUG
  78. QUrl url = QUrl(page->mainFrame()->url().toString().replace("#access_token", "?access_token"));
  79. QUrlQuery query(url);
  80. if (query.hasQueryItem("access_token")) {
  81. qDebug() << "login success";
  82. token = query.queryItemValue("access_token");
  83. if (SENSITIVE_DEBUG) qDebug() << token; //SENSITIVE_DEBUG
  84. loginStatus = true;
  85. emit loginResult(SUCCESS);
  86. }
  87. else if (query.hasQueryItem("login_attempt")) {
  88. qDebug() << "Wrong user/password";
  89. loginStatus = false;
  90. emit loginResult(BAD_PASS);
  91. }
  92. else if (query.hasQueryItem("ret") && query.queryItemValue("ret") == "login") {
  93. qDebug() << "Missing permissions";
  94. loginStatus = false;
  95. emit loginResult(BAD_PERM);
  96. }
  97. else {
  98. qDebug() << "sending credentials";
  99. if (SENSITIVE_DEBUG) qDebug() << url.toString(); //SENSITIVE_DEBUG
  100. page->mainFrame()->findFirstElement("input#email").setAttribute("value", *userName);
  101. page->mainFrame()->findFirstElement("input#pass").setAttribute("value", *password);
  102. page->mainFrame()->evaluateJavaScript("document.getElementById(\"login_form\").submit()");
  103. }
  104. }
  105. }
  106. QUrl FbApi::getLoginUrl() {
  107. QString *url = new QString(fbUrl);
  108. return QUrl(url->replace("APP_ID", appID, Qt::CaseSensitive));
  109. }
  110. void FbApi::loadPictures() {
  111. qDebug() << "fetching picture ids";
  112. qDebug() << "Album:" << albumIDs;
  113. QString url = QString(getAlbumPics);
  114. url.replace("ACCESS_TOKEN", token, Qt::CaseSensitive);
  115. QString albumString = QString("%1").arg(albumIDs.takeFirst());
  116. foreach (QString a, albumIDs) {
  117. albumString += QString(",%1").arg(a);
  118. }
  119. url.replace("ALBUM_IDS", albumString, Qt::CaseSensitive);
  120. resp = net->get(QNetworkRequest(QUrl(url)));
  121. connect(resp, SIGNAL(finished()), this, SLOT(loadPicList()));
  122. }
  123. void FbApi::loadPicList() {
  124. qDebug() << "processing response";
  125. if (SENSITIVE_DEBUG) qDebug() << resp->url().toString(); //SENSITIVE_DEBUG
  126. QJsonDocument doc = QJsonDocument::fromJson(resp->readAll());
  127. QVariant result = doc.toVariant();
  128. resp->close();
  129. qDebug() << "loading photos";
  130. picList.clear();
  131. foreach (QVariant alb, result.toMap().values()) {
  132. foreach (QVariant pic, alb.toMap()["data"].toList()) {
  133. if (highRes) {
  134. picList.append(pic.toMap()["images"].toList()[0].toMap()["source"].toString());
  135. } else {
  136. picList.append(pic.toMap()["source"].toString());
  137. }
  138. }
  139. }
  140. qDebug() << picList.size() << "photo(s)";
  141. if (picList.size() > 0) {
  142. emit picsLoaded();
  143. }
  144. else {
  145. emit error("No photos were loaded.\nPlease check the logfile.");
  146. }
  147. }
  148. void FbApi::loadAlbums() {
  149. qDebug() << "fetching album ids";
  150. QString url = QString(getAlbums);
  151. url.replace("ACCESS_TOKEN", token, Qt::CaseSensitive);
  152. resp = net->get(QNetworkRequest(QUrl(url)));
  153. connect(resp, SIGNAL(finished()), this, SLOT(loadAlbumList()));
  154. }
  155. void FbApi::loadAlbumList() {
  156. qDebug() << "processing response";
  157. if (SENSITIVE_DEBUG) qDebug() << resp->url().toString(); //SENSITIVE_DEBUG
  158. QJsonDocument doc = QJsonDocument::fromJson(resp->readAll());
  159. QVariant result = doc.toVariant();
  160. resp->close();
  161. qDebug() << "loading albums";
  162. albumList.clear();
  163. foreach (QVariant album, result.toMap()["data"].toList()) {
  164. albumList.append(album.toMap());
  165. }
  166. qDebug() << albumList.size() << "album(s)";
  167. if (albumList.size() > 0)
  168. emit albumsLoaded();
  169. else
  170. emit error("No albums loaded. Please check the logfile.");
  171. }
  172. void FbApi::nextPicture() {
  173. if (imgCount >= picList.size()) {
  174. imgCount = 0; //loop
  175. }
  176. QString picUrl = picList.at(imgCount);
  177. QString path = QString(tmpPath).append("/%1").arg(QUrl(picUrl).fileName());
  178. if (caching) {
  179. if (!QFile::exists(path)) {
  180. //load if not already cached
  181. picResp = net->get(QNetworkRequest(QUrl(picUrl)));
  182. connect(picResp, SIGNAL(finished()), this, SLOT(setPicture()));
  183. }
  184. else {
  185. emit picLoaded(path);
  186. qDebug() << imgCount << ": CACHED :" << path;
  187. imgCount++;
  188. }
  189. }
  190. else {
  191. //remove previous image
  192. QFile::remove(path);
  193. picResp = net->get(QNetworkRequest(QUrl(picUrl)));
  194. connect(picResp, SIGNAL(finished()), this, SLOT(setPicture()));
  195. }
  196. }
  197. void FbApi::setPicture() {
  198. if (picResp->error() == QNetworkReply::NoError && picResp->size() > 1) {
  199. QString picUrl = picList.at(imgCount);
  200. QString path = QString(tmpPath).append("/%1").arg(QUrl(picUrl).fileName());
  201. //write picResp to file
  202. pic = new QFile(path);
  203. pic->open(QIODevice::WriteOnly);
  204. pic->write(picResp->readAll());
  205. pic->close();
  206. emit picLoaded(path);
  207. qDebug() << imgCount << ":" << path;
  208. imgCount++;
  209. }
  210. }
  211. void FbApi::acceptPermissions() {
  212. page->mainFrame()->evaluateJavaScript("document.getElementsByName(\"__CONFIRM__\")[0].click()");
  213. }