Merge branch 'master' into situare_interact
[situare] / src / situareservice / situareservice.cpp
index aee9f8e..94e4124 100644 (file)
 #include <qjson/parser.h>
 
 #include <QDebug>
-#include <QNetworkReply>
+#include <QtNetwork/QNetworkReply>
 #include <QPixmap>
 #include <QStringList>
 #include <QtAlgorithms>
 #include <QtGlobal>
 
+#include "database.h"
 #include "../error.h"
 #include "network/networkaccessmanager.h"
 #include "situarecommon.h"
 
 #include "situareservice.h"
 
-SituareService::SituareService(QObject *parent)
+SituareService::SituareService(NetworkAccessManager *networkManager, ImageFetcher *imageFetcher,
+                               QObject *parent)
         : QObject(parent),
         m_user(0)
 {
     qDebug() << __PRETTY_FUNCTION__;
 
-    m_networkManager = new NetworkAccessManager(this);
+    m_networkManager = networkManager;
     connect(m_networkManager, SIGNAL(finished(QNetworkReply*)),
             this, SLOT(requestFinished(QNetworkReply*)), Qt::QueuedConnection);
 
-    m_imageFetcher = new ImageFetcher(new NetworkAccessManager(this), this);
-    connect(this, SIGNAL(fetchImage(QUrl)),
-            m_imageFetcher, SLOT(fetchImage(QUrl)));
-    connect(m_imageFetcher, SIGNAL(imageReceived(QUrl,QPixmap)),
-            this, SLOT(imageReceived(QUrl, QPixmap)));
+    m_imageFetcher = imageFetcher;
+    connect(this, SIGNAL(fetchImage(QString, QUrl)),
+            m_imageFetcher, SLOT(fetchImage(QString, QUrl)));
+    connect(m_imageFetcher, SIGNAL(imageReceived(QString,QPixmap)),
+            this, SLOT(imageReceived(QString,QPixmap)));
     connect(m_imageFetcher, SIGNAL(error(int, int)),
             this, SIGNAL(error(int, int)));
+
+    m_database = new Database(this);
+    m_database->openDatabase();
+    m_database->createNotificationTable();
+    m_database->createUserTable();
+    m_database->createTagTable();
+    m_database->createUserTagTable();
 }
 
 SituareService::~SituareService()
@@ -68,15 +77,28 @@ SituareService::~SituareService()
     m_friendsList.clear();
 }
 
-void SituareService::addProfileImages(const QList<QUrl> &imageUrlList)
+void SituareService::addProfileImages(const QHash<QString, QUrl> &imageUrlList)
 {
     qDebug() << __PRETTY_FUNCTION__;
 
-    foreach(QUrl url, imageUrlList) {
-        emit fetchImage(url);
+    QHashIterator<QString, QUrl> imageUrlListIterator(imageUrlList);
+
+    while (imageUrlListIterator.hasNext()) {
+        imageUrlListIterator.next();
+        emit fetchImage(imageUrlListIterator.key(), imageUrlListIterator.value());
     }
 }
 
+void SituareService::addTags(const QStringList &tags)
+{
+    qWarning() << __PRETTY_FUNCTION__ << tags.count();
+
+    foreach (QString tag, tags)
+        m_database->addTag(613374451, tag);
+
+    emit updateWasSuccessful(SituareService::SuccessfulAddTags);
+}
+
 void SituareService::appendAccessToken(QString &requestUrl)
 {
     qDebug() << __PRETTY_FUNCTION__;
@@ -148,6 +170,38 @@ QString SituareService::degreesToString(double degrees)
     return QString::number(degrees, 'f', PRECISION);
 }
 
+void SituareService::fetchMessages()
+{
+    qDebug() << __PRETTY_FUNCTION__;
+
+    //Request sent to server does not need the UID
+    QByteArray arr = m_database->getNotifications(613374451);
+
+    parseMessagesData(arr);
+}
+
+void SituareService::fetchPeopleWithSimilarInterest(const GeoCoordinate &southWestCoordinates,
+                                                    const GeoCoordinate &northEastCoordinates)
+{
+    qDebug() << __PRETTY_FUNCTION__;
+
+    //Request sent to server does not need the UID
+    QByteArray arr = m_database->getInterestingPeople(613374451,
+                                                      southWestCoordinates,
+                                                      northEastCoordinates);
+
+    parseInterestingPeopleData(arr);
+}
+
+void SituareService::fetchPopularTags()
+{
+    qDebug() << __PRETTY_FUNCTION__;
+
+    QByteArray arr = m_database->getPopularTags();
+
+    parsePopularTagsData(arr);
+}
+
 void SituareService::fetchLocations()
 {
     qDebug() << __PRETTY_FUNCTION__;
@@ -158,35 +212,97 @@ void SituareService::fetchLocations()
     buildRequest(GET_LOCATIONS, parameters);
 }
 
-void SituareService::imageReceived(const QUrl &url, const QPixmap &image)
+QHash<QString, QString> SituareService::getTags(const QString &userId)
 {
     qDebug() << __PRETTY_FUNCTION__;
-    qDebug() << "Image URL: " << url << " size :" << image.size();
 
-    // assign facebook silhouette image to all who doesn't have a profile image
-    if(url == QUrl(SILHOUETTE_URL)) {
-        if(m_user->profileImageUrl().isEmpty()) {
-            m_user->setProfileImage(AvatarImage::create(image, AvatarImage::Large));
-            emit imageReady(m_user);
-        }
-        foreach(User *friendItem, m_friendsList) {
-            if(friendItem->profileImageUrl().isEmpty()) {
-                friendItem->setProfileImage(AvatarImage::create(image, AvatarImage::Small));
-                emit imageReady(friendItem);
+    return m_database->getTags(userId.toInt());
+}
+
+void SituareService::imageReceived(const QString &id, const QPixmap &image)
+{
+    qDebug() << __PRETTY_FUNCTION__;
+
+    if (m_user->userId() == id)
+        emit imageReady(QString(), AvatarImage::create(image, AvatarImage::Large));
+    else
+        emit imageReady(id, AvatarImage::create(image, AvatarImage::Small));
+}
+
+void SituareService::parseInterestingPeopleData(const QByteArray &jsonReply)
+{
+    qDebug() << __PRETTY_FUNCTION__;
+
+    QJson::Parser parser;
+    bool ok;
+
+    QVariantMap result = parser.parse(jsonReply, &ok).toMap();
+
+    if (!ok) {
+        emit error(ErrorContext::SITUARE, SituareError::INVALID_JSON);
+        return;
+    } else {
+        QVariant people = result["people"];
+
+        QList<User> friends;
+        QList<User> others;
+
+        foreach (QVariant personVariant, people.toMap().value("friends").toList()) {
+            User user;
+            QMap<QString, QVariant> person = personVariant.toMap();
+            user.setUserId(person["uid"].toString());
+            user.setName(person["name"].toString());
+            user.setProfileImage(AvatarImage::create(
+                    QPixmap(":/res/images/empty_avatar.png"), AvatarImage::Small));
+            user.setProfileImageUrl(person["image_url"].toUrl());
+            user.setTags(person["tags"].toList());
+
+            bool latOk;
+            qreal latitude = person["latitude"].toReal(&latOk);
+            bool lonOk;
+            qreal longitude = person["longitude"].toReal(&lonOk);
+
+            if (latOk && lonOk) {
+                user.setCoordinates(GeoCoordinate(latitude, longitude));
+
+                //This should be from the server
+                GeoCoordinate myCoord(65.008, 25.5523);
+                qreal meters = myCoord.distanceTo(user.coordinates());
+                qreal value;
+                QString unit;
+                if (meters < 1000) {
+                    value = meters;
+                    unit = "m";
+                } else {
+                    value = meters/1000;
+                    unit = "km";
+                }
+                user.setDistance(value, unit);
             }
+
+            friends.append(user);
+
+            //Remove comment when the actual server is used
+            //emit fetchImage(user.userId(), user.profileImageUrl());
         }
-    }
 
-    if (m_user->profileImageUrl() == url) {
-        m_user->setProfileImage(AvatarImage::create(image, AvatarImage::Large));
-        emit imageReady(m_user);
-    }
+        foreach (QVariant personVariant, people.toMap().value("others").toList()) {
+            User user;
+            QMap<QString, QVariant> person = personVariant.toMap();
+            user.setUserId(person["uid"].toString());
+            user.setName(person["name"].toString());
+            user.setProfileImage(AvatarImage::create(
+                    QPixmap(":/res/images/empty_avatar.png"), AvatarImage::Small));
+            user.setProfileImageUrl(person["image_url"].toUrl());
+            user.setTags(person["tags"].toList());
 
-    foreach(User *friendItem, m_friendsList) {
-        if(friendItem->profileImageUrl() == url) {
-            friendItem->setProfileImage(AvatarImage::create(image, AvatarImage::Small));
-            emit imageReady(friendItem);
+            others.append(user);
+
+            //Remove comment when the actual server is used
+            //emit fetchImage(user.userId(), user.profileImageUrl());
         }
+
+        emit interestingPeopleReceived(friends, others);
     }
 }
 
@@ -235,6 +351,13 @@ void SituareService::parseUserData(const QByteArray &jsonReply)
                           userMap["note"].toString(), imageUrl, userMap["timestamp"].toString(),
                           true, userMap["uid"].toString());
 
+            if(imageUrl.isEmpty()) {
+                // user doesn't have profile image, so we need to get him a silhouette image
+                m_defaultImage = true;
+                user.setProfileImage(AvatarImage::create(
+                        QPixmap(":/res/images/empty_avatar_big.png"), AvatarImage::Large));
+            }
+
             QList<User> tmpFriendsList;
 
             foreach (QVariant friendsVariant, result["friends"].toList()) {
@@ -265,22 +388,29 @@ void SituareService::parseUserData(const QByteArray &jsonReply)
                                false, friendMap["uid"].toString(), distanceMap["units"].toString(),
                                distanceMap["value"].toDouble());
 
+              if(imageUrl.isEmpty()) {
+                  // friend doesn't have profile image, so we need to get him a silhouette image
+                  m_defaultImage = true;
+                  buddy.setProfileImage(AvatarImage::create(
+                          QPixmap(":/res/images/empty_avatar.png"), AvatarImage::Small));
+              }
+
               tmpFriendsList.append(buddy);
             }
 
-            QList<QUrl> imageUrlList; // url list for images
+            QHash<QString, QUrl> imageUrlList; // url list for images
 
             // set unchanged profile images or add new images to imageUrlList for downloading
             if(m_user) {
                 if(m_user->profileImageUrl() != user.profileImageUrl()) {
                     if(!user.profileImageUrl().isEmpty())
-                        imageUrlList.append(user.profileImageUrl());
+                        imageUrlList.insert(user.userId(), user.profileImageUrl());
                 } else {
                     user.setProfileImage(m_user->profileImage());
                 }
             } else {
                 if(!user.profileImageUrl().isEmpty())
-                    imageUrlList.append(user.profileImageUrl());
+                    imageUrlList.insert(user.userId(), user.profileImageUrl());
             }
 
             // clear old user object
@@ -305,13 +435,13 @@ void SituareService::parseUserData(const QByteArray &jsonReply)
                             }
                         }
                         if(!found && !tmpBuddy.profileImageUrl().isEmpty())
-                            imageUrlList.append(tmpBuddy.profileImageUrl());
+                            imageUrlList.insert(tmpBuddy.userId(), tmpBuddy.profileImageUrl());
                     }
                 }
             } else {
                 foreach(User buddy, tmpFriendsList) {
                     if(!buddy.profileImageUrl().isEmpty())
-                        imageUrlList.append(buddy.profileImageUrl());
+                        imageUrlList.insert(buddy.userId(), buddy.profileImageUrl());
                 }
             }
 
@@ -326,14 +456,18 @@ void SituareService::parseUserData(const QByteArray &jsonReply)
             }
             tmpFriendsList.clear();
 
+            //REMOVE WHEN NOT NEEDED! get user tags and set tags to the user
+            m_user->setTags(getTags(m_user->userId()));
+
             emit userDataChanged(m_user, m_friendsList);
 
             // set silhouette image to imageUrlList for downloading
             if(m_defaultImage)
-                imageUrlList.append(QUrl(SILHOUETTE_URL));
+                imageUrlList.insert("", QUrl(SILHOUETTE_URL));
 
             addProfileImages(imageUrlList);
             imageUrlList.clear();
+
         } else {
             QVariant address = result.value("address");
             if(!address.toString().isEmpty()) {
@@ -350,6 +484,123 @@ void SituareService::parseUserData(const QByteArray &jsonReply)
     }
 }
 
+void SituareService::parseMessagesData(const QByteArray &jsonReply)
+{
+    QJson::Parser parser;
+    bool ok;
+
+    QVariantMap result = parser.parse(jsonReply, &ok).toMap();
+
+    if (!ok) {
+        emit error(ErrorContext::SITUARE, SituareError::INVALID_JSON);
+        return;
+    } else {
+        QVariant messages = result["messages"];
+
+        QList<Message> received;
+        QList<Message> sent;
+
+        foreach (QVariant messageVariant, messages.toMap().value("received").toList()) {
+            Message message(Message::MessageTypeReceived);
+            QMap<QString, QVariant> messageMap = messageVariant.toMap();
+            message.setId(messageMap["id"].toString());
+            message.setSenderId(messageMap["sender_id"].toString());
+            message.setReceiverId(messageMap["receiver_id"].toString());
+            message.setSenderName(messageMap["sender_name"].toString());
+            uint timestampSeconds = messageMap["timestamp"].toUInt();
+            message.setTimestamp(QDateTime::fromTime_t(timestampSeconds));
+            message.setText(messageMap["text"].toString());
+            message.setImage(AvatarImage::create(
+                    QPixmap(":/res/images/empty_avatar.png"), AvatarImage::Small));
+
+            bool latOk;
+            qreal latitude = messageMap["latitude"].toReal(&latOk);
+            bool lonOk;
+            qreal longitude = messageMap["longitude"].toReal(&lonOk);
+
+            if (latOk && lonOk) {
+                message.setAddress(messageMap["address"].toString());
+                message.setCoordinates(GeoCoordinate(latitude, longitude));
+            }
+
+            received.append(message);
+
+            //emit fetchImage(message.id(), messageMap["image_url"].toString());
+        }
+
+        foreach (QVariant messageVariant, messages.toMap().value("sent").toList()) {
+            Message message(Message::MessageTypeSent);
+            QMap<QString, QVariant> messageMap = messageVariant.toMap();
+            message.setId(messageMap["id"].toString());
+            message.setSenderId(messageMap["sender_id"].toString());
+            message.setReceiverId(messageMap["receiver_id"].toString());
+            message.setSenderName(messageMap["sender_name"].toString());
+            uint timestampSeconds = messageMap["timestamp"].toUInt();
+            message.setTimestamp(QDateTime::fromTime_t(timestampSeconds));
+            message.setText(messageMap["text"].toString());
+            message.setImage(AvatarImage::create(
+                    QPixmap(":/res/images/empty_avatar.png"), AvatarImage::Small));
+
+            bool latOk;
+            qreal latitude = messageMap["latitude"].toReal(&latOk);
+            bool lonOk;
+            qreal longitude = messageMap["longitude"].toReal(&lonOk);
+
+            if (latOk && lonOk) {
+                message.setAddress(messageMap["address"].toString());
+                message.setCoordinates(GeoCoordinate(latitude, longitude));
+            }
+
+            sent.append(message);
+
+            //emit fetchImage(message.id(), messageMap["image_url"].toString());
+        }
+
+        emit messagesReceived(received, sent);
+    }
+}
+
+void SituareService::parsePopularTagsData(const QByteArray &jsonReply)
+{
+    qDebug() << __PRETTY_FUNCTION__;
+
+    QJson::Parser parser;
+    bool ok;
+
+    QVariantMap result = parser.parse(jsonReply, &ok).toMap();
+
+    if (!ok) {
+        emit error(ErrorContext::SITUARE, SituareError::INVALID_JSON);
+        return;
+    } else {
+        QHash<QString, QString> popularTags;
+
+        foreach (QVariant tagVariant, result["popular_tags"].toList()) {
+            QMap<QString, QVariant> tag = tagVariant.toMap();
+            popularTags.insert(tag["id"].toString(), tag["name"].toString());
+        }
+
+        emit popularTagsReceived(popularTags);
+    }
+}
+
+void SituareService::removeMessage(const QString &id)
+{
+    qDebug() << __PRETTY_FUNCTION__;
+
+    if (m_database->removeMessage(613374451, id))
+        emit updateWasSuccessful(SituareService::SuccessfulRemoveMessage);
+}
+
+
+void SituareService::removeTags(const QStringList &tags)
+{
+    qDebug() << __PRETTY_FUNCTION__;
+
+    if (m_database->removeTags(613374451, tags))
+        emit updateWasSuccessful(SituareService::SuccessfulRemoveTags);
+}
+
 void SituareService::requestFinished(QNetworkReply *reply)
 {
     qDebug() << __PRETTY_FUNCTION__;
@@ -379,7 +630,7 @@ void SituareService::requestFinished(QNetworkReply *reply)
                 parseUserData(replyArray);
             } else if(replyArray.isEmpty()) {
                 if(reply->url().toString().contains(UPDATE_LOCATION.toAscii())) {
-                    emit updateWasSuccessful();
+                    emit updateWasSuccessful(SituareService::SuccessfulUpdateLocation);
                 } else {
                     // session credentials are invalid
                     emit error(ErrorContext::SITUARE, SituareError::SESSION_EXPIRED);
@@ -406,6 +657,24 @@ void SituareService::reverseGeo(const GeoCoordinate &coordinates)
     buildRequest(REVERSE_GEO, parameters);
 }
 
+void SituareService::searchPeopleByTag(const QString &tag)
+{
+    qDebug() << __PRETTY_FUNCTION__;
+
+    QByteArray arr = m_database->getInterestingPeopleByTag(613374451, tag);
+
+    parseInterestingPeopleData(arr);
+}
+
+void SituareService::sendMessage(const QString &receiverId, const QString &message,
+                                 const GeoCoordinate &coordinates)
+{
+    qDebug() << __PRETTY_FUNCTION__;
+
+    if (m_database->sendMessage(613374451, receiverId.toULongLong(), message, coordinates))
+        emit updateWasSuccessful(SituareService::SuccessfulSendMessage);
+}
+
 void SituareService::sendRequest(const QString &requestUrl)
 {
     qDebug() << __PRETTY_FUNCTION__ << "requestUrl" << requestUrl;