example/fbpostproviderplugin/fbpostproviderplugin.cpp
author cgandhi <chandradeep.gandhi@sasken.com>
Tue, 18 May 2010 17:33:55 +0530
changeset 6 c39a6cfd1fb9
child 14 a469c0e6e7fb
permissions -rw-r--r--
Updating the source code for plugin manager, transport manager, smfserver and smfclient. sample plugins and tests are included


// Include files
#include <QtPlugin>
#include <QCryptographicHash>
#include <QTextFormat>
#include <QTextStream>
#include <QFile>
#include <QNetworkReply>
#include <QXmlStreamReader>

#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 = "";


/**
 * Method called by plugins to generate a signature string from a base string
 * @param aBaseString The base string
 * @return The md5 hash of the base string
 */
QString FBPostProviderPlugin::generateSignature(const QString aBaseString)
	{
	writeLog("FBPostProviderPlugin::generateSignature");

	// Create md5 hash of the signature string
    QByteArray byteArray;
    byteArray.insert(0, aBaseString.toAscii());

    QByteArray md5Hash = QCryptographicHash::hash(byteArray,QCryptographicHash::Md5 ).toHex();
    QString returnString (md5Hash);
    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
 */
FBPostProviderPlugin::~FBPostProviderPlugin( )
	{
	if(m_provider)
		delete m_provider;
	}

/**
 * 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
		{
	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
 * not supported.
 * @return Max items that can be returned in a single query
 */
qint32 FBPostProviderPlugin::maxItems( ) const
		{
	qint32 maxItems = 10;
	return maxItems;
		}

/**
 * <Method that returns all the formatting of posts that this
 * service provider supports. May return 0 items to mean
 * only QString is supported.
 * @return Supported formats of posts
 */
QVector<QTextFormat> FBPostProviderPlugin::supportedFormats ( ) const
		{
	QVector<QTextFormat> data;
	return data;
		}

/**
 * Method that returns whether this SP supports Appearence
 * @return Returns true if Appearance is supported, else false.
 * @see SmfAppearenceInfo
 */
bool FBPostProviderPlugin::supportsAppearence ( ) const
		{
	return false;
		}

/**
 * Method to get the latest posts
 * @param aRequest [out] The request data to be sent to network
 * @param aUser The user's contact in this SP, omit for self contact
 * @param aPageNum The page to be extracted
 * @param aItemsPerPage Number of items per page
 * @return SmfPluginError Plugin error if any, else SmfPluginErrNone
 */
SmfPluginError FBPostProviderPlugin::retrieve( SmfPluginRequestData &aRequest,
		const SmfContact *aUser,
		const int aPageNum ,
		const int aItemsPerPage  )
	{
	Q_UNUSED(aUser)
	writeLog("Inside FBPostProviderPlugin::retrieve");

	SmfPluginError error = SmfPluginErrInvalidRequest;

	//// Currently considering for self contatc , ie, omitting aUser
	// invalid arguments
	if( aPageNum < 0 || aItemsPerPage < 0 )
		return error;
	else
		{
		// 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);
		baseString.append("format=XML");
		baseString.append("method=stream.get");
		baseString.append("session_key="+sessionKey);
		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;
		}
	writeLog("Url string is : "+aRequest.iNetworkRequest.url().toString());
	return error;
	}

/**
 * Method to update a post to own area.
 * @param aRequest [out] The request data to be sent to network
 * @param aPostData The post data to be posted
 * @param aLocation The location
 * @return SmfPluginError Plugin error if any, else SmfPluginErrNone
 */
SmfPluginError FBPostProviderPlugin::post( SmfPluginRequestData &aRequest,
		const SmfPost &aPostData,
		const SmfLocation &aLocation )
	{
	Q_UNUSED(aRequest)
Q_UNUSED(aPostData)
Q_UNUSED(aLocation)
	SmfPluginError error = SmfPluginErrInvalidRequest;
	return error;
	}

/**
 * Method to update the last post to own area with new data
 * @param aRequest [out] The request data to be sent to network
 * @param aPostData The edited/new data to be posted
 * @return SmfPluginError Plugin error if any, else SmfPluginErrNone
 */
SmfPluginError FBPostProviderPlugin::updatePost( SmfPluginRequestData &aRequest,
		const SmfPost &aPostData )
	{
	Q_UNUSED(aRequest)
Q_UNUSED(aPostData)
	SmfPluginError error = SmfPluginErrInvalidRequest;
	return error;
	}

/**
 * Method to update a post to a particular contact
 * @param aRequest [out] The request data to be sent to network
 * @param aPostData The post data to be posted
 * @param aContact The contact where the data has to be posted
 * @param aLocation The location
 * @return SmfPluginError Plugin error if any, else SmfPluginErrNone
 */
SmfPluginError FBPostProviderPlugin::postDirected( SmfPluginRequestData &aRequest,
		const SmfPost &aPostData,
		const SmfContact &aContact,
		const SmfLocation *aLocation  )
	{
	Q_UNUSED(aRequest)
Q_UNUSED(aPostData)
Q_UNUSED(aContact)
Q_UNUSED(aLocation)
	SmfPluginError error = SmfPluginErrInvalidRequest;
	return error;
	}


/**
 * Method to post a comment on a post.
 * @param aRequest [out] The request data to be sent to network
 * @param aTarget Post on which comment has to be posted
 * @param aComment comment to be posted
 * @param aLocation location data
 */
SmfPluginError FBPostProviderPlugin::commentOnAPost(SmfPluginRequestData &aRequest,
		const SmfPost &aTarget,
		const SmfPost &aComment,
		const SmfLocation *aLocation )
	{
	Q_UNUSED(aRequest)
Q_UNUSED(aTarget)
Q_UNUSED(aComment)
Q_UNUSED(aLocation)
	SmfPluginError error = SmfPluginErrInvalidRequest;
	return error;
	}

/**
 * Method to update the presence information of the user
 * @param aRequest [out] The request data to be sent to network
 * @param aAppearence The appearence information
 * @param aStatus The status string
 * @return SmfPluginError Plugin error if any, else SmfPluginErrNone
 */
SmfPluginError FBPostProviderPlugin::postAppearence( SmfPluginRequestData &aRequest,
		const SmfPresenceInfo &aAppearence,
		const QString &aStatus )
	{
	Q_UNUSED(aRequest)
Q_UNUSED(aAppearence)
Q_UNUSED(aStatus)
	SmfPluginError error = SmfPluginErrInvalidRequest;
	return error;
	}

/**
 * Share a contact's post to user's friends and followers
 * (e.g. retweet in twitter, share on facebook)
 * @param aRequest [out] The request data to be sent to network
 * @param aPostData data to be posted
 * @param aContact contact to which the post belonged
 * @param aEdited whether user changed items within the post
 * @return SmfPluginError Plugin error if any, else SmfPluginErrNone
 */
SmfPluginError FBPostProviderPlugin::sharePost( SmfPluginRequestData &aRequest,
		const SmfPost &aPostData,
		const SmfContact &aContact,
		const bool &aEdited)
	{
	Q_UNUSED(aRequest)
Q_UNUSED(aPostData)
Q_UNUSED(aContact)
Q_UNUSED(aEdited)
	SmfPluginError error = SmfPluginErrInvalidRequest;
	return error;
	}

/**
 * Customised method for SmfPostProviderPlugin interface
 * @param aRequest [out] The request data to be sent to network
 * @param aOperation The operation type (should be known between
 * the client interface and the plugin)
 * @param aData The data required to form the request (The type
 * of data should be known between client and the plugin)
 * @return SmfPluginError Plugin error if any, else SmfPluginErrNone
 */
SmfPluginError FBPostProviderPlugin::customRequest( SmfPluginRequestData &aRequest,
		const int &aOperation, QByteArray *aData )
	{
	Q_UNUSED(aRequest)
Q_UNUSED(aOperation)
Q_UNUSED(aData)
	SmfPluginError error = SmfPluginErrInvalidRequest;
	return error;
	}


/**
 * The first method to be called in the plugin that implements this interface.
 * If this method is not called, plugin may not behave as expected.
 * Plugins are expected to save the aUtil handle and use and when required.
 * @param aUtil The instance of SmfPluginUtil
 */
void FBPostProviderPlugin::initialize( SmfPluginUtil *aUtil )
	{
	// Save the SmfPluginUtil handle
	m_util = aUtil;

	// Create an instance of FlickrProviderBase
	m_provider = new FBProviderBase;
	m_provider->initialize();
	}

/**
 * Method to get the provider information
 * @return Instance of SmfProviderBase
 */
SmfProviderBase* FBPostProviderPlugin::getProviderInfo( )
	{
	return m_provider;
	}

/**
 * Method to get the result for a network request.
 * @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
 * data from it.
 * @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<SmfPost>. 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,
		SmfPluginRetType &aRetType,
		SmfResultPage &aPageResult )
	{
	writeLog("FBPostProviderPlugin::::responseAvailable");
	Q_UNUSED(aPageResult)
	//This API is slightly changed by Manasij
	SmfPluginError error;
	if(SmfTransportOpNoError == aTransportResult)
		{
		writeLog("No transport error");

		// Write the response to a file
		QFile file("c:\\data\\fbresponse.txt");
		writeLog("response data written to c:\\data\\fbresponse.txt");
		if (!file.open(QIODevice::Append | QIODevice::Text))
				 ;
		file.write(aResponse->data());
		file.close();

		QList<SmfPost> list;

		// For getting contacts
		QXmlStreamReader xml(aResponse->data());
		while (!xml.atEnd())
			{
			xml.readNext();
			if (xml.tokenType() == QXmlStreamReader::StartElement)
				{
				// If the tag is contact
				if (xml.name() == "message")
					{
					writeLog("message tag found");

					SmfPost post;
					QString descStr(xml.readElementText());
					post.setDescription(descStr);

                    list.append(post);
					}
				}
			}

		aResult->setValue(list);
		aRetType = SmfRequestComplete;
		error = SmfPluginErrNone;
		}

	else
		{
		error = SmfPluginErrInvalidRequest;
		aRetType = SmfRequestError;
		}
	delete aResponse;
	return error;
	}


/**
 * Destructor
 */
FBProviderBase::~FBProviderBase( )
	{
	}

/**
 * Method to get the Localisable name of the service.
 * @return The Localisable name of the service.
 */
QString FBProviderBase::serviceName( ) const
	{
	return m_serviceName;
	}

/**
 * Method to get the Logo of the service
 * @return The Logo of the service
 */
QImage FBProviderBase::serviceIcon( ) const
	{
	return m_serviceIcon;
	}

/**
 * Method to get the Readable service description
 * @return The Readable service description
 */
QString FBProviderBase::description( ) const
	{
	return m_description;
	}

/**
 * Method to get the Website of the service
 * @return The Website of the service
 */
QUrl FBProviderBase::serviceUrl( ) const
	{
	return m_serviceUrl;
	}

/**
 * Method to get the URL of the Application providing this service
 * @return The URL of the Application providing this service
 */
QUrl FBProviderBase::applicationUrl( ) const
	{
	return m_applicationUrl;
	}

/**
 * Method to get the Icon of the application
 * @return The Icon of the application
 */
QImage FBProviderBase::applicationIcon( ) const
	{
	return m_applicationIcon;
	}

/**
 * Method to get the Plugin specific ID
 * @return The Plugin specific ID
 */
QString FBProviderBase::pluginId( ) const
	{
	return m_pluginId;
	}

/**
 * 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
 */
QString FBProviderBase::authenticationApp( QString &aProgram,
		QStringList & aArguments,
		QIODevice::OpenModeFlag aMode ) const
	{
	Q_UNUSED(aProgram)
Q_UNUSED(aArguments)
Q_UNUSED(aMode)
	return m_authAppId;
	}

/**
 * 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
 * authorised plugins
 */
QString FBProviderBase::smfRegistrationId( ) const
	{
	return m_smfRegToken;
	}

void FBProviderBase::initialize()
	{
	m_serviceName = "Facebook";
	m_description = "Facebook plugin description";
	m_serviceUrl = QUrl(QString("http://api.facebook.com"));
	m_pluginId = "fbpostproviderplugin.qtplugin";
	m_authAppId = "Facebook AuthAppId";
	m_smfRegToken = "Facebook RegToken";
	}


/*
 * Export Macro
 * plugin name : fbpostproviderplugin
 * plugin class : FBPostProviderPlugin
 */
Q_EXPORT_PLUGIN2( fbpostproviderplugin, FBPostProviderPlugin )