diff -r b5d63d5fc252 -r a469c0e6e7fb example/fbpostproviderplugin/fbpostproviderplugin.cpp --- a/example/fbpostproviderplugin/fbpostproviderplugin.cpp Mon Jun 07 11:43:45 2010 +0100 +++ b/example/fbpostproviderplugin/fbpostproviderplugin.cpp Wed Jun 23 19:51:49 2010 +0530 @@ -1,21 +1,44 @@ +/** + * Copyright (c) 2010 Sasken Communication Technologies Ltd. + * All rights reserved. + * This component and the accompanying materials are made available + * under the terms of the "Eclipse Public License v1.0" + * which accompanies this distribution, and is available + * at the URL "http://www.eclipse.org/legal/epl-v10.html" + * + * Initial Contributors: + * Chandradeep Gandhi, Sasken Communication Technologies Ltd - Initial contribution + * + * Contributors: + * Nalina Hariharan + * + * Description: + * The Plugin that manages post operations on the logged in user's facebook account + * + */ // Include files #include #include #include -#include #include -#include +#include +#include +#include +#ifdef SMF_XMLPARSING #include +#endif #include "fbpostproviderplugin.h" -// Added for flickr testing - start - put your registered app's keys here -static const QString apiKey = ""; -static const QString apiSecret = ""; -static const QString sessionKey = ""; -static const QString sessionSecret = ""; - +static int chance = 0; +QString uid; +#ifdef SMF_XMLPARSING +SmfPost mypost; +SmfContact contact; +QString currentId; +#endif +QMap idNameMap; /** * Method called by plugins to generate a signature string from a base string @@ -24,8 +47,8 @@ */ QString FBPostProviderPlugin::generateSignature(const QString aBaseString) { - writeLog("FBPostProviderPlugin::generateSignature"); - + qDebug()<<"Inside FBPostProviderPlugin::generateSignature()"; + // Create md5 hash of the signature string QByteArray byteArray; byteArray.insert(0, aBaseString.toAscii()); @@ -35,21 +58,6 @@ return returnString; } - -/** - * Method called by plugins for logging - * @param log string to be logged - */ -void FBPostProviderPlugin::writeLog(QString log) const - { - QFile file("c:\\data\\PluginLogs.txt"); - if (!file.open(QIODevice::Append | QIODevice::Text)) - ; - QTextStream out(&file); - out << log << "\n"; - file.close(); - } - /** * Destructor */ @@ -60,49 +68,53 @@ } /** - * Method that returns maximum no of chars (unicode) that service - * provider can post without truncation. Negative value means + * Method that returns maximum no of chars (unicode) that service + * provider can post without truncation. Negative value means * no limit * @return Max characters that can be posted without truncation */ qint32 FBPostProviderPlugin::maxCharsInPost( ) const - { + { + qDebug()<<"Inside FBPostProviderPlugin::maxCharsInPost()"; qint32 maxCharsInPost = 256; return maxCharsInPost; - } + } /** - * Method that returns maximum no of items that can be returned - * in a single query to getPosts. Negative value means feature + * Method that returns maximum no of items that can be returned + * in a single query to getPosts. Negative value means feature * not supported. * @return Max items that can be returned in a single query */ qint32 FBPostProviderPlugin::maxItems( ) const - { + { + qDebug()<<"Inside FBPostProviderPlugin::maxItems()"; qint32 maxItems = 10; return maxItems; - } + } /** - * FBPostProviderPlugin::supportedFormats ( ) const - { + { + qDebug()<<"Inside FBPostProviderPlugin::supportedFormats()"; QVector data; return data; - } + } /** * Method that returns whether this SP supports Appearence - * @return Returns true if Appearance is supported, else false. + * @return Returns true if Appearance is supported, else false. * @see SmfAppearenceInfo */ bool FBPostProviderPlugin::supportsAppearence ( ) const - { + { + qDebug()<<"Inside FBPostProviderPlugin::supportsAppearence()"; return false; - } + } /** * Method to get the latest posts @@ -114,53 +126,218 @@ */ SmfPluginError FBPostProviderPlugin::retrieve( SmfPluginRequestData &aRequest, const SmfContact *aUser, - const int aPageNum , + const int aPageNum , const int aItemsPerPage ) { Q_UNUSED(aUser) - writeLog("Inside FBPostProviderPlugin::retrieve"); + qDebug()<<"Inside FBPostProviderPlugin::retrieve()"; + + //// Currently considering for self contact , ie, omitting aUser + if(0 == chance) + return getFacebookUserId(aRequest); + else + return getPosts(aRequest, aPageNum , aItemsPerPage); + } + + +/** + * Method to get the user's facebook ID + * @param aRequest [out] The request data to be sent to network + * @return SmfPluginError Plugin error if any, else SmfPluginErrNone + */ +SmfPluginError FBPostProviderPlugin::getFacebookUserId( + SmfPluginRequestData &aRequest ) + { + qDebug()<<"Inside FBPostProviderPlugin::getFacebookUserId()"; + + SmfPluginError error = SmfPluginErrUserNotLoggedIn; + +#if 1 +// Reading the keys, CSM Stubbed - START + QFile file("c:\\data\\FacebookKeys.txt"); + if (!file.open(QIODevice::ReadOnly)) + { + qDebug()<<"File to read the keys could not be opened"; + return error; + } + + qDebug()<<"Key file read, going to parse the key values from file"; + + QByteArray arr = file.readAll(); + QList list = arr.split('\n'); + file.close(); - SmfPluginError error = SmfPluginErrInvalidRequest; + QString apiKey(list[0]); + QString apiSecret(list[1]); + QString sessionKey(list[2]); + QString sessionSecret(list[3]); + + qDebug()<<"Api Key = "+apiKey; + qDebug()<<"Api Secret = "+apiSecret; + qDebug()<<"session Key = "+sessionKey; + qDebug()<<"session Secret = "+sessionSecret; +// Reading the keys, CSM Stubbed - END +#endif + + // Get the current date and time and convert it to sec as a string + QString call_id = QString::number(QDateTime::currentDateTime().toTime_t(), 10); + + // Create the API signature string + QString baseString; + baseString.append("api_key="+apiKey); + baseString.append("call_id="+call_id); +#ifdef SMF_XMLPARSING + baseString.append("format=XML"); +#else + baseString.append("format=JSON"); +#endif + baseString.append("method=users.getLoggedInUser"); + baseString.append("session_key="+sessionKey); + baseString.append("ss=1"); + baseString.append("v=1.0"); + baseString.append(sessionSecret); - //// Currently considering for self contatc , ie, omitting aUser + // Create the url + QUrl url("http://api.facebook.com/restserver.php?"); + url.addQueryItem("api_key", apiKey); + url.addQueryItem("call_id", call_id); +#ifdef SMF_XMLPARSING + url.addQueryItem("format", "XML"); +#else + url.addQueryItem("format", "JSON"); +#endif + url.addQueryItem("method", "users.getLoggedInUser"); + url.addQueryItem("session_key", sessionKey); + url.addQueryItem("ss", "1"); + url.addQueryItem("v", "1.0"); + url.addQueryItem("sig", generateSignature(baseString)); + + // Create the request, set the url + aRequest.iNetworkRequest.setUrl(url); + aRequest.iRequestType = SmfContactRetrievePosts; + aRequest.iPostData = NULL; + aRequest.iHttpOperationType = QNetworkAccessManager::GetOperation; + error = SmfPluginErrNone; + + qDebug()<<"Url string is : "< list = arr.split('\n'); + file.close(); + + QString apiKey(list[0]); + QString apiSecret(list[1]); + QString sessionKey(list[2]); + QString sessionSecret(list[3]); + + qDebug()<<"Api Key = "+apiKey; + qDebug()<<"Api Secret = "+apiSecret; + qDebug()<<"session Key = "+sessionKey; + qDebug()<<"session Secret = "+sessionSecret; +// Reading the keys, CSM Stubbed - END +#endif + + // Get the current date and time and convert it to sec as a string + QString call_id = QString::number(QDateTime::currentDateTime().toTime_t(), 10); + + // Create the API signature string + QString baseString; + baseString.append("api_key="+apiKey); + baseString.append("call_id="+call_id); +#ifdef SMF_XMLPARSING + baseString.append("format=XML"); +#else + baseString.append("format=JSON"); +#endif + if(0 == aPageNum) + { + //baseString.append("limit="+QString::number((aItemsPerPage*(aPageNum+1)), 10)); + qDebug()<<"Hardcoding pagenumber and itemperpage to fetch 5 posts"; + int val = 5; + baseString.append("limit="+QString::number(val)); + } + else + baseString.append("limit="+QString::number((aItemsPerPage*aPageNum), 10)); + baseString.append("method=stream.get"); + baseString.append("session_key="+sessionKey); + baseString.append("source_ids="+uid); + baseString.append("ss=1"); + baseString.append("v=1.0"); + baseString.append(sessionSecret); - // Create the url - QUrl url("http://api.facebook.com/restserver.php?"); - url.addQueryItem("api_key", apiKey); - url.addQueryItem("call_id", call_id); - url.addQueryItem("format", "XML"); - url.addQueryItem("method", "stream.get"); - url.addQueryItem("session_key", sessionKey); - url.addQueryItem("ss", "1"); - url.addQueryItem("v", "1.0"); - url.addQueryItem("sig", generateSignature(baseString)); - - // Create the request, set the url - aRequest.iNetworkRequest.setUrl(url); - aRequest.iRequestType = SmfContactRetrievePosts; - aRequest.iPostData = NULL; - aRequest.iHttpOperationType = QNetworkAccessManager::GetOperation; - error = SmfPluginErrNone; + // Create the url + QUrl url("http://api.facebook.com/restserver.php?"); + url.addQueryItem("api_key", apiKey); + url.addQueryItem("call_id", call_id); +#ifdef SMF_XMLPARSING + url.addQueryItem("format", "XML"); +#else + url.addQueryItem("format", "JSON"); +#endif + if(0 == aPageNum) + { +// url.addQueryItem("limit", QString::number((aItemsPerPage*(aPageNum+1)), 10)); + qDebug()<<"Hardcoding pagenumber and itemperpage to fetch 5 posts"; + int val = 5; + url.addQueryItem("limit", QString::number(val)); } - writeLog("Url string is : "+aRequest.iNetworkRequest.url().toString()); + else + url.addQueryItem("limit", QString::number((aItemsPerPage*aPageNum), 10)); + url.addQueryItem("method", "stream.get"); + url.addQueryItem("session_key", sessionKey); + url.addQueryItem("source_ids",uid); + url.addQueryItem("ss", "1"); + url.addQueryItem("v", "1.0"); + url.addQueryItem("sig", generateSignature(baseString)); + + // Create the request, set the url + aRequest.iNetworkRequest.setUrl(url); + aRequest.iRequestType = SmfContactRetrievePosts; + aRequest.iPostData = NULL; + aRequest.iHttpOperationType = QNetworkAccessManager::GetOperation; + error = SmfPluginErrNone; + + qDebug()<<"Url string is : "<().guid(); + + if( (0 == aPostData.description().size()) || (0 == aContact.value("Guid").value().guid().size()) ) + { + qDebug()<<"Invalid arguments"; + return error; + } + + qDebug()<<"Valid arguments"; + +#if 1 +// Reading the keys, CSM Stubbed - START + QFile file("c:\\data\\FacebookKeys.txt"); + if (!file.open(QIODevice::ReadOnly)) + { + qDebug()<<"File to read the keys could not be opened"; + return SmfPluginErrUserNotLoggedIn; + } + + qDebug()<<"Key file read, going to parse the key values from file"; + + QByteArray arr = file.readAll(); + QList list = arr.split('\n'); + file.close(); + + QString apiKey(list[0]); + QString apiSecret(list[1]); + QString sessionKey(list[2]); + QString sessionSecret(list[3]); + + qDebug()<<"Api Key = "<().guid()); + baseString.append("v=1.0"); + baseString.append(sessionSecret); + + // Create the url + QUrl url("http://api.facebook.com/restserver.php?"); + url.addQueryItem("api_key", apiKey); + url.addQueryItem("call_id", call_id); +#ifdef SMF_XMLPARSING + url.addQueryItem("format", "XML"); +#else + url.addQueryItem("format", "JSON"); +#endif + url.addQueryItem("message", aPostData.description()); + url.addQueryItem("method", "stream.publish"); + url.addQueryItem("session_key", sessionKey); + url.addQueryItem("ss", "1"); + url.addQueryItem("target_id", aContact.value("Guid").value().guid()); + url.addQueryItem("v", "1.0"); + url.addQueryItem("sig", generateSignature(baseString)); + + // Create the request, set the url + aRequest.iNetworkRequest.setUrl(url); + aRequest.iRequestType = SmfContactPostDirected; + aRequest.iPostData = NULL; + aRequest.iHttpOperationType = QNetworkAccessManager::GetOperation; + error = SmfPluginErrNone; + + qDebug()<<"Url string is : "<initialize(); @@ -326,77 +594,389 @@ /** * Method to get the result for a network request. + * @param aOperation The type of operation to be requested * @param aTransportResult The result of transport operation * @param aResponse The QByteArray instance containing the network response. - * The plugins should delete this instance once they have read the + * The plugins should delete this instance once they have read the * data from it. - * @param aResult [out] An output parameter to the plugin manager.If the - * return value is SmfSendRequestAgain, QVariant will be of type + * @param aResult [out] An output parameter to the plugin manager.If the + * return value is SmfSendRequestAgain, QVariant will be of type * SmfPluginRequestData. - * For SmfPostProviderPlugin: If last operation was retrieve(), aResult will be - * of type QList. If last operation was post() or updatePost() or - * postDirected() or commentOnAPost() or postAppearence() or sharePost(), + * For SmfPostProviderPlugin: If last operation was retrieve(), aResult will be + * of type QList. If last operation was post() or updatePost() or + * postDirected() or commentOnAPost() or postAppearence() or sharePost(), * aResult will be of type bool * @param aRetType [out] SmfPluginRetType * @param aPageResult [out] The SmfResultPage structure variable */ -SmfPluginError FBPostProviderPlugin::responseAvailable( - const SmfTransportResult &aTransportResult, - QByteArray *aResponse, - QVariant* aResult, +SmfPluginError FBPostProviderPlugin::responseAvailable( + const SmfRequestTypeID aOperation, + const SmfTransportResult &aTransportResult, + QByteArray *aResponse, + QVariant* aResult, SmfPluginRetType &aRetType, SmfResultPage &aPageResult ) { - writeLog("FBPostProviderPlugin::::responseAvailable"); + qDebug()<<"Inside FBPostProviderPlugin::responseAvailable()"; Q_UNUSED(aPageResult) - //This API is slightly changed by Manasij - SmfPluginError error; + SmfPluginError error = SmfPluginErrNetworkError; + + if( !aResponse || (0 == aResponse->size()) ) + { + qDebug()<<"Response is NULL or empty"; + aRetType = SmfRequestError; + return error; + } + + QByteArray response(*aResponse); + delete aResponse; + qDebug()<<"FB response = "<data()); - file.close(); - - QList list; + qDebug()<<"No transport error"; - // For getting contacts - QXmlStreamReader xml(aResponse->data()); - while (!xml.atEnd()) + if(SmfContactRetrievePosts == aOperation) { - xml.readNext(); - if (xml.tokenType() == QXmlStreamReader::StartElement) + qDebug()<<"Response for retrieving posts"; + if(0 == chance) + { + chance = 1; + qDebug()<<"For Getting Current logged in User"; + + QString errStr; + errStr.clear(); + uid.clear(); +#ifdef SMF_XMLPARSING + qDebug()<<"Xml parsing"; + // For getting contacts from xml response + QXmlStreamReader xml(response); + while (!xml.atEnd()) + { + xml.readNext(); + if (xml.tokenType() == QXmlStreamReader::StartElement) + { + if (xml.name() == "users_getLoggedInUser_response") + { + qDebug()<<"users_getLoggedInUser_response tag found"; + QString message(xml.readElementText()); + uid.append(message); + qDebug()<<"current logged in uid = "<parse(response, &ok); + if (!ok) + { + qDebug()<<"An error occurred during json parsing, error = "<errorString(); + aRetType = SmfRequestError; + return SmfPluginErrParsingFailed; + } + else + { + QVariantMap map = result.toMap(); + errStr.append(map["error_msg"].toString()); + } + } + else + { + qDebug()<<"Response is ok, so don't parse"; + uid.append(response); + } +#endif + + if(errStr.size()) + { + qDebug()<<"Response error found = "<setValue(errStr); + } + else + { + qDebug()<<"current logged in uid = "< list; + QString errStr; + errStr.clear(); + +#ifdef SMF_XMLPARSING + qDebug()<<"Xml parsing"; + + // For getting contacts from xml response + QXmlStreamReader xml(response); + while (!xml.atEnd()) + { + xml.readNext(); + + if (xml.tokenType() == QXmlStreamReader::StartElement) + { + if (xml.name() == "post_id") + { + QString message(xml.readElementText()); + mypost.setId(message); + qDebug()<<"post post_id = "<().guid(); + } + else if (xml.name() == "message") + { + QString message(xml.readElementText()); + mypost.setDescription(message); + qDebug()<<"post message = "<().guid()); + QVariant guidVar = QVariant::fromValue(guid); + contact.setValue("Guid", guidVar); + + QContactName contactName; + contactName.setFirstName(idNameMap.value(list[i].owner().value("Guid").value().guid())); + QVariant nameVar = QVariant::fromValue(contactName); + contact.setValue("Name", nameVar); + + list[i].setOwner(contact); + } + } +#else + qDebug()<<"Json parsing"; + + bool ok; + QVariantMap result = m_util->parse(response, &ok).toMap(); + if (!ok) + { + qDebug()<<"An error occurred during json parsing"; + aRetType = SmfRequestError; + return SmfPluginErrParsingFailed; + } + + chance = 0; + + if(response.contains(QByteArray("error_msg"))) + { + errStr.append(result["error_msg"].toString()); + } + else + { + QList list1 = result["posts"].toList(); + QListIterator iter(list1); + while(iter.hasNext()) + { + SmfPost post; + + QVariantMap map2 = iter.next().toMap(); + qDebug()<<"post_id = "< list2 = result["profiles"].toList(); + QListIterator iter2(list2); + while(iter2.hasNext()) + { + QVariantMap map2 = iter2.next().toMap(); + qDebug()<<"owner's id = "<().guid())); + qDebug()<<"Name = "<setValue(list); + else if(SmfTransportOpOperationCanceledError == aTransportResult) + { + qDebug()<<"Operation Cancelled !!!"; + error = SmfPluginErrCancelComplete; aRetType = SmfRequestComplete; - error = SmfPluginErrNone; } else { - error = SmfPluginErrInvalidRequest; + qDebug()<<"Transport Error !!!"; + error = SmfPluginErrNetworkError; aRetType = SmfRequestError; } - delete aResponse; + return error; } @@ -463,6 +1043,25 @@ } /** +* Method to get the list of interfaces that this provider support +* @return List of supported Interafces +*/ +QList FBProviderBase::supportedInterfaces( ) const + { + return m_supportedInterfaces; + } + +/** +* Method to get the list of languages supported by this service provider +* @return a QStringList of languages supported by this service +* provider in 2 letter ISO 639-1 format. +*/ +QStringList FBProviderBase::supportedLanguages( ) const + { + return m_supportedLangs; + } + +/** * Method to get the Plugin specific ID * @return The Plugin specific ID */ @@ -472,27 +1071,27 @@ } /** - * Method to get the ID of the authentication application + * Method to get the ID of the authentication application * for this service * @param aProgram The authentication application name * @param aArguments List of arguments required for authentication app * @param aMode Strting mode for authentication application - * @return The ID of the authentication application + * @return The ID of the authentication application */ -QString FBProviderBase::authenticationApp( QString &aProgram, - QStringList & aArguments, +QString FBProviderBase::authenticationApp( QString &aProgram, + QStringList & aArguments, QIODevice::OpenModeFlag aMode ) const { Q_UNUSED(aProgram) -Q_UNUSED(aArguments) -Q_UNUSED(aMode) + Q_UNUSED(aArguments) + Q_UNUSED(aMode) return m_authAppId; } /** - * Method to get the unique registration ID provided by the + * Method to get the unique registration ID provided by the * Smf for authorised plugins - * @return The unique registration ID/token provided by the Smf for + * @return The unique registration ID/token provided by the Smf for * authorised plugins */ QString FBProviderBase::smfRegistrationId( ) const @@ -500,6 +1099,10 @@ return m_smfRegToken; } +/** + * Method that initializes this class. This method should be called + * from the initialize() method of the FBPostProviderPlugin class + */ void FBProviderBase::initialize() { m_serviceName = "Facebook"; @@ -508,6 +1111,7 @@ m_pluginId = "fbpostproviderplugin.qtplugin"; m_authAppId = "Facebook AuthAppId"; m_smfRegToken = "Facebook RegToken"; + m_supportedInterfaces.append("org.symbian.smf.plugin.contact.posts/v0.2"); }