Re-factored SituareService::formUrlParameters() publish parameter
[situare] / src / situareservice / situareservice.cpp
index 53b7dcf..03be242 100644 (file)
@@ -38,11 +38,11 @@ SituareService::SituareService(QObject *parent)
 {
     qDebug() << __PRETTY_FUNCTION__;
 
-    m_networkManager = NetworkAccessManager::instance();
+    m_networkManager = new NetworkAccessManager(this);
     connect(m_networkManager, SIGNAL(finished(QNetworkReply*)),
-            this, SLOT(requestFinished(QNetworkReply*)));
+            this, SLOT(requestFinished(QNetworkReply*)), Qt::QueuedConnection);
 
-    m_imageFetcher = new ImageFetcher(NetworkAccessManager::instance(), this);
+    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)),
@@ -76,7 +76,7 @@ void SituareService::fetchLocations()
     sendRequest(url, COOKIE, cookie);
 }
 
-void SituareService::reverseGeo(const QPointF &coordinates)
+void SituareService::reverseGeo(const GeoCoordinate &coordinates)
 {
     qDebug() << __PRETTY_FUNCTION__;
 
@@ -91,26 +91,18 @@ void SituareService::reverseGeo(const QPointF &coordinates)
     sendRequest(url, COOKIE, cookie);
 }
 
-void SituareService::updateLocation(const QPointF &coordinates, const QString &status,
+void SituareService::updateLocation(const GeoCoordinate &coordinates, const QString &status,
                                     const bool &publish)
 {
     qDebug() << __PRETTY_FUNCTION__;
 
+    QString urlParameters = formUrlParameters(coordinates, status, publish);
+    QUrl url = formUrl(SITUARE_URL, UPDATE_LOCATION, urlParameters);
+
     QString cookie = formCookie(API_KEY, m_credentials.expires(), m_credentials.userID(),
                                 m_credentials.sessionKey(), m_credentials.sessionSecret(),
                                 m_credentials.sig(), EN_LOCALE);
 
-
-    QString publishValue;
-    if(publish) {
-        publishValue = PUBLISH_TRUE;
-    }
-    else {
-        publishValue = PUBLISH_FALSE;
-    }
-    QString urlParameters = formUrlParameters(coordinates, status, publishValue);
-    QUrl url = formUrl(SITUARE_URL, UPDATE_LOCATION, urlParameters);
-
     sendRequest(url, COOKIE, cookie);
 }
 
@@ -188,31 +180,34 @@ QUrl SituareService::formUrl(const QString &baseUrl, const QString &phpScript,
     return url;
 }
 
-QString SituareService::formUrlParameters(const QPointF &coordinates, QString status,
-                                          QString publish)
+QString SituareService::formUrlParameters(const GeoCoordinate &coordinates, QString status,
+                                          bool publish)
 {
+    qDebug() << __PRETTY_FUNCTION__;
+
+    // one scene pixel is about 5.4e-6 degrees, the integer part is max three digits and one
+    // additional digit is added for maximum precision
+    const int COORDINATE_PRECISION = 10;
+
     QString parameters;
 
     parameters.append(QUESTION_MARK);
     parameters.append(LATITUDE);
     parameters.append(EQUAL_MARK);
-    parameters.append(QString::number(coordinates.y()));
+    parameters.append(QString::number(coordinates.latitude(), 'f', COORDINATE_PRECISION));
     parameters.append(AMBERSAND_MARK);
     parameters.append(LONGTITUDE);
     parameters.append(EQUAL_MARK);
-    parameters.append(QString::number(coordinates.x()));
+    parameters.append(QString::number(coordinates.longitude(), 'f', COORDINATE_PRECISION));
 
-    if(publish.compare(PUBLISH_TRUE) == 0) {
-        parameters.append(AMBERSAND_MARK);
-        parameters.append(PUBLISH);
-        parameters.append(EQUAL_MARK);
+    parameters.append(AMBERSAND_MARK);
+    parameters.append(PUBLISH);
+    parameters.append(EQUAL_MARK);
+
+    if(publish)
         parameters.append(PUBLISH_TRUE);
-    } else if(publish.compare(PUBLISH_FALSE) == 0) {
-        parameters.append(AMBERSAND_MARK);
-        parameters.append(PUBLISH);
-        parameters.append(EQUAL_MARK);
+    else
         parameters.append(PUBLISH_FALSE);
-    }
 
     if(!status.isEmpty()) {
         parameters.append(AMBERSAND_MARK);
@@ -234,7 +229,7 @@ void SituareService::sendRequest(const QUrl &url, const QString &cookieType, con
     request.setAttribute(QNetworkRequest::CacheSaveControlAttribute, false);
     request.setRawHeader(cookieType.toAscii(), cookie.toUtf8());
 
-    QNetworkReply *reply = m_networkManager->get(request);
+    QNetworkReply *reply = m_networkManager->get(request, true);
 
     m_currentRequests.append(reply);
 }
@@ -287,23 +282,14 @@ void SituareService::credentialsReady(const FacebookCredentials &credentials)
 {
     qDebug() << __PRETTY_FUNCTION__;
 
-    m_credentials = credentials;    
+    m_credentials = credentials;
 }
 
 void SituareService::parseUserData(const QByteArray &jsonReply)
 {
     qDebug() << __PRETTY_FUNCTION__;
 
-    m_visited = 0;
-    m_nbrOfImages = 0;
     m_defaultImage = false;
-    qDeleteAll(m_friendsList.begin(), m_friendsList.end());
-    m_friendsList.clear();
-
-    if(m_user) {
-        delete m_user;
-        m_user = 0;
-    }
 
     QJson::Parser parser;
     bool ok;
@@ -323,7 +309,7 @@ void SituareService::parseUserData(const QByteArray &jsonReply)
             QVariant userVariant = result.value("user");
             QMap<QString, QVariant> userMap = userVariant.toMap();
 
-            QPointF coordinates(userMap["longitude"].toReal(), userMap["latitude"].toReal());
+            GeoCoordinate coordinates(userMap["latitude"].toReal(), userMap["longitude"].toReal());
 
             QUrl imageUrl = userMap[NORMAL_SIZE_PROFILE_IMAGE].toUrl();
 
@@ -335,21 +321,23 @@ void SituareService::parseUserData(const QByteArray &jsonReply)
             QString address = userMap["address"].toString();
             if(address.isEmpty()) {
                 QStringList location;
-                location.append(QString::number(coordinates.y()));
-                location.append(QString::number(coordinates.x()));
+                location.append(QString::number(coordinates.latitude()));
+                location.append(QString::number(coordinates.longitude()));
                 address = location.join(", ");
             }
 
-            m_user = new User(address, coordinates, userMap["name"].toString(),
+            User user = User(address, coordinates, userMap["name"].toString(),
                           userMap["note"].toString(), imageUrl, userMap["timestamp"].toString(),
                           true, userMap["uid"].toString());
 
+            QList<User> tmpFriendsList;
+
             foreach (QVariant friendsVariant, result["friends"].toList()) {
               QMap<QString, QVariant> friendMap = friendsVariant.toMap();
               QVariant distance = friendMap["distance"];
               QMap<QString, QVariant> distanceMap = distance.toMap();
 
-              QPointF coordinates(friendMap["longitude"].toReal(), friendMap["latitude"].toReal());
+              GeoCoordinate coordinates(friendMap["latitude"].toReal(),friendMap["longitude"].toReal());
 
               QUrl imageUrl = friendMap["profile_pic"].toUrl();
 
@@ -361,22 +349,86 @@ void SituareService::parseUserData(const QByteArray &jsonReply)
               QString address = friendMap["address"].toString();
               if(address.isEmpty()) {
                   QStringList location;
-                  location.append(QString::number(coordinates.y()));
-                  location.append(QString::number(coordinates.x()));
+                  location.append(QString::number(coordinates.latitude()));
+                  location.append(QString::number(coordinates.longitude()));
                   address = location.join(", ");
               }
 
-              User *user = new User(address, coordinates,
-                                    friendMap["name"].toString(),
-                                    friendMap["note"].toString(), imageUrl,
-                                    friendMap["timestamp"].toString(),
-                                    false, friendMap["uid"].toString(),
-                                    distanceMap["units"].toString(),
-                                    distanceMap["value"].toDouble());
+              User buddy = User(address, coordinates, friendMap["name"].toString(),
+                               friendMap["note"].toString(), imageUrl,
+                               friendMap["timestamp"].toString(),
+                               false, friendMap["uid"].toString(), distanceMap["units"].toString(),
+                               distanceMap["value"].toDouble());
 
-              m_friendsList.append(user);
+              tmpFriendsList.append(buddy);
             }
-            addProfileImages();
+
+            QList<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());
+                } else {
+                    user.setProfileImage(m_user->profileImage());
+                }
+            } else {
+                if(!user.profileImageUrl().isEmpty())
+                    imageUrlList.append(user.profileImageUrl());
+            }
+
+            // clear old user object
+            if(m_user) {
+                delete m_user;
+                m_user = 0;
+            }
+
+            // create new user object from temporary user object
+            m_user = new User(user);
+
+            // set unchanged profile images or add new images to imageUrlList for downloading
+            if(!m_friendsList.isEmpty()) {
+                foreach(User tmpBuddy, tmpFriendsList) {
+                    if(!tmpBuddy.profileImageUrl().isEmpty()) {
+                        bool found = false;
+                        foreach(User *buddy, m_friendsList) {
+                            if(tmpBuddy.profileImageUrl() == buddy->profileImageUrl()) {
+                                tmpBuddy.setProfileImage(buddy->profileImage());
+                                found = true;
+                                break;
+                            }
+                        }
+                        if(!found && !tmpBuddy.profileImageUrl().isEmpty())
+                            imageUrlList.append(tmpBuddy.profileImageUrl());
+                    }
+                }
+            } else {
+                foreach(User buddy, tmpFriendsList) {
+                    if(!buddy.profileImageUrl().isEmpty())
+                        imageUrlList.append(buddy.profileImageUrl());
+                }
+            }
+
+            // clear old friendlist
+            qDeleteAll(m_friendsList.begin(), m_friendsList.end());
+            m_friendsList.clear();
+
+            // populate new friendlist with temporary friendlist's data
+            foreach(User tmpFriendItem, tmpFriendsList) {
+                User *friendItem = new User(tmpFriendItem);
+                m_friendsList.append(friendItem);
+            }
+            tmpFriendsList.clear();
+
+            emit userDataChanged(m_user, m_friendsList);
+
+            // set silhouette image to imageUrlList for downloading
+            if(m_defaultImage)
+                imageUrlList.append(QUrl(SILHOUETTE_URL));
+
+            addProfileImages(imageUrlList);
+            imageUrlList.clear();
         } else {
             QVariant address = result.value("address");
             if(!address.toString().isEmpty()) {
@@ -402,51 +454,35 @@ void SituareService::imageReceived(const QUrl &url, const QPixmap &image)
     if(url == QUrl(SILHOUETTE_URL)) {
         if(m_user->profileImageUrl().isEmpty()) {
             m_user->setProfileImage(AvatarImage::create(image, AvatarImage::Large));
+            emit imageReady(m_user);
         }
-        for(int i=0;i < m_friendsList.count();i++) {
-            if(m_friendsList.at(i)->profileImageUrl().isEmpty()) {
-                m_friendsList.at(i)->setProfileImage(AvatarImage::create(image,
-                                                                         AvatarImage::Small));
+        foreach(User *friendItem, m_friendsList) {
+            if(friendItem->profileImageUrl().isEmpty()) {
+                friendItem->setProfileImage(AvatarImage::create(image, AvatarImage::Small));
+                emit imageReady(friendItem);
             }
         }
     }
 
     if (m_user->profileImageUrl() == url) {
         m_user->setProfileImage(AvatarImage::create(image, AvatarImage::Large));
+        emit imageReady(m_user);
     }
 
-    for(int i=0;i<m_friendsList.count();i++) {
-        if(m_friendsList.at(i)->profileImageUrl() == url) {
-            m_friendsList.at(i)->setProfileImage(AvatarImage::create(image, AvatarImage::Small));
-            m_nbrOfImages++; // indicates how many friend profile images has been downloaded
+    foreach(User *friendItem, m_friendsList) {
+        if(friendItem->profileImageUrl() == url) {
+            friendItem->setProfileImage(AvatarImage::create(image, AvatarImage::Small));
+            emit imageReady(friendItem);
         }
     }
-
-    if(m_nbrOfImages == m_visited) {
-        qDebug() << "m_nbrOfImages: " << m_nbrOfImages << " m_visited: " << m_visited;
-        qDebug() << "emit userDataChanged";
-        emit userDataChanged(m_user, m_friendsList);
-    }
 }
 
-void SituareService::addProfileImages()
+void SituareService::addProfileImages(const QList<QUrl> &imageUrlList)
 {
     qDebug() << __PRETTY_FUNCTION__;
 
-    // reduce net traffic by sending only one download request for facebook silhouette image
-    if(m_defaultImage) {
-        emit fetchImage(QUrl(SILHOUETTE_URL));
-    }
-
-    if(!m_user->profileImageUrl().isEmpty() && m_user->profileImageUrl().isValid())
-        emit fetchImage(m_user->profileImageUrl());
-
-    for(int i=0;i<m_friendsList.count();i++) {
-        if(!m_friendsList.at(i)->profileImageUrl().isEmpty() &&
-           m_friendsList.at(i)->profileImageUrl().isValid()) {
-            m_visited++; // indicates how many friends that have profile image
-            emit fetchImage(m_friendsList.at(i)->profileImageUrl());
-        }
+    foreach(QUrl url, imageUrlList) {
+        emit fetchImage(url);
     }
 }