Changed fetchPeopleWithSimilarInterest to send request to Situare server instead...
[situare] / src / situareservice / situareservice.cpp
1 /*
2    Situare - A location system for Facebook
3    Copyright (C) 2010  Ixonos Plc. Authors:
4
5       Henri Lampela - henri.lampela@ixonos.com
6       Sami Rämö - sami.ramo@ixonos.com
7
8    Situare is free software; you can redistribute it and/or
9    modify it under the terms of the GNU General Public License
10    version 2 as published by the Free Software Foundation.
11
12    Situare is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with Situare; if not, write to the Free Software
19    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
20    USA.
21 */
22
23 #include <qjson/parser.h>
24
25 #include <QDebug>
26 #include <QtNetwork/QNetworkReply>
27 #include <QPixmap>
28 #include <QStringList>
29 #include <QtAlgorithms>
30 #include <QtGlobal>
31
32 #include "database.h"
33 #include "../error.h"
34 #include "network/networkaccessmanager.h"
35 #include "situarecommon.h"
36 #include "ui/avatarimage.h"
37
38 #include "situareservice.h"
39
40 SituareService::SituareService(NetworkAccessManager *networkManager, ImageFetcher *imageFetcher,
41                                QObject *parent)
42         : QObject(parent),
43         m_user(0)
44 {
45     qDebug() << __PRETTY_FUNCTION__;
46
47     m_networkManager = networkManager;
48     connect(m_networkManager, SIGNAL(finished(QNetworkReply*)),
49             this, SLOT(requestFinished(QNetworkReply*)), Qt::QueuedConnection);
50
51     m_imageFetcher = imageFetcher;
52     connect(this, SIGNAL(fetchImage(QString, QUrl)),
53             m_imageFetcher, SLOT(fetchImage(QString, QUrl)));
54     connect(m_imageFetcher, SIGNAL(imageReceived(QString,QPixmap)),
55             this, SLOT(imageReceived(QString,QPixmap)));
56     connect(m_imageFetcher, SIGNAL(error(int, int)),
57             this, SIGNAL(error(int, int)));
58
59     m_database = new Database(this);
60     m_database->openDatabase();
61     m_database->createNotificationTable();
62     m_database->createUserTable();
63     m_database->createTagTable();
64     m_database->createUserTagTable();
65 }
66
67 SituareService::~SituareService()
68 {
69     qDebug() << __PRETTY_FUNCTION__;
70
71     if(m_user) {
72         delete m_user;
73         m_user = 0;
74     }
75
76     qDeleteAll(m_friendsList.begin(), m_friendsList.end());
77     m_friendsList.clear();
78 }
79
80 void SituareService::addProfileImages(const QHash<QString, QUrl> &imageUrlList)
81 {
82     qDebug() << __PRETTY_FUNCTION__;
83
84     QHashIterator<QString, QUrl> imageUrlListIterator(imageUrlList);
85
86     while (imageUrlListIterator.hasNext()) {
87         imageUrlListIterator.next();
88         emit fetchImage(imageUrlListIterator.key(), imageUrlListIterator.value());
89     }
90 }
91
92 void SituareService::addTags(const QStringList &tags)
93 {
94     qWarning() << __PRETTY_FUNCTION__ << tags.count();
95
96     foreach (QString tag, tags)
97         m_database->addTag(613374451, tag);
98
99     emit updateWasSuccessful(SituareService::SuccessfulAddTags);
100 }
101
102 void SituareService::appendAccessToken(QString &requestUrl)
103 {
104     qDebug() << __PRETTY_FUNCTION__;
105
106     requestUrl.append(m_session);
107 }
108
109 void SituareService::buildRequest(const QString &script, const QHash<QString, QString> &parameters)
110 {
111     qDebug() << __PRETTY_FUNCTION__;
112
113     const QString PARAMETER_KEY_API = "api";
114     const QString PARAMETER_VALUE_API = "2.0";
115
116     QString url = SITUARE_URL;
117     url.append(script);
118     url.append("?");
119
120     // append default api version parameter if not yet specified
121     if (!parameters.contains(PARAMETER_KEY_API))
122         url.append(PARAMETER_KEY_API + "=" + PARAMETER_VALUE_API + "&");
123
124     // append parameters
125     if (!parameters.isEmpty()) {
126         QHash<QString, QString>::const_iterator i = parameters.constBegin();
127         while (i != parameters.constEnd()) {
128             url.append(i.key());
129             url.append("=");
130             url.append(i.value());
131             url.append("&");
132             i++;
133         }
134     }
135
136     /// @todo BUG: Url parameter strings are not url escaped
137
138 //    qWarning() << __PRETTY_FUNCTION__ << "request url with parameters:" << url;
139
140     if (!m_session.isEmpty()) {
141         appendAccessToken(url);
142         sendRequest(url);
143     } else {
144         emit error(ErrorContext::SITUARE, SituareError::SESSION_EXPIRED);
145     }
146 }
147
148 void SituareService::clearUserData()
149 {
150     qDebug() << __PRETTY_FUNCTION__;
151
152     qDeleteAll(m_friendsList.begin(), m_friendsList.end());
153     m_friendsList.clear();
154
155     if(m_user) {
156         delete m_user;
157         m_user = 0;
158     }
159     emit userDataChanged(m_user, m_friendsList);
160 }
161
162 QString SituareService::degreesToString(double degrees)
163 {
164     qDebug() << __PRETTY_FUNCTION__;
165
166     // one scene pixel is about 5.4e-6 degrees, the integer part is max three digits and one
167     // additional digit is added for maximum precision
168     const int PRECISION = 10;
169
170     return QString::number(degrees, 'f', PRECISION);
171 }
172
173 void SituareService::fetchMessages()
174 {
175     qDebug() << __PRETTY_FUNCTION__;
176
177     buildRequest(GET_MESSAGES, QHash<QString, QString>());
178 }
179
180 void SituareService::fetchPeopleWithSimilarInterest(const qreal distance)
181 {
182     qDebug() << __PRETTY_FUNCTION__;
183
184     const int TO_KM_DIVIDER = 1000;
185     QHash<QString, QString> parameters;
186     parameters.insert("distance", degreesToString(distance / TO_KM_DIVIDER));
187
188     buildRequest(GET_PEOPLE_WITH_SIMILAR_INTEREST, parameters);
189 }
190
191 void SituareService::fetchPopularTags()
192 {
193     qDebug() << __PRETTY_FUNCTION__;
194
195     QByteArray arr = m_database->getPopularTags();
196
197     parsePopularTagsData(arr);
198 }
199
200 void SituareService::fetchLocations()
201 {
202     qDebug() << __PRETTY_FUNCTION__;
203
204     QHash<QString, QString> parameters;
205     parameters.insert("extra_user_data", NORMAL_SIZE_PROFILE_IMAGE);
206
207     buildRequest(GET_LOCATIONS, parameters);
208 }
209
210 SituareService::RequestName SituareService::getRequestName(const QUrl &url) const
211 {
212     qDebug() << __PRETTY_FUNCTION__;
213
214     if (url.toString().contains(GET_LOCATIONS))
215         return SituareService::RequestGetLocations;
216     else if (url.toString().contains(UPDATE_LOCATION))
217         return SituareService::RequestUpdateLocation;
218     else if (url.toString().contains(REVERSE_GEO))
219         return SituareService::RequestReverseGeo;
220     else if (url.toString().contains(GET_MESSAGES))
221         return SituareService::RequestGetMessages;
222     else if (url.toString().contains(REMOVE_MESSAGE))
223         return SituareService::RequestRemoveMessage;
224     else if (url.toString().contains(SEND_MESSAGE))
225         return SituareService::RequestSendMessage;
226     else if (url.toString().contains(GET_PEOPLE_WITH_SIMILAR_INTEREST))
227         return SituareService::RequestGetPeopleWithSimilarInterest;
228     else
229         return SituareService::RequestUnknown;
230 }
231
232 QHash<QString, QString> SituareService::getTags(const QString &userId)
233 {
234     qDebug() << __PRETTY_FUNCTION__;
235
236     return m_database->getTags(userId.toInt());
237 }
238
239 void SituareService::imageReceived(const QString &id, const QPixmap &image)
240 {
241     qDebug() << __PRETTY_FUNCTION__;
242
243     if (m_user->userId() == id)
244         emit imageReady(QString(), AvatarImage::create(image, AvatarImage::Large));
245     else
246         emit imageReady(id, AvatarImage::create(image, AvatarImage::Small));
247 }
248
249 void SituareService::parseInterestingPeopleData(const QVariant &interestingPeopleData)
250 {
251     qDebug() << __PRETTY_FUNCTION__;
252
253     QVariant people = interestingPeopleData.toMap();
254
255     QList<User> friends;
256     QList<User> others;
257
258     foreach (QVariant personVariant, people.toMap().value("friends").toList()) {
259         User user;
260         QMap<QString, QVariant> person = personVariant.toMap();
261         user.setUserId(person["uid"].toString());
262         user.setName(person["name"].toString());
263         user.setProfileImage(AvatarImage::create(
264                 QPixmap(":/res/images/empty_avatar.png"), AvatarImage::Small));
265         user.setProfileImageUrl(person["pic_square"].toUrl());
266         user.setTimestamp(person["timestamp"].toString());
267         user.setTags(person["tags"].toString());
268         user.setAddress(person["address"].toString());
269         user.setNote(person["note"].toString());
270
271         bool latOk;
272         qreal latitude = person["lat"].toReal(&latOk);
273         bool lonOk;
274         qreal longitude = person["lon"].toReal(&lonOk);
275
276         if (latOk && lonOk) {
277             user.setCoordinates(GeoCoordinate(latitude, longitude));
278
279             qreal meters = person["distance"].toReal() * 1000;
280             qreal value;
281             QString unit;
282             if (meters < 1000) {
283                 value = meters;
284                 unit = "m";
285             } else {
286                 value = meters/1000;
287                 unit = "km";
288             }
289             user.setDistance(value, unit);
290         }
291
292         friends.append(user);
293
294         //Remove comment when the actual server is used
295         //emit fetchImage(user.userId(), user.profileImageUrl());
296     }
297
298     foreach (QVariant personVariant, people.toMap().value("others").toList()) {
299         User user;
300         QMap<QString, QVariant> person = personVariant.toMap();
301         user.setUserId(person["uid"].toString());
302         user.setName(person["name"].toString());
303         user.setProfileImage(AvatarImage::create(
304                 QPixmap(":/res/images/empty_avatar.png"), AvatarImage::Small));
305         user.setProfileImageUrl(person["pic_square"].toUrl());
306         user.setTimestamp(person["timestamp"].toString());
307         user.setTags(person["tags"].toString());
308
309         others.append(user);
310
311         emit fetchImage(user.userId(), user.profileImageUrl());
312     }
313
314     emit interestingPeopleReceived(friends, others);
315 }
316
317 void SituareService::parseReply(const QByteArray &jsonReply, RequestName requestName)
318 {
319     qDebug() << __PRETTY_FUNCTION__ << jsonReply;
320
321     QJson::Parser parser;
322     bool ok;
323
324     QVariantMap result = parser.parse(jsonReply, &ok).toMap();
325
326     if (!ok) {
327         emit error(ErrorContext::SITUARE, SituareError::INVALID_JSON);
328     } else {
329         QVariant resultStatus = result["ResultStatus"];
330         QVariant resultData = result["ResultData"];
331
332         if (resultStatus.toString() == "ERROR") {
333             QVariantMap errorData = resultData.toMap();
334             emit error(ErrorContext::SITUARE, errorData["ErrorCode"].toInt());
335         } else if (resultStatus.toString() == "OK") {
336             if (requestName == SituareService::RequestGetLocations)
337                 parseUserData(resultData);
338             else if (requestName == SituareService::RequestUpdateLocation)
339                 emit updateWasSuccessful(SituareService::SuccessfulUpdateLocation);
340             else if (requestName == SituareService::RequestRemoveMessage)
341                 emit updateWasSuccessful(SituareService::SuccessfulRemoveMessage);
342             else if (requestName == SituareService::RequestReverseGeo)
343                 parseReverseGeoData(resultData);
344             else if (requestName == SituareService::RequestGetMessages)
345                 parseMessagesData(resultData);
346             else if (requestName == SituareService::RequestSendMessage)
347                 emit updateWasSuccessful((SituareService::SuccessfulSendMessage));
348             else if (requestName == SituareService::RequestGetPeopleWithSimilarInterest)
349                 parseInterestingPeopleData(resultData);
350         }
351     }
352 }
353
354 void SituareService::parseReverseGeoData(const QVariant &reverseGeoData)
355 {
356     qDebug() << __PRETTY_FUNCTION__;
357
358     QVariantMap result = reverseGeoData.toMap();
359
360     if (result.contains("address") && !result["address"].toString().isEmpty()) {
361         emit reverseGeoReady(result["address"].toString());
362     } else {
363         QStringList coordinates;
364         coordinates.append(result["lat"].toString());
365         coordinates.append(result["lon"].toString());
366         emit error(ErrorContext::SITUARE, SituareError::ADDRESS_RETRIEVAL_FAILED);
367         emit reverseGeoReady(coordinates.join(", "));
368     }
369 }
370
371 void SituareService::parseUserData(const QVariant &userData)
372 {
373     qDebug() << __PRETTY_FUNCTION__;
374
375     m_defaultImage = false;
376
377     QVariantMap result = userData.toMap();
378
379     if (result.contains("user")) {
380
381         QVariant userVariant = result.value("user");
382         QMap<QString, QVariant> userMap = userVariant.toMap();
383
384         GeoCoordinate coordinates(userMap["latitude"].toReal(), userMap["longitude"].toReal());
385
386         QUrl imageUrl = userMap[NORMAL_SIZE_PROFILE_IMAGE].toUrl();
387
388         if(imageUrl.isEmpty()) {
389             // user doesn't have profile image, so we need to get him a silhouette image
390             m_defaultImage = true;
391         }
392
393         QString address = userMap["address"].toString();
394         if(address.isEmpty()) {
395             QStringList location;
396             location.append(QString::number(coordinates.latitude()));
397             location.append(QString::number(coordinates.longitude()));
398             address = location.join(", ");
399         }
400
401         User user = User(address, coordinates, userMap["name"].toString(),
402                       userMap["note"].toString(), imageUrl, userMap["timestamp"].toString(),
403                       true, userMap["uid"].toString());
404
405         if(imageUrl.isEmpty()) {
406             // user doesn't have profile image, so we need to get him a silhouette image
407             m_defaultImage = true;
408             user.setProfileImage(AvatarImage::create(
409                     QPixmap(":/res/images/empty_avatar_big.png"), AvatarImage::Large));
410         }
411
412         QList<User> tmpFriendsList;
413
414         foreach (QVariant friendsVariant, result["friends"].toList()) {
415           QMap<QString, QVariant> friendMap = friendsVariant.toMap();
416           QVariant distance = friendMap["distance"];
417           QMap<QString, QVariant> distanceMap = distance.toMap();
418
419           GeoCoordinate coordinates(friendMap["latitude"].toReal(),friendMap["longitude"].toReal());
420
421           QUrl imageUrl = friendMap["profile_pic"].toUrl();
422
423           if(imageUrl.isEmpty()) {
424               // friend doesn't have profile image, so we need to get him a silhouette image
425               m_defaultImage = true;
426           }
427
428           QString address = friendMap["address"].toString();
429           if(address.isEmpty()) {
430               QStringList location;
431               location.append(QString::number(coordinates.latitude()));
432               location.append(QString::number(coordinates.longitude()));
433               address = location.join(", ");
434           }
435
436           User buddy = User(address, coordinates, friendMap["name"].toString(),
437                            friendMap["note"].toString(), imageUrl,
438                            friendMap["timestamp"].toString(),
439                            false, friendMap["uid"].toString(), distanceMap["units"].toString(),
440                            distanceMap["value"].toDouble());
441
442           if(imageUrl.isEmpty()) {
443               // friend doesn't have profile image, so we need to get him a silhouette image
444               m_defaultImage = true;
445               buddy.setProfileImage(AvatarImage::create(
446                       QPixmap(":/res/images/empty_avatar.png"), AvatarImage::Small));
447           }
448
449           tmpFriendsList.append(buddy);
450         }
451
452         QHash<QString, QUrl> imageUrlList; // url list for images
453
454         // set unchanged profile images or add new images to imageUrlList for downloading
455         if(m_user) {
456             if(m_user->profileImageUrl() != user.profileImageUrl()) {
457                 if(!user.profileImageUrl().isEmpty())
458                     imageUrlList.insert(user.userId(), user.profileImageUrl());
459             } else {
460                 user.setProfileImage(m_user->profileImage());
461             }
462         } else {
463             if(!user.profileImageUrl().isEmpty())
464                 imageUrlList.insert(user.userId(), user.profileImageUrl());
465         }
466
467         // clear old user object
468         if(m_user) {
469             delete m_user;
470             m_user = 0;
471         }
472
473         // create new user object from temporary user object
474         m_user = new User(user);
475
476         // set unchanged profile images or add new images to imageUrlList for downloading
477         if(!m_friendsList.isEmpty()) {
478             foreach(User tmpBuddy, tmpFriendsList) {
479                 if(!tmpBuddy.profileImageUrl().isEmpty()) {
480                     bool found = false;
481                     foreach(User *buddy, m_friendsList) {
482                         if(tmpBuddy.profileImageUrl() == buddy->profileImageUrl()) {
483                             tmpBuddy.setProfileImage(buddy->profileImage());
484                             found = true;
485                             break;
486                         }
487                     }
488                     if(!found && !tmpBuddy.profileImageUrl().isEmpty())
489                         imageUrlList.insert(tmpBuddy.userId(), tmpBuddy.profileImageUrl());
490                 }
491             }
492         } else {
493             foreach(User buddy, tmpFriendsList) {
494                 if(!buddy.profileImageUrl().isEmpty())
495                     imageUrlList.insert(buddy.userId(), buddy.profileImageUrl());
496             }
497         }
498
499         // clear old friendlist
500         qDeleteAll(m_friendsList.begin(), m_friendsList.end());
501         m_friendsList.clear();
502
503         // populate new friendlist with temporary friendlist's data
504         foreach(User tmpFriendItem, tmpFriendsList) {
505             User *friendItem = new User(tmpFriendItem);
506             m_friendsList.append(friendItem);
507         }
508         tmpFriendsList.clear();
509
510         //REMOVE WHEN NOT NEEDED! get user tags and set tags to the user
511         m_user->setTags(getTags(m_user->userId()));
512
513         emit userDataChanged(m_user, m_friendsList);
514
515         // set silhouette image to imageUrlList for downloading
516         if(m_defaultImage)
517             imageUrlList.insert("", QUrl(SILHOUETTE_URL));
518
519         addProfileImages(imageUrlList);
520         imageUrlList.clear();
521     }
522 }
523
524 void SituareService::parseMessagesData(const QVariant &messagesData)
525 {
526     QVariantMap result = messagesData.toMap();
527
528     QList<Message> received;
529     QList<Message> sent;
530
531     foreach (QVariant messageVariant, result["received"].toList()) {
532         Message message(Message::MessageTypeReceived);
533         QMap<QString, QVariant> messageMap = messageVariant.toMap();
534         message.setId(messageMap["mid"].toString());
535         message.setSenderId(messageMap["sid"].toString());
536         message.setReceiverId(messageMap["rid"].toString());
537         message.setSenderName(messageMap["name"].toString());
538         uint timestampSeconds = messageMap["timestamp"].toUInt();
539         message.setTimestamp(QDateTime::fromTime_t(timestampSeconds));
540         message.setText(messageMap["message"].toString());
541         message.setImage(AvatarImage::create(
542                 QPixmap(":/res/images/empty_avatar.png"), AvatarImage::Small));
543
544         bool latOk;
545         qreal latitude = messageMap["lat"].toReal(&latOk);
546         bool lonOk;
547         qreal longitude = messageMap["lon"].toReal(&lonOk);
548
549         if (latOk && lonOk) {
550             message.setAddress(messageMap["address"].toString());
551             message.setCoordinates(GeoCoordinate(latitude, longitude));
552         }
553
554         received.append(message);
555
556         emit fetchImage(message.id(), messageMap["pic_square"].toString());
557     }
558
559     foreach (QVariant messageVariant, result["sent"].toList()) {
560         Message message(Message::MessageTypeSent);
561         QMap<QString, QVariant> messageMap = messageVariant.toMap();
562         message.setId(messageMap["mid"].toString());
563         message.setSenderId(messageMap["sid"].toString());
564         message.setReceiverId(messageMap["rid"].toString());
565         message.setSenderName(messageMap["name"].toString());
566         uint timestampSeconds = messageMap["timestamp"].toUInt();
567         message.setTimestamp(QDateTime::fromTime_t(timestampSeconds));
568         message.setText(messageMap["message"].toString());
569         message.setImage(AvatarImage::create(
570                 QPixmap(":/res/images/empty_avatar.png"), AvatarImage::Small));
571
572         bool latOk;
573         qreal latitude = messageMap["lat"].toReal(&latOk);
574         bool lonOk;
575         qreal longitude = messageMap["lon"].toReal(&lonOk);
576
577         if (latOk && lonOk) {
578             message.setAddress(messageMap["address"].toString());
579             message.setCoordinates(GeoCoordinate(latitude, longitude));
580         }
581
582         sent.append(message);
583
584         emit fetchImage(message.id(), messageMap["pic_square"].toString());
585     }
586
587     emit messagesReceived(received, sent);
588 }
589
590 void SituareService::parsePopularTagsData(const QByteArray &jsonReply)
591 {
592     qDebug() << __PRETTY_FUNCTION__;
593
594     QJson::Parser parser;
595     bool ok;
596
597     QVariantMap result = parser.parse(jsonReply, &ok).toMap();
598
599     if (!ok) {
600         emit error(ErrorContext::SITUARE, SituareError::INVALID_JSON);
601         return;
602     } else {
603         QHash<QString, QString> popularTags;
604
605         foreach (QVariant tagVariant, result["popular_tags"].toList()) {
606             QMap<QString, QVariant> tag = tagVariant.toMap();
607             popularTags.insert(tag["id"].toString(), tag["name"].toString());
608         }
609
610         emit popularTagsReceived(popularTags);
611     }
612 }
613
614 void SituareService::removeMessage(const QString &id)
615 {
616     qDebug() << __PRETTY_FUNCTION__;
617
618     QHash<QString, QString> parameters;
619     parameters.insert("mid", id);
620
621     buildRequest(REMOVE_MESSAGE, parameters);
622 }
623
624
625 void SituareService::removeTags(const QStringList &tags)
626 {
627     qDebug() << __PRETTY_FUNCTION__;
628
629     if (m_database->removeTags(613374451, tags))
630         emit updateWasSuccessful(SituareService::SuccessfulRemoveTags);
631 }
632
633 void SituareService::requestFinished(QNetworkReply *reply)
634 {
635     qDebug() << __PRETTY_FUNCTION__;
636
637     //Reply from situare
638     if (m_currentRequests.contains(reply)) {
639         if (reply->error())
640             emit error(ErrorContext::NETWORK, reply->error());
641         else
642             parseReply(reply->readAll(), getRequestName(reply->url()));
643
644         m_currentRequests.removeAll(reply);
645         reply->deleteLater();
646     }
647 }
648
649 void SituareService::reverseGeo(const GeoCoordinate &coordinates)
650 {
651     qDebug() << __PRETTY_FUNCTION__;
652
653     QHash<QString, QString> parameters;
654     parameters.insert("lat", degreesToString(coordinates.latitude()));
655     parameters.insert("lon", degreesToString(coordinates.longitude()));
656     parameters.insert("format", "json");
657
658     buildRequest(REVERSE_GEO, parameters);
659 }
660
661 void SituareService::searchPeopleByTag(const QString &tag)
662 {
663     qDebug() << __PRETTY_FUNCTION__;
664
665     QByteArray arr = m_database->getInterestingPeopleByTag(613374451, tag);
666
667     parseInterestingPeopleData(arr);
668 }
669
670 void SituareService::sendMessage(const QString &receiverId, const QString &message,
671                                  const GeoCoordinate &coordinates)
672 {
673     qDebug() << __PRETTY_FUNCTION__;
674
675     QHash<QString, QString> parameters;
676     parameters.insert("rid", receiverId);
677     parameters.insert("message", message);
678
679     if (coordinates.isValid()) {
680         parameters.insert("lat", degreesToString(coordinates.latitude()));
681         parameters.insert("lon", degreesToString(coordinates.longitude()));
682     }
683
684     buildRequest(SEND_MESSAGE, parameters);
685 }
686
687 void SituareService::sendRequest(const QString &requestUrl)
688 {
689     qDebug() << __PRETTY_FUNCTION__ << "requestUrl" << requestUrl;
690
691     // make and send the request
692     QNetworkRequest request;
693     request.setUrl(QUrl(requestUrl));
694     request.setAttribute(QNetworkRequest::CacheSaveControlAttribute, false);
695     QNetworkReply *reply = m_networkManager->get(request, true);
696     m_currentRequests.append(reply);
697 }
698
699 void SituareService::updateSession(const QString &session)
700 {
701     qDebug() << __PRETTY_FUNCTION__;
702
703     m_session = session;
704
705     if (m_session.isEmpty())
706         clearUserData();
707 }
708
709 void SituareService::updateLocation(const GeoCoordinate &coordinates, const QString &status,
710                                     const bool &publish)
711 {
712     qDebug() << __PRETTY_FUNCTION__;
713
714     QHash<QString, QString> parameters;
715     parameters.insert("lat", degreesToString(coordinates.latitude()));
716     parameters.insert("lon", degreesToString(coordinates.longitude()));
717     parameters.insert("publish", publish ? "true" : "false");
718     parameters.insert("data", status); ///< @todo if !empty ???
719
720     buildRequest(UPDATE_LOCATION, parameters);
721 }