d68c67ccc7a649ad74ddbdda4c2a151ec5b33ef4
[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     //Request sent to server does not need the UID
178     QByteArray arr = m_database->getNotifications(613374451);
179
180     parseMessagesData(arr);
181 }
182
183 void SituareService::fetchPeopleWithSimilarInterest(const GeoCoordinate &southWestCoordinates,
184                                                     const GeoCoordinate &northEastCoordinates)
185 {
186     qDebug() << __PRETTY_FUNCTION__;
187
188     //Request sent to server does not need the UID
189     QByteArray arr = m_database->getInterestingPeople(613374451,
190                                                       southWestCoordinates,
191                                                       northEastCoordinates);
192
193     parseInterestingPeopleData(arr);
194 }
195
196 void SituareService::fetchPopularTags()
197 {
198     qDebug() << __PRETTY_FUNCTION__;
199
200     QByteArray arr = m_database->getPopularTags();
201
202     parsePopularTagsData(arr);
203 }
204
205 void SituareService::fetchLocations()
206 {
207     qDebug() << __PRETTY_FUNCTION__;
208
209     QHash<QString, QString> parameters;
210     parameters.insert("extra_user_data", NORMAL_SIZE_PROFILE_IMAGE);
211
212     buildRequest(GET_LOCATIONS, parameters);
213 }
214
215 SituareService::RequestName SituareService::getRequestName(const QUrl &url) const
216 {
217     qDebug() << __PRETTY_FUNCTION__;
218
219     if (url.toString().contains(GET_LOCATIONS))
220         return SituareService::RequestGetLocations;
221     else if (url.toString().contains(UPDATE_LOCATION))
222         return SituareService::RequestUpdateLocation;
223     else if (url.toString().contains(REVERSE_GEO))
224         return SituareService::RequestReverseGeo;
225     else
226         return SituareService::RequestUnknown;
227 }
228
229 QHash<QString, QString> SituareService::getTags(const QString &userId)
230 {
231     qDebug() << __PRETTY_FUNCTION__;
232
233     return m_database->getTags(userId.toInt());
234 }
235
236 void SituareService::imageReceived(const QString &id, const QPixmap &image)
237 {
238     qDebug() << __PRETTY_FUNCTION__;
239
240     if (m_user->userId() == id)
241         emit imageReady(QString(), AvatarImage::create(image, AvatarImage::Large));
242     else
243         emit imageReady(id, AvatarImage::create(image, AvatarImage::Small));
244 }
245
246 void SituareService::parseInterestingPeopleData(const QByteArray &jsonReply)
247 {
248     qDebug() << __PRETTY_FUNCTION__;
249
250     QJson::Parser parser;
251     bool ok;
252
253     QVariantMap result = parser.parse(jsonReply, &ok).toMap();
254
255     if (!ok) {
256         emit error(ErrorContext::SITUARE, SituareError::INVALID_JSON);
257         return;
258     } else {
259         QVariant people = result["people"];
260
261         QList<User> friends;
262         QList<User> others;
263
264         foreach (QVariant personVariant, people.toMap().value("friends").toList()) {
265             User user;
266             QMap<QString, QVariant> person = personVariant.toMap();
267             user.setUserId(person["uid"].toString());
268             user.setName(person["name"].toString());
269             user.setProfileImage(AvatarImage::create(
270                     QPixmap(":/res/images/empty_avatar.png"), AvatarImage::Small));
271             user.setProfileImageUrl(person["image_url"].toUrl());
272             user.setTags(person["tags"].toList());
273
274             bool latOk;
275             qreal latitude = person["latitude"].toReal(&latOk);
276             bool lonOk;
277             qreal longitude = person["longitude"].toReal(&lonOk);
278
279             if (latOk && lonOk) {
280                 user.setCoordinates(GeoCoordinate(latitude, longitude));
281
282                 //This should be from the server
283                 GeoCoordinate myCoord(65.008, 25.5523);
284                 qreal meters = myCoord.distanceTo(user.coordinates());
285                 qreal value;
286                 QString unit;
287                 if (meters < 1000) {
288                     value = meters;
289                     unit = "m";
290                 } else {
291                     value = meters/1000;
292                     unit = "km";
293                 }
294                 user.setDistance(value, unit);
295             }
296
297             friends.append(user);
298
299             //Remove comment when the actual server is used
300             //emit fetchImage(user.userId(), user.profileImageUrl());
301         }
302
303         foreach (QVariant personVariant, people.toMap().value("others").toList()) {
304             User user;
305             QMap<QString, QVariant> person = personVariant.toMap();
306             user.setUserId(person["uid"].toString());
307             user.setName(person["name"].toString());
308             user.setProfileImage(AvatarImage::create(
309                     QPixmap(":/res/images/empty_avatar.png"), AvatarImage::Small));
310             user.setProfileImageUrl(person["image_url"].toUrl());
311             user.setTags(person["tags"].toList());
312
313             others.append(user);
314
315             //Remove comment when the actual server is used
316             //emit fetchImage(user.userId(), user.profileImageUrl());
317         }
318
319         emit interestingPeopleReceived(friends, others);
320     }
321 }
322
323 void SituareService::parseReply(const QByteArray &jsonReply, RequestName requestName)
324 {
325     qDebug() << __PRETTY_FUNCTION__;
326
327     QJson::Parser parser;
328     bool ok;
329
330     QVariantMap result = parser.parse(jsonReply, &ok).toMap();
331
332     if (!ok) {
333         emit error(ErrorContext::SITUARE, SituareError::INVALID_JSON);
334     } else {
335         QVariant resultStatus = result["ResultStatus"];
336         QVariant resultData = result["ResultData"];
337
338         if (resultStatus.toString() == "ERROR") {
339             QVariantMap errorData = resultData.toMap();
340             emit error(ErrorContext::SITUARE, errorData["ErrorCode"].toInt());
341         } else if (resultStatus.toString() == "OK") {
342             if (requestName == SituareService::RequestGetLocations)
343                 parseUserData(resultData);
344             else if (requestName == SituareService::RequestUpdateLocation)
345                 emit updateWasSuccessful();
346             else if (requestName == SituareService::RequestReverseGeo)
347                 parseReverseGeoData(resultData);
348         }
349     }
350 }
351
352 void SituareService::parseReverseGeoData(const QVariant &reverseGeoData)
353 {
354     qDebug() << __PRETTY_FUNCTION__;
355
356     QVariantMap result = reverseGeoData.toMap();
357
358     if (result.contains("address") && !result["address"].toString().isEmpty()) {
359         emit reverseGeoReady(result["address"].toString());
360     } else {
361         QStringList coordinates;
362         coordinates.append(result["lat"].toString());
363         coordinates.append(result["lon"].toString());
364         emit error(ErrorContext::SITUARE, SituareError::ADDRESS_RETRIEVAL_FAILED);
365         emit reverseGeoReady(coordinates.join(", "));
366     }
367 }
368
369 void SituareService::parseUserData(const QVariant &userData)
370 {
371     qDebug() << __PRETTY_FUNCTION__;
372
373     m_defaultImage = false;
374
375     QVariantMap result = userData.toMap();
376
377     if (result.contains("user")) {
378
379         QVariant userVariant = result.value("user");
380         QMap<QString, QVariant> userMap = userVariant.toMap();
381
382         GeoCoordinate coordinates(userMap["latitude"].toReal(), userMap["longitude"].toReal());
383
384         QUrl imageUrl = userMap[NORMAL_SIZE_PROFILE_IMAGE].toUrl();
385
386         if(imageUrl.isEmpty()) {
387             // user doesn't have profile image, so we need to get him a silhouette image
388             m_defaultImage = true;
389         }
390
391         QString address = userMap["address"].toString();
392         if(address.isEmpty()) {
393             QStringList location;
394             location.append(QString::number(coordinates.latitude()));
395             location.append(QString::number(coordinates.longitude()));
396             address = location.join(", ");
397         }
398
399         User user = User(address, coordinates, userMap["name"].toString(),
400                       userMap["note"].toString(), imageUrl, userMap["timestamp"].toString(),
401                       true, userMap["uid"].toString());
402
403         if(imageUrl.isEmpty()) {
404             // user doesn't have profile image, so we need to get him a silhouette image
405             m_defaultImage = true;
406             user.setProfileImage(AvatarImage::create(
407                     QPixmap(":/res/images/empty_avatar_big.png"), AvatarImage::Large));
408         }
409
410         QList<User> tmpFriendsList;
411
412         foreach (QVariant friendsVariant, result["friends"].toList()) {
413           QMap<QString, QVariant> friendMap = friendsVariant.toMap();
414           QVariant distance = friendMap["distance"];
415           QMap<QString, QVariant> distanceMap = distance.toMap();
416
417           GeoCoordinate coordinates(friendMap["latitude"].toReal(),friendMap["longitude"].toReal());
418
419           QUrl imageUrl = friendMap["profile_pic"].toUrl();
420
421           if(imageUrl.isEmpty()) {
422               // friend doesn't have profile image, so we need to get him a silhouette image
423               m_defaultImage = true;
424           }
425
426           QString address = friendMap["address"].toString();
427           if(address.isEmpty()) {
428               QStringList location;
429               location.append(QString::number(coordinates.latitude()));
430               location.append(QString::number(coordinates.longitude()));
431               address = location.join(", ");
432           }
433
434           User buddy = User(address, coordinates, friendMap["name"].toString(),
435                            friendMap["note"].toString(), imageUrl,
436                            friendMap["timestamp"].toString(),
437                            false, friendMap["uid"].toString(), distanceMap["units"].toString(),
438                            distanceMap["value"].toDouble());
439
440           if(imageUrl.isEmpty()) {
441               // friend doesn't have profile image, so we need to get him a silhouette image
442               m_defaultImage = true;
443               buddy.setProfileImage(AvatarImage::create(
444                       QPixmap(":/res/images/empty_avatar.png"), AvatarImage::Small));
445           }
446
447           tmpFriendsList.append(buddy);
448         }
449
450         QHash<QString, QUrl> imageUrlList; // url list for images
451
452         // set unchanged profile images or add new images to imageUrlList for downloading
453         if(m_user) {
454             if(m_user->profileImageUrl() != user.profileImageUrl()) {
455                 if(!user.profileImageUrl().isEmpty())
456                     imageUrlList.insert(user.userId(), user.profileImageUrl());
457             } else {
458                 user.setProfileImage(m_user->profileImage());
459             }
460         } else {
461             if(!user.profileImageUrl().isEmpty())
462                 imageUrlList.insert(user.userId(), user.profileImageUrl());
463         }
464
465         // clear old user object
466         if(m_user) {
467             delete m_user;
468             m_user = 0;
469         }
470
471         // create new user object from temporary user object
472         m_user = new User(user);
473
474         // set unchanged profile images or add new images to imageUrlList for downloading
475         if(!m_friendsList.isEmpty()) {
476             foreach(User tmpBuddy, tmpFriendsList) {
477                 if(!tmpBuddy.profileImageUrl().isEmpty()) {
478                     bool found = false;
479                     foreach(User *buddy, m_friendsList) {
480                         if(tmpBuddy.profileImageUrl() == buddy->profileImageUrl()) {
481                             tmpBuddy.setProfileImage(buddy->profileImage());
482                             found = true;
483                             break;
484                         }
485                     }
486                     if(!found && !tmpBuddy.profileImageUrl().isEmpty())
487                         imageUrlList.insert(tmpBuddy.userId(), tmpBuddy.profileImageUrl());
488                 }
489             }
490         } else {
491             foreach(User buddy, tmpFriendsList) {
492                 if(!buddy.profileImageUrl().isEmpty())
493                     imageUrlList.insert(buddy.userId(), buddy.profileImageUrl());
494             }
495         }
496
497         // clear old friendlist
498         qDeleteAll(m_friendsList.begin(), m_friendsList.end());
499         m_friendsList.clear();
500
501         // populate new friendlist with temporary friendlist's data
502         foreach(User tmpFriendItem, tmpFriendsList) {
503             User *friendItem = new User(tmpFriendItem);
504             m_friendsList.append(friendItem);
505         }
506         tmpFriendsList.clear();
507
508         //REMOVE WHEN NOT NEEDED! get user tags and set tags to the user
509         m_user->setTags(getTags(m_user->userId()));
510
511         emit userDataChanged(m_user, m_friendsList);
512
513         // set silhouette image to imageUrlList for downloading
514         if(m_defaultImage)
515             imageUrlList.insert("", QUrl(SILHOUETTE_URL));
516
517         addProfileImages(imageUrlList);
518         imageUrlList.clear();
519     }
520 }
521
522 void SituareService::parseMessagesData(const QByteArray &jsonReply)
523 {
524     QJson::Parser parser;
525     bool ok;
526
527     QVariantMap result = parser.parse(jsonReply, &ok).toMap();
528
529     if (!ok) {
530         emit error(ErrorContext::SITUARE, SituareError::INVALID_JSON);
531         return;
532     } else {
533         QVariant messages = result["messages"];
534
535         QList<Message> received;
536         QList<Message> sent;
537
538         foreach (QVariant messageVariant, messages.toMap().value("received").toList()) {
539             Message message(Message::MessageTypeReceived);
540             QMap<QString, QVariant> messageMap = messageVariant.toMap();
541             message.setId(messageMap["id"].toString());
542             message.setSenderId(messageMap["sender_id"].toString());
543             message.setReceiverId(messageMap["receiver_id"].toString());
544             message.setSenderName(messageMap["sender_name"].toString());
545             uint timestampSeconds = messageMap["timestamp"].toUInt();
546             message.setTimestamp(QDateTime::fromTime_t(timestampSeconds));
547             message.setText(messageMap["text"].toString());
548             message.setImage(AvatarImage::create(
549                     QPixmap(":/res/images/empty_avatar.png"), AvatarImage::Small));
550
551             bool latOk;
552             qreal latitude = messageMap["latitude"].toReal(&latOk);
553             bool lonOk;
554             qreal longitude = messageMap["longitude"].toReal(&lonOk);
555
556             if (latOk && lonOk) {
557                 message.setAddress(messageMap["address"].toString());
558                 message.setCoordinates(GeoCoordinate(latitude, longitude));
559             }
560
561             received.append(message);
562
563             //emit fetchImage(message.id(), messageMap["image_url"].toString());
564         }
565
566         foreach (QVariant messageVariant, messages.toMap().value("sent").toList()) {
567             Message message(Message::MessageTypeSent);
568             QMap<QString, QVariant> messageMap = messageVariant.toMap();
569             message.setId(messageMap["id"].toString());
570             message.setSenderId(messageMap["sender_id"].toString());
571             message.setReceiverId(messageMap["receiver_id"].toString());
572             message.setSenderName(messageMap["sender_name"].toString());
573             uint timestampSeconds = messageMap["timestamp"].toUInt();
574             message.setTimestamp(QDateTime::fromTime_t(timestampSeconds));
575             message.setText(messageMap["text"].toString());
576             message.setImage(AvatarImage::create(
577                     QPixmap(":/res/images/empty_avatar.png"), AvatarImage::Small));
578
579             bool latOk;
580             qreal latitude = messageMap["latitude"].toReal(&latOk);
581             bool lonOk;
582             qreal longitude = messageMap["longitude"].toReal(&lonOk);
583
584             if (latOk && lonOk) {
585                 message.setAddress(messageMap["address"].toString());
586                 message.setCoordinates(GeoCoordinate(latitude, longitude));
587             }
588
589             sent.append(message);
590
591             //emit fetchImage(message.id(), messageMap["image_url"].toString());
592         }
593
594         emit messagesReceived(received, sent);
595     }
596 }
597
598 void SituareService::parsePopularTagsData(const QByteArray &jsonReply)
599 {
600     qDebug() << __PRETTY_FUNCTION__;
601
602     QJson::Parser parser;
603     bool ok;
604
605     QVariantMap result = parser.parse(jsonReply, &ok).toMap();
606
607     if (!ok) {
608         emit error(ErrorContext::SITUARE, SituareError::INVALID_JSON);
609         return;
610     } else {
611         QHash<QString, QString> popularTags;
612
613         foreach (QVariant tagVariant, result["popular_tags"].toList()) {
614             QMap<QString, QVariant> tag = tagVariant.toMap();
615             popularTags.insert(tag["id"].toString(), tag["name"].toString());
616         }
617
618         emit popularTagsReceived(popularTags);
619     }
620 }
621
622 void SituareService::removeMessage(const QString &id)
623 {
624     qDebug() << __PRETTY_FUNCTION__;
625
626     if (m_database->removeMessage(613374451, id))
627         emit updateWasSuccessful(SituareService::SuccessfulRemoveMessage);
628 }
629
630
631 void SituareService::removeTags(const QStringList &tags)
632 {
633     qDebug() << __PRETTY_FUNCTION__;
634
635     if (m_database->removeTags(613374451, tags))
636         emit updateWasSuccessful(SituareService::SuccessfulRemoveTags);
637 }
638
639 void SituareService::requestFinished(QNetworkReply *reply)
640 {
641     qDebug() << __PRETTY_FUNCTION__;
642
643     //Reply from situare
644     if (m_currentRequests.contains(reply)) {
645
646         if (reply->error())
647             emit error(ErrorContext::NETWORK, reply->error());
648         else
649             parseReply(reply->readAll(), getRequestName(reply->url()));
650
651         m_currentRequests.removeAll(reply);
652         reply->deleteLater();
653     }
654 }
655
656 void SituareService::reverseGeo(const GeoCoordinate &coordinates)
657 {
658     qDebug() << __PRETTY_FUNCTION__;
659
660     QHash<QString, QString> parameters;
661     parameters.insert("lat", degreesToString(coordinates.latitude()));
662     parameters.insert("lon", degreesToString(coordinates.longitude()));
663     parameters.insert("format", "json");
664
665     buildRequest(REVERSE_GEO, parameters);
666 }
667
668 void SituareService::searchPeopleByTag(const QString &tag)
669 {
670     qDebug() << __PRETTY_FUNCTION__;
671
672     QByteArray arr = m_database->getInterestingPeopleByTag(613374451, tag);
673
674     parseInterestingPeopleData(arr);
675 }
676
677 void SituareService::sendMessage(const QString &receiverId, const QString &message,
678                                  const GeoCoordinate &coordinates)
679 {
680     qDebug() << __PRETTY_FUNCTION__;
681
682     if (m_database->sendMessage(613374451, receiverId.toULongLong(), message, coordinates))
683         emit updateWasSuccessful(SituareService::SuccessfulSendMessage);
684 }
685
686 void SituareService::sendRequest(const QString &requestUrl)
687 {
688     qDebug() << __PRETTY_FUNCTION__ << "requestUrl" << requestUrl;
689
690     // make and send the request
691     QNetworkRequest request;
692     request.setUrl(QUrl(requestUrl));
693     request.setAttribute(QNetworkRequest::CacheSaveControlAttribute, false);
694     QNetworkReply *reply = m_networkManager->get(request, true);
695     m_currentRequests.append(reply);
696 }
697
698 void SituareService::updateSession(const QString &session)
699 {
700     qDebug() << __PRETTY_FUNCTION__;
701
702     m_session = session;
703
704     if (m_session.isEmpty())
705         clearUserData();
706 }
707
708 void SituareService::updateLocation(const GeoCoordinate &coordinates, const QString &status,
709                                     const bool &publish)
710 {
711     qDebug() << __PRETTY_FUNCTION__;
712
713     QHash<QString, QString> parameters;
714     parameters.insert("lat", degreesToString(coordinates.latitude()));
715     parameters.insert("lon", degreesToString(coordinates.longitude()));
716     parameters.insert("publish", publish ? "true" : "false");
717     parameters.insert("data", status); ///< @todo if !empty ???
718
719     buildRequest(UPDATE_LOCATION, parameters);
720 }