8923cb8c21b37cdba12479db97423fe4b6f58c4b
[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
66 public:
67
68     /**
69     * Unit test class
70     */
71     friend class TestSituareService;
72
73     enum SuccessfulMethod {SuccessfulUpdateLocation, SuccessfulAddTags, SuccessfulRemoveTags,
74                            SuccessfulSendMessage, SuccessfulRemoveMessage};
75
76     /**
77     * @brief Default constructor
78     *
79     * @param parent instance of parent
80     */
81     SituareService(NetworkAccessManager *networkManager, ImageFetcher *imageFetcher,
82                    QObject *parent = 0);
83
84     /**
85     * @brief Destructor
86     *
87     */
88     ~SituareService();
89
90 /*******************************************************************************
91  * MEMBER FUNCTIONS AND SLOTS
92  ******************************************************************************/
93     /**
94     * @brief Retrieves people with similart interest (same tags).
95     *
96     * People is searched from area defined by maximum distance
97     * @param maximumDistance maximum distance to people
98     */
99     void fetchPeopleWithSimilarInterest(const qreal distance);
100
101     /**
102     * @brief Retrieves location user and friends information from Situare server
103     *
104     */
105     void fetchLocations();
106
107     /**
108     * @brief Translates coordinates to street address via Situare server
109     *
110     * @param coordinates coordinates to be translated
111     */
112     void reverseGeo(const GeoCoordinate &coordinates);
113
114     /**
115     * @brief Updates location to the Situare server
116     *
117     * @param coordinates current cordinates
118     * @param status message
119     * @param publish publish location on Facebook wall
120     */
121     void updateLocation(const GeoCoordinate &coordinates, const QString &status, const bool &publish);
122
123 public slots:
124     /**
125     * @brief Adds tags to the Situare server
126     *
127     * CURRENTLY TAGS ARE UPDATED TO THE LOCAL DATABASE, NOT SITUARE SERVER
128     * @param tags list of user's tags
129     */
130     void addTags(const QStringList &tags);
131
132     /**
133     * @brief Public slot, to clear user data
134     *
135     */
136     void clearUserData();
137
138     /**
139     * @brief Retrieves messages sent to user.
140     */
141     void fetchMessages();
142
143     /**
144     * @brief Retrieves popular tags.
145     *
146     * Tags are fetch from local database instead of Situare server.
147     */
148     void fetchPopularTags();
149
150     /**
151     * @brief Removes message.
152     *
153     * @param id message ID
154     */
155     void removeMessage(const QString &id);
156
157     /**
158     * @brief Removes tags.
159     *
160     * @param tags list of tags to remove
161     */
162     void removeTags(const QStringList &tags);
163
164     /**
165     * @brief Public slot, which indicates when http request has been completed
166     *
167     * @param reply storage for http reply
168     */
169     void requestFinished(QNetworkReply *reply);
170
171     /**
172     * @brief Searches people by tag name.
173     *
174     * @param tag tag name
175     */
176     void searchPeopleByTag(const QString &tag);
177
178     /**
179     * @brief Sends a message to a person.
180     *
181     * @param receiverId Facebook user ID
182     * @param message message text
183     * @param message coordinates
184     */
185     void sendMessage(const QString &receiverId, const QString &message,
186                      const GeoCoordinate &coordinates = GeoCoordinate());
187
188     /**
189       * @brief Update session data
190       *
191       * @param session New session data
192       */
193     void updateSession(const QString &session);
194
195 private:
196     /**
197     * @brief Requests ImageFetcher if user/friend has a profile image
198     *        uses members: m_user and m_friendsList
199     *
200     * @param imageUrlList list of image urls
201     */
202     void addProfileImages(const QHash<QString, QUrl> &imageUrlList);
203
204     /**
205       * @brief Append access_token and other session data to the reques url
206       *
207       * @param[in,out] requestUrl Request URL with other request parameters and ending to &
208       */
209     void appendAccessToken(QString &requestUrl);
210
211     /**
212       * @brief Build and send request
213       *
214       * Appends script pathname and parameters to the server base URL. Access token is appended and
215       * the request sent if the access token is available, otherwise the request is queued.
216       *
217       * @param script Requested script pathname
218       * @param parameters Hash containing parameter key/value pairs.
219       */
220     void buildRequest(const QString &script, const QHash<QString,QString> &parameters);
221
222     /**
223       * @brief Convert coordinate value in degrees (double) to string with enough precision
224       *
225       * @param degrees Coordinate value in degrees
226       * @returns Coordinate value as string
227       */
228     QString degreesToString(double degrees);
229     
230     /**
231     * @brief Returns reuquest script's name.
232     *
233     * @param url url to check
234     * @return RequestName
235     */
236     SituareService::RequestName getRequestName(const QUrl &url) const;
237
238     /**
239     * @brief Temporary method to get tags.
240     *
241     * Tags are fetch from local database instead of Situare server.
242     * @param userId
243     * @return QStringList list of tags
244     */
245     QHash<QString, QString> getTags(const QString &userId);
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 and friend data from JSON string
284     *
285     * @param userData user data QVariant tree
286     */
287     void parseUserData(const QVariant &userData);
288
289     /**
290       * @brief Send request
291       *
292       * @param requestUrl Request URL containing also all parameters
293       */
294     void sendRequest(const QString &requestUrl);
295
296 private slots:
297     /**
298     * @brief Slot for received images
299     *
300     * @param id image ID
301     * @param image image pixmap
302     */
303     void imageReceived(const QString &id, const QPixmap &image);
304
305 /*******************************************************************************
306  * SIGNALS
307  ******************************************************************************/
308 signals:
309     /**
310     * @brief Signals error
311     *
312     * @param context error context
313     * @param error error code
314     */
315     void error(const int context, const int error);
316
317     /**
318     * @brief Signal for image fetching
319     *
320     * @param id Image id
321     * @param url Image url
322     */
323     void fetchImage(const QString &id, const QUrl &url);
324
325     /**
326     * @brief Signals when image is downloaded
327     *
328     * @param id image ID
329     * @param image image pixmap
330     */
331     void imageReady(const QString &id, const QPixmap &image);
332
333     /**
334     * @brief Signal when fetchPeopleWithSimilarInterest request is finished
335     *
336     * @param friends list of friends
337     * @param others list of other people
338     */
339     void interestingPeopleReceived(QList<User> &friends, QList<User> &others);
340
341     /**
342     * @brief Signal when fetchMessages request is finished
343     *
344     * @param messages list of messages sent to user
345     */
346     void messagesReceived(QList<Message> &received, QList<Message> &sent);
347
348     /**
349     * @brief Signals when fetchPopularTags request is finished
350     *
351     * @param popularTags list of popular tags
352     */
353     void popularTagsReceived(QHash<QString, QString> &popularTags);
354
355     /**
356     * @brief Signals when address data is retrieved
357     *
358     * @param address Street address
359     */
360     void reverseGeoReady(const QString &address);
361
362     /**
363     * @brief Signals when updateLocation request finished successfully
364     */
365     void updateWasSuccessful(SituareService::SuccessfulMethod successfulMethod);
366
367     /**
368     * @brief Signals when user data is retrieved
369     *
370     * @param user instance of user
371     * @param friendList list of friends
372     */
373     void userDataChanged(User *user, QList<User *> &friendList);
374
375 /*******************************************************************************
376  * DATA MEMBERS
377  ******************************************************************************/
378 private:
379     bool m_defaultImage;    ///< Indicates if some of the friends/user doesn't have a image
380
381     QList<QNetworkReply *> m_currentRequests;       ///< List of current http requests
382     QList<User *> m_friendsList;                    ///< List of friends(User)
383
384     QString m_session;                          ///< Session data
385
386     Database *m_database;                       ///< Instance of the database
387     ImageFetcher *m_imageFetcher;               ///< Instance of the image fetcher    
388     NetworkAccessManager *m_networkManager;     ///< Pointer to QNetworkAccessManager
389     User *m_user;                               ///< Pointer to User
390 };
391
392 #endif // SITUARESERVICE_H