example/sampleplugin/sampleplugin.cpp
changeset 6 c39a6cfd1fb9
parent 5 edb9dc8273d9
child 7 be09cf1f39dd
equal deleted inserted replaced
5:edb9dc8273d9 6:c39a6cfd1fb9
     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 )