146fb7405dc8b17cd8ac3d27372ff2a33114358a
[situare] / src / situareservice / situareservice.h
1 /*
2    Situare - A location system for Facebook
3    Copyright (C) 2010  Ixonos Plc. Authors:
4
5       Henri Lampela - henri.lampela@ixonos.com
6       Jussi Laitinen - jussi.laitinen@ixonos.com
7       Sami Rämö - sami.ramo@ixonos.com
8
9    Situare is free software; you can redistribute it and/or
10    modify it under the terms of the GNU General Public License
11    version 2 as published by the Free Software Foundation.
12
13    Situare is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with Situare; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
21    USA.
22 */
23
24
25 #ifndef SITUARESERVICE_H
26 #define SITUARESERVICE_H
27
28 #include <QObject>
29
30 #include "../user/user.h"
31 #include "imagefetcher.h"
32 #include "message.h"
33
34 class Database;
35 class NetworkAccessManager;
36 class QNetworkReply;
37 class QNetworkRequest;
38 class GeoCoordinate;
39 class QUrl;
40
41 /**
42 * @brief SituareService class for communicating with Situare server
43 *
44 * @author Henri Lampela
45 * @author Jussi Laitinen - jussi.laitinen (at) ixonos.com
46 * @author Sami Rämö - sami.ramo (at) ixonos.com
47 */
48 class SituareService : public QObject
49 {
50     Q_OBJECT
51
52 private:
53     /**
54     * @brief Request name enum
55     */
56     enum RequestName { RequestUnknown,
57                        RequestGetLocations,
58                        RequestUpdateLocation,
59                        RequestReverseGeo,
60                        RequestGetMessages,
61                        RequestRemoveMessage,
62                        RequestSendMessage,
63                        RequestGetPeopleWithSimilarInterest,
64                        RequestGetPopularTags,
65                        RequestAddTags,
66                        RequestGetTags };
67
68 public:
69
70     /**
71     * Unit test class
72     */
73     friend class TestSituareService;
74
75     enum SuccessfulMethod {SuccessfulUpdateLocation, SuccessfulAddTags, SuccessfulRemoveTags,
76                            SuccessfulSendMessage, SuccessfulRemoveMessage};
77
78     /**
79     * @brief Default constructor
80     *
81     * @param parent instance of parent
82     */
83     SituareService(NetworkAccessManager *networkManager, ImageFetcher *imageFetcher,
84                    QObject *parent = 0);
85
86     /**
87     * @brief Destructor
88     *
89     */
90     ~SituareService();
91
92 /*******************************************************************************
93  * MEMBER FUNCTIONS AND SLOTS
94  ******************************************************************************/
95     /**
96     * @brief Retriesves user tags.
97     *
98     * @return QStringList list of tags
99     */
100     void getTags();
101
102     /**
103     * @brief Retrieves people with similart interest (same tags).
104     *
105     * People is searched from area defined by maximum distance
106     * @param maximumDistance maximum distance to people
107     */
108     void fetchPeopleWithSimilarInterest(const qreal distance);
109
110     /**
111     * @brief Retrieves location user and friends information from Situare server
112     *
113     */
114     void fetchLocations();
115
116     /**
117     * @brief Translates coordinates to street address via Situare server
118     *
119     * @param coordinates coordinates to be translated
120     */
121     void reverseGeo(const GeoCoordinate &coordinates);
122
123     /**
124     * @brief Updates location to the Situare server
125     *
126     * @param coordinates current cordinates
127     * @param status message
128     * @param publish publish location on Facebook wall
129     */
130     void updateLocation(const GeoCoordinate &coordinates, const QString &status, const bool &publish);
131
132 public slots:
133     /**
134     * @brief Adds tags to the Situare server
135     *
136     * CURRENTLY TAGS ARE UPDATED TO THE LOCAL DATABASE, NOT SITUARE SERVER
137     * @param tags list of user's tags
138     */
139     void addTags(const QStringList &tags);
140
141     /**
142     * @brief Public slot, to clear user data
143     *
144     */
145     void clearUserData();
146
147     /**
148     * @brief Retrieves messages sent to user.
149     */
150     void fetchMessages();
151
152     /**
153     * @brief Retrieves popular tags.
154     *
155     * Tags are fetch from local database instead of Situare server.
156     */
157     void fetchPopularTags();
158
159     /**
160     * @brief Removes message.
161     *
162     * @param id message ID
163     */
164     void removeMessage(const QString &id);
165
166     /**
167     * @brief Removes tags.
168     *
169     * @param tags list of tags to remove
170     */
171     void removeTags(const QStringList &tags);
172
173     /**
174     * @brief Public slot, which indicates when http request has been completed
175     *
176     * @param reply storage for http reply
177     */
178     void requestFinished(QNetworkReply *reply);
179
180     /**
181     * @brief Searches people by tag name.
182     *
183     * @param tag tag name
184     */
185     void searchPeopleByTag(const QString &tag);
186
187     /**
188     * @brief Sends a message to a person.
189     *
190     * @param receiverId Facebook user ID
191     * @param message message text
192     * @param message coordinates
193     */
194     void sendMessage(const QString &receiverId, const QString &message,
195                      const GeoCoordinate &coordinates = GeoCoordinate());
196
197     /**
198       * @brief Update session data
199       *
200       * @param session New session data
201       */
202     void updateSession(const QString &session);
203
204 private:
205     /**
206     * @brief Requests ImageFetcher if user/friend has a profile image
207     *        uses members: m_user and m_friendsList
208     *
209     * @param imageUrlList list of image urls
210     */
211     void addProfileImages(const QHash<QString, QUrl> &imageUrlList);
212
213     /**
214       * @brief Append access_token and other session data to the reques url
215       *
216       * @param[in,out] requestUrl Request URL with other request parameters and ending to &
217       */
218     void appendAccessToken(QString &requestUrl);
219
220     /**
221       * @brief Build and send request
222       *
223       * Appends script pathname and parameters to the server base URL. Access token is appended and
224       * the request sent if the access token is available, otherwise the request is queued.
225       *
226       * @param script Requested script pathname
227       * @param parameters Hash containing parameter key/value pairs.
228       */
229     void buildRequest(const QString &script, const QHash<QString,QString> &parameters);
230
231     /**
232       * @brief Convert coordinate value in degrees (double) to string with enough precision
233       *
234       * @param degrees Coordinate value in degrees
235       * @returns Coordinate value as string
236       */
237     QString degreesToString(double degrees);
238     
239     /**
240     * @brief Returns reuquest script's name.
241     *
242     * @param url url to check
243     * @return RequestName
244     */
245     SituareService::RequestName getRequestName(const QUrl &url) const;
246
247     /**
248     * @brief Parses interesting people data from JSON string
249     *
250     * @param interestingPeopleData interesting people data QVariant tree
251     */
252     void parseInterestingPeopleData(const QVariant &interestingPeopleData);
253
254     /**
255     * @brief Parses messages data from JSON string
256     *
257     * @param messagesData messages data QVariant tree
258     */
259     void parseMessagesData(const QVariant &messagesData);
260
261     /**
262     * @brief Parses popular tags data from JSON string
263     *
264     * @param popularTagsData popular tags data QVariant tree
265     */
266     void parsePopularTagsData(const QVariant &popularTagsData);
267
268     /**
269     * @brief Parses reply from JSON string
270     *
271     * Calls different parse methods or emits error signal if response contains error status.
272     */
273     void parseReply(const QByteArray &jsonReply, RequestName requestName);
274
275     /**
276     * @brief Parses reverse geo data
277     *
278     * @param reverseGeoData reverse geo data QVariant tree
279     */
280     void parseReverseGeoData(const QVariant &reverseGeoData);
281
282     /**
283     * @brief Parses user tags data from JSON string
284     *
285     * @param userTagsData user tags data QVariant tree
286     */
287     void parseUserTagsData(const QVariant &userTagsData);
288
289     /**
290     * @brief Parses user and friend data from JSON string
291     *
292     * @param userData user data QVariant tree
293     */
294     void parseUserData(const QVariant &userData);
295
296     /**
297       * @brief Send request
298       *
299       * @param requestUrl Request URL containing also all parameters
300       */
301     void sendRequest(const QString &requestUrl);
302
303 private slots:
304     /**
305     * @brief Slot for received images
306     *
307     * @param id image ID
308     * @param image image pixmap
309     */
310     void imageReceived(const QString &id, const QPixmap &image);
311
312 /*******************************************************************************
313  * SIGNALS
314  ******************************************************************************/
315 signals:
316     /**
317     * @brief Signals error
318     *
319     * @param context error context
320     * @param error error code
321     */
322     void error(const int context, const int error);
323
324     /**
325     * @brief Signal for image fetching
326     *
327     * @param id Image id
328     * @param url Image url
329     */
330     void fetchImage(const QString &id, const QUrl &url);
331
332     /**
333     * @brief Signals when image is downloaded
334     *
335     * @param id image ID
336     * @param image image pixmap
337     */
338     void imageReady(const QString &id, const QPixmap &image);
339
340     /**
341     * @brief Signal when fetchPeopleWithSimilarInterest request is finished
342     *
343     * @param friends list of friends
344     * @param others list of other people
345     */
346     void interestingPeopleReceived(QList<User> &friends, QList<User> &others);
347
348     /**
349     * @brief Signal when fetchMessages request is finished
350     *
351     * @param messages list of messages sent to user
352     */
353     void messagesReceived(QList<Message> &received, QList<Message> &sent);
354
355     /**
356     * @brief Signals when fetchPopularTags request is finished
357     *
358     * @param popularTags list of popular tags
359     */
360     void popularTagsReceived(QHash<QString, QString> &popularTags);
361
362     /**
363     * @brief Signals when address data is retrieved
364     *
365     * @param address Street address
366     */
367     void reverseGeoReady(const QString &address);
368
369     /**
370     * @brief Signals when updateLocation request finished successfully
371     */
372     void updateWasSuccessful(SituareService::SuccessfulMethod successfulMethod);
373
374     /**
375     * @brief Signals when user data is retrieved
376     *
377     * @param user instance of user
378     * @param friendList list of friends
379     */
380     void userDataChanged(User *user, QList<User *> &friendList);
381
382     /**
383     * @brief Signals when getTags request is finished
384     *
385     * @param userTags list of user tags
386     */
387     void userTagsReceived(QHash<QString, QString> &userTags);
388
389 /*******************************************************************************
390  * DATA MEMBERS
391  ******************************************************************************/
392 private:
393     bool m_defaultImage;    ///< Indicates if some of the friends/user doesn't have a image
394
395     QList<QNetworkReply *> m_currentRequests;       ///< List of current http requests
396     QList<User *> m_friendsList;                    ///< List of friends(User)
397
398     QString m_session;                          ///< Session data
399
400     Database *m_database;                       ///< Instance of the database
401     ImageFetcher *m_imageFetcher;               ///< Instance of the image fetcher    
402     NetworkAccessManager *m_networkManager;     ///< Pointer to QNetworkAccessManager
403     User *m_user;                               ///< Pointer to User
404 };
405
406 #endif // SITUARESERVICE_H