1 |
|
2 // Include files |
|
3 #include "sampleplugin.h" |
|
4 #include <QNetworkRequest> |
|
5 #include <QNetworkAccessManager> |
|
6 #include <qfile.h> |
|
7 #include <stdio.h> |
|
8 |
|
9 /** |
|
10 * Constructor with default argument |
|
11 * @param aUtil The SmfPluginUtil instance. The plugins can |
|
12 * call the method getAuthKeys() of this class, with its pluginID to |
|
13 * get the OAuth keys, keys are returned only if this plugin is |
|
14 * authorised by Smf franework |
|
15 */ |
|
16 SamplePlugin::SamplePlugin( SmfPluginUtil *aUtil ) |
|
17 { |
|
18 m_provider = new SampleProviderBase(); |
|
19 m_util = aUtil; |
|
20 } |
|
21 |
|
22 /** |
|
23 * Destructor |
|
24 */ |
|
25 SamplePlugin::~SamplePlugin( ) |
|
26 { |
|
27 if(m_provider) |
|
28 delete m_provider; |
|
29 } |
|
30 |
|
31 /** |
|
32 * Method to get a list of pictures |
|
33 * @param aRequest [out] The request data to be sent to network |
|
34 * @param aPageNum The page to be extracted |
|
35 * @param aItemsPerPage Number of items per page |
|
36 * @return SmfPluginError Plugin error if any, else SmfPluginErrNone |
|
37 */ |
|
38 SmfPluginError SamplePlugin::pictures( SmfPluginRequestData &aRequest, |
|
39 const int aPageNum, |
|
40 const int aItemsPerPage ) |
|
41 { |
|
42 SmfPluginError error = SmfPluginErrInvalidRequest; |
|
43 |
|
44 // invalid arguments |
|
45 if( aPageNum < 0 || aItemsPerPage < 0 ) |
|
46 return error; |
|
47 else |
|
48 { |
|
49 // Create a map of the arguments keys and their repective values |
|
50 QMultiMap<QByteArray, QByteArray> params; |
|
51 QString pageNum, itemPerPage; |
|
52 pageNum.number(aPageNum); |
|
53 itemPerPage.number(aItemsPerPage); |
|
54 params.insert("method", "getpictures"); |
|
55 params.insert("pagenumber", pageNum.toAscii()); |
|
56 params.insert("itemsperpage", itemPerPage.toAscii()); |
|
57 |
|
58 QNetworkAccessManager::Operation type = QNetworkAccessManager::GetOperation; |
|
59 SmfSignatureMethod signMethod = HMAC_SHA1; |
|
60 SmfParsingMode mode = ParseForInlineQuery; |
|
61 |
|
62 error = createRequest(aRequest, type, signMethod, params, mode, NULL); |
|
63 } |
|
64 return error; |
|
65 } |
|
66 |
|
67 |
|
68 /** |
|
69 * Method called by plugins to generate a request data |
|
70 * @param aRequest [out] The request data to be sent to network |
|
71 * @param aOperation The type of http operation |
|
72 * @param aSignatureMethod The signature method to be used |
|
73 * @param aParams A map of parameters to its values |
|
74 * @param aMode The mode of creation of the request |
|
75 * @param aPostData The data to be posted (for HTTP POST |
|
76 * only, else it will be NULL) |
|
77 * @return SmfPluginError Plugin error if any, else SmfPluginErrNone |
|
78 */ |
|
79 SmfPluginError SamplePlugin::createRequest( SmfPluginRequestData &aRequest, |
|
80 const QNetworkAccessManager::Operation aOperation, |
|
81 const SmfSignatureMethod aSignatureMethod, |
|
82 QMultiMap<QByteArray, QByteArray> &aParams, |
|
83 const SmfParsingMode aMode, |
|
84 QBuffer *aPostData ) |
|
85 { |
|
86 SmfPluginError error; |
|
87 QString url = m_provider->serviceUrl().toString(); |
|
88 |
|
89 // Get the oAuth keys from The Smf Server |
|
90 QMap<QString, QString> keys; |
|
91 QString registrationToken = retrievePrivateRegToken(); |
|
92 m_util->getAuthKeys(keys, registrationToken, m_provider->pluginId()); |
|
93 |
|
94 // Unable to get the tokens |
|
95 if(keys.isEmpty()) |
|
96 error = SmfPluginErrInvalidApplication; |
|
97 else |
|
98 { |
|
99 |
|
100 // Get the token and token secret from keys |
|
101 QByteArray token; |
|
102 QByteArray tokenSecret; |
|
103 token.append(keys.value("oauth_token")); |
|
104 tokenSecret.append(keys.value("oauth_token_secret")); |
|
105 |
|
106 // convert the parameters to string and sign it |
|
107 QByteArray content = m_util->createParameterString(url, aOperation, token, tokenSecret, |
|
108 aSignatureMethod, aParams, aMode ); |
|
109 |
|
110 // Unable to create the signed string |
|
111 if(content.isEmpty()) |
|
112 error = SmfPluginErrInvalidRequest; |
|
113 else |
|
114 { |
|
115 // add the parameter string to the URL |
|
116 url.append(content); |
|
117 |
|
118 // set the url of the request |
|
119 aRequest.iNetworkRequest.setUrl(QUrl(url)); |
|
120 |
|
121 // set the type of http operation to be performed |
|
122 aRequest.iHttpOperationType = aOperation; |
|
123 |
|
124 // As it is a GET operation, set iPostData to NULL |
|
125 aRequest.iPostData = aPostData; |
|
126 |
|
127 // For successful creation of request |
|
128 error = SmfPluginErrNone; |
|
129 } |
|
130 } |
|
131 return error; |
|
132 } |
|
133 |
|
134 |
|
135 /** |
|
136 * Method to get a description |
|
137 * @param aRequest [out] The request data to be sent to network |
|
138 * @param aImage The image abot which the description is required |
|
139 * @return SmfPluginError Plugin error if any, else SmfPluginErrNone |
|
140 */ |
|
141 SmfPluginError SamplePlugin::description( SmfPluginRequestData &aRequest, |
|
142 const SmfPicture &aImage ) |
|
143 { |
|
144 SmfPluginError error; |
|
145 |
|
146 // Create a map of the arguments keys and their repective values |
|
147 QMultiMap<QByteArray, QByteArray> params; |
|
148 params.insert("method", "getpictureDescription"); |
|
149 params.insert("photoId", aImage.id().toAscii()); |
|
150 |
|
151 QNetworkAccessManager::Operation type = QNetworkAccessManager::GetOperation; |
|
152 SmfSignatureMethod signMethod = HMAC_SHA1; |
|
153 SmfParsingMode mode = ParseForInlineQuery; |
|
154 |
|
155 error = createRequest(aRequest, type, signMethod, params, mode, NULL); |
|
156 |
|
157 return error; |
|
158 } |
|
159 |
|
160 /** |
|
161 * Method to upload a picture |
|
162 * @param aRequest [out] The request data to be sent to network |
|
163 * @param aImage The image to be uploaded |
|
164 * @return SmfPluginError Plugin error if any, else SmfPluginErrNone |
|
165 */ |
|
166 SmfPluginError SamplePlugin::upload( SmfPluginRequestData &aRequest, |
|
167 const SmfPicture &aImage ) |
|
168 { |
|
169 SmfPluginError error = SmfPluginErrInvalidRequest; |
|
170 |
|
171 // Create a map of the arguments keys and their repective values |
|
172 QMultiMap<QByteArray, QByteArray> params; |
|
173 params.insert("method", "upload"); |
|
174 params.insert("title", aImage.title().toAscii()); |
|
175 params.insert("owner", aImage.owner().toAscii()); |
|
176 params.insert("description", aImage.description().toAscii()); |
|
177 params.insert("tags", aImage.tags().join(" ").toAscii()); |
|
178 switch(aImage.visibility()) |
|
179 { |
|
180 case SMFVisibilityFriend: |
|
181 params.insert("isFriend", "true"); |
|
182 break; |
|
183 case SMFVisibilityPublic: |
|
184 params.insert("isPublic", "true"); |
|
185 break; |
|
186 case SMFVisibilityFamily: |
|
187 params.insert("isFamily", "true"); |
|
188 break; |
|
189 case SMFVisibilityGroup: |
|
190 params.insert("isGroup", "true"); |
|
191 break; |
|
192 default:// SMFVisibilityPersonal |
|
193 params.insert("isPrivate", "true"); |
|
194 } |
|
195 |
|
196 QNetworkAccessManager::Operation type = QNetworkAccessManager::PostOperation; |
|
197 SmfSignatureMethod signMethod = HMAC_SHA1; |
|
198 SmfParsingMode mode = ParseForRequestContent; |
|
199 |
|
200 // Write the image as png format to the buffer |
|
201 QByteArray ba; |
|
202 QBuffer buffer(&ba); |
|
203 buffer.open(QIODevice::WriteOnly); |
|
204 aImage.picture().save(&buffer, "PNG"); |
|
205 |
|
206 error = createRequest(aRequest, type, signMethod, params, mode, &buffer); |
|
207 |
|
208 return error; |
|
209 } |
|
210 |
|
211 /** |
|
212 * Method to upload a list of pictures |
|
213 * @param aRequest [out] The request data to be sent to network |
|
214 * @param aImages The list of images to be uploaded |
|
215 * @return SmfPluginError Plugin error if any, else SmfPluginErrNone |
|
216 */ |
|
217 SmfPluginError SamplePlugin::upload( SmfPluginRequestData &aRequest, |
|
218 const QList<SmfPicture> &aImages ) |
|
219 { |
|
220 SmfPluginError error; |
|
221 |
|
222 for(int index = 0; index < aImages.count(); index++) |
|
223 { |
|
224 error = upload(aRequest, aImages.value(index)); |
|
225 if(SmfPluginErrNone != error) |
|
226 break; |
|
227 } |
|
228 return error; |
|
229 } |
|
230 |
|
231 /** |
|
232 * Method to post comment on a picture is available |
|
233 * @param aRequest [out] The request data to be sent to network |
|
234 * @param aImage The image on which comment is to be posted |
|
235 * @param aComment The comment to be posted |
|
236 * @return SmfPluginError Plugin error if any, else SmfPluginErrNone |
|
237 */ |
|
238 SmfPluginError SamplePlugin::postComment( SmfPluginRequestData &aRequest, |
|
239 const SmfPicture &aImage, |
|
240 const SmfComment &aComment ) |
|
241 { |
|
242 SmfPluginError error = SmfPluginErrInvalidRequest; |
|
243 |
|
244 // Create a map of the arguments keys and their repective values |
|
245 QMultiMap<QByteArray, QByteArray> params; |
|
246 params.insert("method", "postComment"); |
|
247 params.insert("photoId", aImage.id().toAscii()); |
|
248 params.insert("comment", "excellent Himalaya"); |
|
249 |
|
250 QNetworkAccessManager::Operation type = QNetworkAccessManager::GetOperation; |
|
251 SmfSignatureMethod signMethod = HMAC_SHA1; |
|
252 SmfParsingMode mode = ParseForInlineQuery; |
|
253 |
|
254 error = createRequest(aRequest, type, signMethod, params, mode, NULL); |
|
255 return error; |
|
256 } |
|
257 |
|
258 /** |
|
259 * This function retrieves the registration token that was provided to Authentication App |
|
260 * while authenticatiing user with the service |
|
261 * |
|
262 * Plugin source codes are not open source - so free to use anything they like |
|
263 */ |
|
264 QString SamplePlugin::retrievePrivateRegToken() |
|
265 { |
|
266 |
|
267 /** |
|
268 * This is a private implementation - |
|
269 * implementer might choose to use registry to store/retrieve this token |
|
270 * or to write encrypted (symmetric) token to a file kept at known dir |
|
271 */ |
|
272 QFile qf("/resource/data/sampleplugindata.dat"); |
|
273 qf.open(QIODevice::ReadOnly); |
|
274 QByteArray qba = qf.read(20); |
|
275 qba.chop(5); |
|
276 QString rs(qba.toBase64()); |
|
277 return rs; |
|
278 } |
|
279 |
|
280 |
|
281 /** |
|
282 * Method to get the provider information |
|
283 * @return Instance of SmfProviderBase |
|
284 */ |
|
285 SmfProviderBase* SamplePlugin::getProviderInfo( ) |
|
286 { |
|
287 return m_provider; |
|
288 } |
|
289 |
|
290 /** |
|
291 * Method to get the result for a network request. |
|
292 * @param aTransportResult The result of transport operation |
|
293 * @param aReply The QNetworkReply instance for the request |
|
294 * @param aResult [out] An output parameter to the plugin manager.If the |
|
295 * return value is SmfSendRequestAgain, QVariant will be of type |
|
296 * SmfPluginRequestData. |
|
297 * For SmfGalleryPlugin: If last operation was pictures(), aResult will |
|
298 * be of type QList<SmfPicture>. If last operation was description(), |
|
299 * aResult will be of type QString. If last operation was upload() or |
|
300 * postComment(), aResult will be of type bool. |
|
301 * @param aRetType [out] SmfPluginRetType |
|
302 * @param aPageResult [out] The SmfResultPage structure variable |
|
303 */ |
|
304 SmfPluginError SamplePlugin::responseAvailable( |
|
305 const SmfTransportResult &aTransportResult, |
|
306 QNetworkReply *aReply, |
|
307 QVariant* aResult, |
|
308 SmfPluginRetType &aRetType, |
|
309 SmfResultPage &aPageResult ) |
|
310 { |
|
311 SmfPluginError error; |
|
312 if(SmfTransportOpNoError == aTransportResult) |
|
313 { |
|
314 // Assuming a JSON response, parse the response |
|
315 QByteArray response = aReply->readAll(); |
|
316 m_provider->updateDataUsage(0, aReply->readBufferSize()); |
|
317 bool parseResult = false; |
|
318 QVariant *result = new QVariant(); |
|
319 /** see http://qjson.sourceforge.net/usage.html for more details */ |
|
320 parseResult = m_util->getJsonHandle()->parse(response, &parseResult); |
|
321 |
|
322 // For parsing error |
|
323 if(!parseResult) |
|
324 { |
|
325 aRetType = SmfRequestError; |
|
326 error = SmfPluginErrInvalidRequest; |
|
327 } |
|
328 |
|
329 else |
|
330 { |
|
331 // The plugins should convert the result to suitable format, |
|
332 // like if last operation was pictures(), result should be converted to the |
|
333 // type QList<SmfPicture>. If last operation was description(), result should |
|
334 // be converted to the type QString. If last operation was upload() or |
|
335 // postComment(), result should be converted to the type bool. |
|
336 |
|
337 // After conversion, assign the value os result to aResult |
|
338 aResult = result; |
|
339 |
|
340 // if the request is complete |
|
341 aRetType = SmfRequestComplete; |
|
342 |
|
343 // if request need to be sent again |
|
344 aRetType = SmfSendRequestAgain; |
|
345 |
|
346 error = SmfPluginErrNone; |
|
347 } |
|
348 } |
|
349 else |
|
350 { |
|
351 error = SmfPluginErrInvalidRequest; |
|
352 aRetType = SmfRequestError; |
|
353 } |
|
354 |
|
355 return error; |
|
356 } |
|
357 |
|
358 |
|
359 /** |
|
360 * Constructor with default argument |
|
361 * @param aParent The parent object |
|
362 */ |
|
363 SampleProviderBase::SampleProviderBase( QObject* aParent ) |
|
364 : SmfProviderBase(aParent) |
|
365 { |
|
366 } |
|
367 |
|
368 /** |
|
369 * Copy Constructor |
|
370 * @param aOther The reference object |
|
371 */ |
|
372 SampleProviderBase::SampleProviderBase( const SampleProviderBase &aOther ) |
|
373 { |
|
374 } |
|
375 |
|
376 /** |
|
377 * Destructor |
|
378 */ |
|
379 SampleProviderBase::~SampleProviderBase( ) |
|
380 { |
|
381 } |
|
382 |
|
383 /** |
|
384 * Method to get the Localisable name of the service. |
|
385 * @return The Localisable name of the service. |
|
386 */ |
|
387 QString SampleProviderBase::serviceName( ) const |
|
388 { |
|
389 return m_serviceName; |
|
390 } |
|
391 |
|
392 /** |
|
393 * Method to get the Logo of the service |
|
394 * @return The Logo of the service |
|
395 */ |
|
396 QImage SampleProviderBase::serviceIcon( ) const |
|
397 { |
|
398 return m_serviceIcon; |
|
399 } |
|
400 |
|
401 /** |
|
402 * Method to get the Readable service description |
|
403 * @return The Readable service description |
|
404 */ |
|
405 QString SampleProviderBase::description( ) const |
|
406 { |
|
407 return m_description; |
|
408 } |
|
409 |
|
410 /** |
|
411 * Method to get the Website of the service |
|
412 * @return The Website of the service |
|
413 */ |
|
414 QUrl SampleProviderBase::serviceUrl( ) const |
|
415 { |
|
416 return m_serviceUrl; |
|
417 } |
|
418 |
|
419 /** |
|
420 * Method to get the URL of the Application providing this service |
|
421 * @return The URL of the Application providing this service |
|
422 */ |
|
423 QUrl SampleProviderBase::applicationUrl( ) const |
|
424 { |
|
425 return m_applicationUrl; |
|
426 } |
|
427 |
|
428 /** |
|
429 * Method to get the Icon of the application |
|
430 * @return The Icon of the application |
|
431 */ |
|
432 QImage SampleProviderBase::applicationIcon( ) const |
|
433 { |
|
434 return m_applicationIcon; |
|
435 } |
|
436 |
|
437 /** |
|
438 * Method to get the Plugin specific ID |
|
439 * @return The Plugin specific ID |
|
440 */ |
|
441 QString SampleProviderBase::pluginId( ) const |
|
442 { |
|
443 return m_pluginId; |
|
444 } |
|
445 |
|
446 /** |
|
447 * Method to get the ID of the authentication application |
|
448 * for this service |
|
449 * @param aProgram The authentication application name |
|
450 * @param aArguments List of arguments required for authentication app |
|
451 * @param aMode Strting mode for authentication application |
|
452 * @return The ID of the authentication application |
|
453 */ |
|
454 QString SampleProviderBase::authenticationApp( QString &aProgram, |
|
455 QStringList & aArguments, |
|
456 QIODevice::OpenModeFlag aMode ) const |
|
457 { |
|
458 return m_authAppId; |
|
459 } |
|
460 |
|
461 /** |
|
462 * Method to get the unique registration ID provided by the |
|
463 * Smf for authorised plugins |
|
464 * @return The unique registration ID/token provided by the Smf for |
|
465 * authorised plugins |
|
466 */ |
|
467 QString SampleProviderBase::smfRegistrationId( ) const |
|
468 { |
|
469 return m_smfRegToken; |
|
470 } |
|
471 |
|
472 /** |
|
473 * Method to get the data usage of each plugin |
|
474 * @return The data usage structure |
|
475 */ |
|
476 SmfPluginDataUsage SampleProviderBase::getDataUsage( ) const |
|
477 { |
|
478 return m_dataUsage; |
|
479 } |
|
480 |
|
481 /** |
|
482 * Method to update the data usage of this plugin. This method is called |
|
483 * after the plugin sends request to Plugin manager and after it receives |
|
484 * data from plugin manager. |
|
485 * @param aBytesSent The number of bytes sent, when this argument has |
|
486 * some value other than 1, aBytesReceived should be zero. |
|
487 * @param aBytesReceived The number of bytes received, when this argument |
|
488 * has some value other than 1, aBytesSent should be zero. |
|
489 * @return Returns true if success else returns false |
|
490 */ |
|
491 bool SampleProviderBase::updateDataUsage( const uint &aBytesSent, |
|
492 const uint &aBytesReceived ) |
|
493 { |
|
494 bool ret = true; |
|
495 if( aBytesSent && !aBytesReceived ) |
|
496 m_dataUsage.iBytesSent += aBytesSent; |
|
497 else if( !aBytesSent && aBytesReceived ) |
|
498 m_dataUsage.iBytesReceived += aBytesReceived; |
|
499 else |
|
500 // don't update m_dataUsage, error in arguments |
|
501 ret = false; |
|
502 |
|
503 return ret; |
|
504 } |
|
505 |
|
506 /* |
|
507 * Export Macro |
|
508 * plugin name : sampleplugin |
|
509 * plugin class : SamplePlugin |
|
510 */ |
|
511 //Q_EXPORT_PLUGIN2( sampleplugin, SamplePlugin ) |
|