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