Submitting following changes -
AuthApps for Last.fm and Twitter added
API for checking ServiceAuthorization added for SMFCredMgrClient
API added for forcefully removing credential details from SMFCredMgr
Extra argument checks in SMfClient APIs
APIs for service login and logout from SMFClient
Redundant members removed from SmfServerSymbian
DSM bug fixes
Test Apps included
/**
* 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:
* Sangeetha Prasad, Nalina Hariharan
*
* Description:
* The Plugin that fetches gallery related items from the logged in user's flickr account
*
*/
// Include files
#include <QtPlugin>
#include <QCryptographicHash>
#include <QDataStream>
#include <QFile>
#include <QDebug>
#include <QMap>
#include <QListIterator>
#include <QXmlStreamReader>
#include <QSettings>
#include <smfpluginutil.h>
#include "flickrgalleryplugin.h"
static int count = 0;
static int chance = 0; // 0 = for pics from album, 1 = pics not in any album
static int listIndex = 0;// For Mutliple Load
QByteArray payload;
QByteArray boundary("---ThIsIsAsAmPleBouNDaRyStrInGFrOmNaliNa---");
// Todo:- Macro added for limiting items fetched to recent 5
// Remove after demo
#define SETLIMITOFFIVEFORSMFDEMO 1
/**
* Method to interpret the key sets obtained from credential manager
* @param aApiKey [out] The api key
* @param aApiSecret [out] The api secret
* @param aAuthToken [out] The auth token provided by Flickr
*/
void FlickrGalleryPlugin::fetchKeys( QString &aApiKey,
QString &aApiSecret,
QString &aAuthToken )
{
qDebug()<<"Inside FlickrGalleryPlugin::fetchKeys()";
qDebug()<<"Reg Token = "<<m_provider->m_smfRegToken;
qDebug()<<"Expiry Date as int = "<<m_provider->m_validity.toTime_t();
SmfAuthParams keys;
SmfPluginUtil util;
util.getAuthKeys(keys, m_provider->m_smfRegToken,
m_provider->m_validity, m_provider->m_pluginId);
qDebug()<<"Number of key-value pairs = "<<keys.count();
QByteArray keyName;
keyName.append("ApiKey");
aApiKey.append(keys.value(keyName));
keyName.clear();
keyName.append("ApiSecret");
aApiSecret.append(keys.value(keyName));
keyName.clear();
keyName.append("AuthToken");
aAuthToken.append(keys.value(keyName));
qDebug()<<"Api Key = "<<aApiKey;
qDebug()<<"Api Secret = "<<aApiSecret;
qDebug()<<"Auth Token = "<<aAuthToken;
}
/**
* Destructor
*/
FlickrGalleryPlugin::~FlickrGalleryPlugin( )
{
if(m_provider)
delete m_provider;
}
/**
* Method to get a list of albums
* @param aRequest [out] The request data to be sent to network
* @param aNames The subject or any keywords to be used to filter albums with that name
* @param aUser The user whose albums are requested
* @param aPageNum The page to be extracted
* @param aItemsPerPage Number of items per page
* @return SmfPluginError Plugin error if any, else SmfPluginErrNone
*/
SmfPluginError FlickrGalleryPlugin::albums( SmfPluginRequestData &aRequest,
const QStringList &aNames,
const SmfContact *aUser,
const int aPageNum,
const int aItemsPerPage )
{
qDebug()<<"Inside FlickrGalleryPlugin::albums()";
Q_UNUSED(aNames)
Q_UNUSED(aPageNum)
Q_UNUSED(aItemsPerPage)
SmfPluginError error = SmfPluginErrUserNotLoggedIn;
// Get the key sets from SMF Plugin Utility class.
QString apiKey;
QString apiSecret;
QString authToken;
fetchKeys(apiKey, apiSecret, authToken );
QString userId = aUser->value("Guid").value<QContactGuid>().guid();
qDebug()<<"Flickr user's ID for fetching photos = "<<userId;
// Create the API signature string
QString baseString;
baseString.append(apiSecret);
baseString.append("api_key"+apiKey);
baseString.append("auth_token"+authToken);
baseString.append("formatjson");
baseString.append("methodflickr.photosets.getList");
#ifdef SETLIMITOFFIVEFORSMFDEMO
baseString.append("page"+QString::number(1));
baseString.append("per_page"+QString::number(5));
#else
baseString.append("page"+QString::number(aPageNum));
baseString.append("per_page"+QString::number(aItemsPerPage));
#endif
if(userId.length())
baseString.append("user_id"+userId);
// Create the url
QUrl url("http://api.flickr.com/services/rest/?");
url.addQueryItem("api_key", apiKey);
url.addQueryItem("auth_token", authToken);
url.addQueryItem("format","json");
if(userId.length())
url.addQueryItem("user_id", userId);
url.addQueryItem("method", "flickr.photosets.getList");
#ifdef SETLIMITOFFIVEFORSMFDEMO
url.addQueryItem("page", QString::number(1));
url.addQueryItem("per_page", QString::number(5));
#else
url.addQueryItem("page", QString::number(aPageNum));
url.addQueryItem("per_page", QString::number(aItemsPerPage));
#endif
url.addQueryItem("api_sig", generateSignature(baseString));
// Create the request, set the url
aRequest.iNetworkRequest.setUrl(url);
aRequest.iRequestType = SmfPictureGetAlbums;
aRequest.iPostData = NULL;
aRequest.iHttpOperationType = QNetworkAccessManager::GetOperation;
error = SmfPluginErrNone;
qDebug()<<"Url string is : "<<aRequest.iNetworkRequest.url().toString();
return error;
}
/**
* Method to get a list of pictures
* @param aRequest [out] The request data to be sent to network
* @param aAlbums The album(s) whose pictures are being requested
* @param aPageNum The page to be extracted
* @param aItemsPerPage Number of items per page
* @return SmfPluginError Plugin error if any, else SmfPluginErrNone
*/
SmfPluginError FlickrGalleryPlugin::pictures( SmfPluginRequestData &aRequest,
const SmfPictureAlbumList &aAlbums,
const int aPageNum,
const int aItemsPerPage )
{
qDebug()<<"Inside FlickrGalleryPlugin::pictures()";
SmfPluginError error = SmfPluginErrInvalidArguments;
if( (aPageNum < 0) || (aItemsPerPage < 0))
{
qDebug()<<"Invalid arguments";
return error;
}
// Get the key sets from SMF Plugin Utility class.
QString apiKey;
QString apiSecret;
QString authToken;
fetchKeys(apiKey, apiSecret, authToken );
QString albumId;
albumId.clear();
if(aAlbums.count())
{
chance = 0;
albumId = aAlbums.at(0).id();
qDebug()<<"Fetching photos from a photoset with its id = "<<albumId;
}
else
{
qDebug()<<"Fetching photos which are not in any sets";
chance = 1;
}
QString extras("date_upload,description,owner_name,tags,url_sq,url_t,url_s,url_m,url_o");
// Create the API signature string
QString baseString;
baseString.append(apiSecret);
baseString.append("api_key"+apiKey);
baseString.append("auth_token"+authToken);
baseString.append("extras"+extras);
baseString.append("formatjson");
if(aAlbums.count())
baseString.append("methodflickr.photosets.getPhotos");
else
baseString.append("methodflickr.photos.getNotInSet");
#ifdef SETLIMITOFFIVEFORSMFDEMO
baseString.append("page"+QString::number(1));
baseString.append("per_page"+QString::number(5));
#else
baseString.append("page"+QString::number(aPageNum));
baseString.append("per_page"+QString::number(aItemsPerPage));
#endif
if(aAlbums.count())
baseString.append("photoset_id"+albumId);
// Create the url
QUrl url("http://api.flickr.com/services/rest/?");
url.addQueryItem("api_key", apiKey);
url.addQueryItem("auth_token", authToken);
url.addQueryItem("extras", extras);
url.addQueryItem("format","json");
if(aAlbums.count())
url.addQueryItem("method", "flickr.photosets.getPhotos");
else
url.addQueryItem("method", "flickr.photos.getNotInSet");
#ifdef SETLIMITOFFIVEFORSMFDEMO
url.addQueryItem("page", QString::number(1));
url.addQueryItem("per_page", QString::number(5));
#else
url.addQueryItem("page", QString::number(aPageNum));
url.addQueryItem("per_page", QString::number(aItemsPerPage));
#endif
if(aAlbums.count())
url.addQueryItem("photoset_id", albumId);
url.addQueryItem("api_sig", generateSignature(baseString));
// Create the request, set the url
aRequest.iNetworkRequest.setUrl(url);
aRequest.iRequestType = SmfPictureGetPictures;
aRequest.iPostData = NULL;
aRequest.iHttpOperationType = QNetworkAccessManager::GetOperation;
error = SmfPluginErrNone;
qDebug()<<"Url string is : "<<aRequest.iNetworkRequest.url().toString();
return error;
}
/**
* Method to get a description
* @param aRequest [out] The request data to be sent to network
* @param aImage The image abot which the description is required
* @return SmfPluginError Plugin error if any, else SmfPluginErrNone
*/
SmfPluginError FlickrGalleryPlugin::description(SmfPluginRequestData &aRequest,
const SmfPicture &aImage)
{
qDebug()<<"Inside FlickrGalleryPlugin::description()";
SmfPluginError error = SmfPluginErrInvalidArguments;
if( 0 == aImage.id().size())
{
qDebug()<<"Invalid arguments";
return error;
}
// Get the key sets from SMF Plugin Utility class.
QString apiKey;
QString apiSecret;
QString authToken;
fetchKeys(apiKey, apiSecret, authToken );
// Create the API signature string
QString baseString;
baseString.append(apiSecret);
baseString.append("api_key"+apiKey);
baseString.append("auth_token"+authToken);
baseString.append("formatjson");
baseString.append("methodflickr.photos.getInfo");
baseString.append("photo_id"+aImage.id());
// Create the url
QUrl url("http://api.flickr.com/services/rest/?");
url.addQueryItem("api_key", apiKey);
url.addQueryItem("auth_token", authToken);
url.addQueryItem("format","json");
url.addQueryItem("method", "flickr.photos.getInfo");
url.addQueryItem("photo_id",aImage.id());
url.addQueryItem("api_sig", generateSignature(baseString));
// Create the request, set the url
aRequest.iNetworkRequest.setUrl(url);
aRequest.iRequestType = SmfPictureDescription;
aRequest.iPostData = NULL;
aRequest.iHttpOperationType = QNetworkAccessManager::GetOperation;
error = SmfPluginErrNone;
qDebug()<<"Url string is : "<<aRequest.iNetworkRequest.url().toString();
return error;
}
/**
* Method to upload a picture
* @param aRequest [out] The request data to be sent to network
* @param aImage The image to be uploaded
* @param aAlbum the optional destination album name
* @return SmfPluginError Plugin error if any, else SmfPluginErrNone
*/
SmfPluginError FlickrGalleryPlugin::upload( SmfPluginRequestData &aRequest,
const SmfPicture &aImage,
const SmfPictureAlbum* aAlbum )
{
qDebug()<<"Inside FlickrGalleryPlugin::upload()";
Q_UNUSED(aAlbum)
SmfPluginError error = SmfPluginErrInvalidArguments;
if( 0 == aImage.picture().byteCount())
{
qDebug()<<"Invalid arguments";
return error;
}
// Get the key sets from SMF Plugin Utility class.
QString apiKey;
QString apiSecret;
QString authToken;
fetchKeys(apiKey, apiSecret, authToken );
// Create the Payload data
QDataStream stream(&payload, QIODevice::WriteOnly);
int bytes = 0;
// Create the api_key field
QByteArray keyField = constructField ( "api_key", apiKey, boundary );
bytes = stream.writeRawData(keyField.data(), keyField.length());
qDebug()<<"Bytes written for API key field = "<<QString::number(bytes, 10);
// Create the auth_token field
QByteArray tokenField = constructField ( "auth_token", authToken, boundary );
bytes = stream.writeRawData(tokenField.data(), tokenField.length());
qDebug()<<"Bytes written for Auth token field = "<<QString::number(bytes, 10);
// Create the API signature string
QString baseString;
baseString.append(apiSecret);
baseString.append("api_key"+apiKey);
baseString.append("auth_token"+authToken);
baseString = generateSignature(baseString);
// Create the signature field
QByteArray sigField = constructField ( "api_sig", baseString, boundary );
bytes = stream.writeRawData(sigField.data(), sigField.length());
qDebug()<<"Bytes written for API signature field = "<<QString::number(bytes, 10);
// Create the file header field
QByteArray fileField = constructField ( "photo", "", boundary, "c:\\data\\TestUploadPics\\BlueHills.jpg" );
bytes = stream.writeRawData(fileField.data(), fileField.length());
qDebug()<<"Bytes written for File header field = "<<QString::number(bytes, 10);
// GEt the image data into a Bytearray
QByteArray pic;
QBuffer buffer(&pic);
buffer.open(QIODevice::WriteOnly);
aImage.picture().save(&buffer, "JPG");
qDebug()<<"Number of bytes in the pic = "<<QString::number(pic.size(), 10);
// Add the file content to the stream
if(pic.size())
{
bytes = stream.writeRawData ( pic.data(), pic.length() );
qDebug()<<"Bytes written for File content field = "<<QString::number(bytes, 10);
}
// Create the end field
QByteArray endField;
endField.append ( "\r\n--" );
endField.append ( boundary );
endField.append ( "--\r\n\r\n" );
bytes = stream.writeRawData(endField.data(), endField.length());
qDebug()<<"Bytes written for end field = "<<QString::number(bytes, 10);
QUrl url("http://api.flickr.com/services/upload/");
// Create the request, set the url
aRequest.iNetworkRequest.setUrl(url);
aRequest.iNetworkRequest.setRawHeader("Content-Type", "multipart/form-data; boundary="+boundary);
aRequest.iRequestType = SmfPictureUpload;
aRequest.iPostData = new QBuffer(&payload);
aRequest.iHttpOperationType = QNetworkAccessManager::PostOperation;
error = SmfPluginErrNone;
qDebug()<<"Url string is : "<<aRequest.iNetworkRequest.url().toString();
return error;
}
/**
* Method to construct individual fields for photo upload
* @param aName The name argument
* @param aContent The content of this field
* @param aBoundary The boundary string (need to be unique in the payload data)
* @param aFilename The filename if for photo field
* @return The field data constructed by this method
*/
QByteArray FlickrGalleryPlugin::constructField( const QString &aName,
const QString &aContent,
const QByteArray &aBoundary,
const QString & aFilename )
{
QByteArray data;
data.append ( "--" );
data.append ( aBoundary );
data.append ( "\r\n" );
data.append ( "Content-Disposition: form-data; name=\"" );
data.append ( aName.toAscii() );
if ( aFilename.isEmpty() )
{
data.append ( "\"\r\n\r\n" );
data.append ( aContent.toAscii() );
data.append ( "\r\n" );
}
else
{
data.append ( "\"; filename=\"" );
data.append ( aFilename.toAscii() );
data.append ( "\"\r\n" );
data.append ( "Content-Type: image/jpeg\r\n\r\n" );
}
return data;
}
/**
* Method to upload a list of pictures
* @param aRequest [out] The request data to be sent to network
* @param aImages The list of images to be uploaded
* @return SmfPluginError Plugin error if any, else SmfPluginErrNone
*/
SmfPluginError FlickrGalleryPlugin::upload( SmfPluginRequestData &aRequest,
const QList<SmfPicture> &aImages,
const SmfPictureAlbum* aAlbum )
{
SmfPluginError error = SmfPluginErrUserNotLoggedIn;
qDebug()<<("\r\n multiple Uploaded Pictures.....= "+QString::number(aImages.count(),10));
Q_UNUSED(aAlbum)
// Get the key sets from SMF Plugin Utility class.
QString apiKey;
QString apiSecret;
QString authToken;
fetchKeys(apiKey, apiSecret, authToken );
count =aImages.count();
QByteArray boundary("---ThIsIsAsAmPleBouNDaRyStrInGFrOmSaNgEeTa---");
QDataStream stream(&payload, QIODevice::WriteOnly);
int bytes = 0;
// Create the api_key field
QByteArray keyField = constructField("api_key",apiKey,boundary,"");//,apiKey,boundary);
bytes = stream.writeRawData(keyField.data(), keyField.length());
qDebug()<<("Bytes written for API key field = "+QString::number(bytes, 10));
// Create the auth_token field
QByteArray tokenField = constructField ( "auth_token", authToken, boundary,"");
bytes = stream.writeRawData(tokenField.data(), tokenField.length());
qDebug()<<("Bytes written for Auth token field = "+QString::number(bytes, 10));
//Create the API signature string
QString baseString;
baseString.append(apiSecret);
baseString.append("api_key"+apiKey);
baseString.append("auth_token"+authToken);
//baseString.append("formatjson"); //not working this format
baseString = generateSignature(baseString);
//extract the smfpicture object
SmfPicture aImage=aImages[listIndex];
//Create the signature field
QByteArray sigField = constructField ("api_sig", baseString, boundary,"" );
bytes = stream.writeRawData(sigField.data(), sigField.length());
qDebug()<<("QImage String = "+aImage.url().toString());
//Create the file header field
QByteArray fileField = constructField ( "photo", "", boundary, aImage.url().toString());
bytes = stream.writeRawData(fileField.data(), fileField.length());
//QByteArray pic ;
QImage image=aImage.picture();
//for checking only
int byte=image.numBytes();
qDebug()<<("Bytes written for QImage = "+QString::number(byte,10));
//For finding the format of Image file (eg. c:\\data\\image.jpg);
QString fileName=aImage.url().toString();
int last = fileName.lastIndexOf(".",-1);
qDebug()<<("last QImage = "+QString::number(last,10));
QString Format=fileName.right(fileName.size()-last-1); //-1 for removing "." from .jpg
qDebug()<<("Format of QImage = "+Format);
QByteArray pic;
QBuffer buffer(&pic);
buffer.open(QIODevice::WriteOnly);
image.save(&buffer,Format.toLatin1(),-1); // writes image into format given by Format
qDebug()<<("Number of bytes in the picture = "+QString::number(buffer.size(), 10));
// Add the file content to the stream
if (pic.size())
{
bytes = stream.writeRawData ( pic.data(), pic.length() );
qDebug()<<("Bytes written for File content field = "+QString::number(bytes, 10));
}
qDebug()<<("Before Url string is : "+QString(payload));
// Create the end field
QByteArray endField;
endField.append ( "\r\n--" );
endField.append ( boundary );
endField.append ( "--\r\n\r\n" );
bytes = stream.writeRawData(endField.data(), endField.length());
qDebug()<<("Bytes written for end field = "+QString::number(bytes, 10));
//Create the url
QUrl url("http://api.flickr.com/services/upload/");
//url.addQueryItem("format","json"); //Not working
//Create the request, set the url
aRequest.iNetworkRequest.setUrl(url);
aRequest.iNetworkRequest.setRawHeader("Content-Type", "multipart/form-data; boundary="+boundary);
aRequest.iNetworkRequest.setRawHeader("Host", "api.flickr.com");
aRequest.iRequestType = SmfPictureUpload;
aRequest.iPostData=new QBuffer(&payload);
aRequest.iHttpOperationType = QNetworkAccessManager::PostOperation;
error = SmfPluginErrNone;
return error;
}
/**
* Method to post comment on a picture is available
* @param aRequest [out] The request data to be sent to network
* @param aImage The image on which comment is to be posted
* @param aComment The comment to be posted
* @return SmfPluginError Plugin error if any, else SmfPluginErrNone
*/
SmfPluginError FlickrGalleryPlugin::postComment( SmfPluginRequestData &aRequest,
const SmfPicture &aImage,
const SmfComment &aComment )
{
qDebug()<<"Inside FlickrGalleryPlugin::postComment()";
SmfPluginError error = SmfPluginErrInvalidArguments;
if( 0 == aImage.id().size() || (0 == aComment.text().size()) )
{
qDebug()<<"Invalid arguments";
return error;
}
// Get the key sets from SMF Plugin Utility class.
QString apiKey;
QString apiSecret;
QString authToken;
fetchKeys(apiKey, apiSecret, authToken );
// Create the API signature string
QString baseString;
baseString.append(apiSecret);
baseString.append("api_key"+apiKey);
baseString.append("auth_token"+authToken);
baseString.append("comment_text"+aComment.text());
baseString.append("formatjson");
baseString.append("methodflickr.photos.comments.addComment");
baseString.append("photo_id"+aImage.id());
// Create the url
QUrl url("http://api.flickr.com/services/rest/?");
url.addQueryItem("api_key", apiKey);
url.addQueryItem("auth_token", authToken);
url.addQueryItem("comment_text", aComment.text());
url.addQueryItem("format","json");
url.addQueryItem("method", "flickr.photos.comments.addComment");
url.addQueryItem("photo_id",aImage.id());
url.addQueryItem("api_sig", generateSignature(baseString));
// Create the request, set the url
aRequest.iNetworkRequest.setUrl(url);
aRequest.iRequestType = SmfPicturePostComment;
aRequest.iPostData = NULL;
aRequest.iHttpOperationType = QNetworkAccessManager::GetOperation;
error = SmfPluginErrNone;
qDebug()<<"Url string is : "<<aRequest.iNetworkRequest.url().toString();
return error;
}
/**
* 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 FlickrGalleryPlugin::generateSignature(const QString aBaseString)
{
qDebug()<<("FlickrGalleryPlugin::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;
}
/**
* Customised method for SmfContactFetcherPlugin 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 FlickrGalleryPlugin::customRequest( SmfPluginRequestData &aRequest,
const int &aOperation, QByteArray *aData )
{
Q_UNUSED(aRequest)
Q_UNUSED(aOperation)
Q_UNUSED(aData)
return SmfPluginErrServiceNotSupported;
}
/**
* 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.
*/
void FlickrGalleryPlugin::initialize( )
{
// Create an instance of FBContactProviderBase
m_provider = new FlickrProviderBase;
m_provider->initialize();
}
/**
* Method to get the provider information
* @return Instance of SmfProviderBase
*/
SmfProviderBase* FlickrGalleryPlugin::getProviderInfo( )
{
return m_provider;
}
/**
* 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
* 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 SmfGalleryPlugin: If last operation was albums, aResult will be of
* type QList<SmfPictureAlbum>. If the last operation was pictures(), aResult
* will be of type QList<SmfPicture>. If last operation was description(),
* aResult will be of type QString. If last operation was upload() or
* postComment(), aResult will be of type bool.
* @param aRetType [out] SmfPluginRetType
* @param aPageResult [out] The SmfResultPage structure variable
*/
SmfPluginError FlickrGalleryPlugin::responseAvailable(
const SmfRequestTypeID aOperation,
const SmfTransportResult &aTransportResult,
QByteArray *aResponse,
QVariant* aResult,
SmfPluginRetType &aRetType,
SmfResultPage &aPageResult )
{
qDebug()<<"Inside FlickrGalleryPlugin::responseAvailable()";
Q_UNUSED(aPageResult)
SmfPluginError error = SmfPluginErrNetworkError;
if( !aResponse || (0 == aResponse->size()) )
{
qDebug()<<"Response is NULL or empty";
aRetType = SmfRequestError;
return error;
}
QByteArray response(*aResponse);
delete aResponse;
QFile respFile("c://data//SmfPluginFlickrResponse.txt");
if(!respFile.open(QIODevice::WriteOnly))
{
qDebug()<<"File to write the response could not be opened, so writing to this file";
qDebug()<<"Flickr response = "<<QString(response);
}
else
{
respFile.write(response);
respFile.close();
qDebug()<<"Writing FB response to a file named 'SmfPluginFlickrResponse.txt'";
}
qDebug()<<"Response size = "<<response.size();
if(SmfTransportOpNoError == aTransportResult)
{
qDebug()<<"No transport error";
if(SmfPictureGetAlbums == aOperation)
{
qDebug()<<"Response for retrieving album lists";
QList<SmfPictureAlbum> albumList;
QString errStr;
errStr.clear();
// Remove the "jsonFlickrApi(" from starting of the response and ")" from its end
response.remove(0, 14);
response.chop(1);
bool ok;
SmfPluginUtil util;
QVariantMap result = util.parse(response, &ok).toMap();
if (!ok)
{
qDebug()<<"An error occurred during json parsing";
aRetType = SmfRequestError;
return SmfPluginErrParsingFailed;
}
if(response.contains(QByteArray("fail")))
{
errStr.append(result["message"].toString());
}
else
{
QVariantMap map1 = result["photosets"].toMap();
QList<QVariant> list1 = map1["photoset"].toList();
QListIterator<QVariant> iter(list1);
while(iter.hasNext())
{
SmfPictureAlbum album;
QVariantMap map2 = iter.next().toMap();
// Set the album's title
QVariantMap map3 = map2["title"].toMap();
album.setTitle(map3["_content"].toString());
qDebug()<<"title = "<<album.title();
// Set the album's description
QVariantMap map4 = map2["description"].toMap();
album.setDescription(map4["_content"].toString());
qDebug()<<"desc = "<<album.description();
// Set the album's picture count
album.setPictureCount(map2["photos"].toInt());
qDebug()<<"pic count = "<<album.pictureCount();
// Set the album's id
album.setId(map2["id"].toString());
qDebug()<<"id = "<<album.id();
albumList.append(album);
#ifdef SETLIMITOFFIVEFORSMFDEMO
if(5 == albumList.count())
break;
#endif
}
}
if(errStr.size())
{
qDebug()<<"Response error found = "<<errStr;
error = SmfPluginErrInvalidRequest;
aRetType = SmfRequestError;
aResult->setValue(errStr);
}
else
{
qDebug()<<"list count = "<<albumList.count();
aResult->setValue(albumList);
aRetType = SmfRequestComplete;
error = SmfPluginErrNone;
}
}
else if(SmfPictureGetPictures == aOperation)
{
qDebug()<<"Response for retrieving photos";
QList<SmfPicture> picList;
QString errStr;
errStr.clear();
// Remove the "jsonFlickrApi(" from starting of the response and ")" from its end
response.remove(0, 14);
response.chop(1);
bool ok;
SmfPluginUtil util;
QVariantMap result = util.parse(response, &ok).toMap();
if (!ok)
{
qDebug()<<"An error occurred during json parsing";
aRetType = SmfRequestError;
return SmfPluginErrParsingFailed;
}
if(response.contains(QByteArray("fail")))
{
errStr.append(result["message"].toString());
}
else
{
QVariantMap map1;
if(0 == chance)
map1 = result["photoset"].toMap();
else
map1 = result["photos"].toMap();
QList<QVariant> list1 = map1["photo"].toList();
QListIterator<QVariant> iter(list1);
while(iter.hasNext())
{
SmfPicture pic;
QVariantMap map2 = iter.next().toMap();
// Set the pic's id
pic.setId(map2["id"].toString());
// Set the pic's description
QVariantMap map3 = map2["description"].toMap();
pic.setDescription(map3["_content"].toString());
// Set the pic's title
pic.setTitle(map2["title"].toString());
qDebug()<<"title = "<<map2["title"].toString();
// Set the pic's owner
pic.setOwner(map2["ownername"].toString());
// Set the pic's posted date
QDateTime date = QDateTime::fromTime_t(map2["dateupload"].toUInt());
qDebug()<<"time = "<<date;
pic.setPostedDate(date);
// Set the pic's tags
QString tags(map2["tags"].toString());
QStringList tagList = tags.split(' ');
pic.addTags(tagList);
// Set the pic's url
// url_sq,url_t,url_s,url_m,url_o
if(map2["url_o"].toString().size())
pic.setUrl(map2["url_o"].toString());
else if(map2["url_m"].toString().size())
pic.setUrl(map2["url_m"].toString());
else if(map2["url_sq"].toString().size())
pic.setUrl(map2["url_sq"].toString());
else if(map2["url_s"].toString().size())
pic.setUrl(map2["url_s"].toString());
else if(map2["url_t"].toString().size())
pic.setUrl(map2["url_t"].toString());
qDebug()<<"url = "<<pic.url();
picList.append(pic);
}
}
if(errStr.size())
{
qDebug()<<"Response error found = "<<errStr;
error = SmfPluginErrInvalidRequest;
aRetType = SmfRequestError;
aResult->setValue(errStr);
}
else
{
qDebug()<<"list count = "<<picList.count();
aResult->setValue(picList);
aRetType = SmfRequestComplete;
error = SmfPluginErrNone;
}
}
else if(SmfPictureDescription == aOperation)
{
qDebug()<<"Response for photo decscription";
QString description;
QString errStr;
errStr.clear();
// Remove the "jsonFlickrApi(" from starting of the response and ")" from its end
response.remove(0, 14);
response.chop(1);
bool ok;
SmfPluginUtil util;
QVariantMap result = util.parse(response, &ok).toMap();
if (!ok)
{
qDebug()<<"An error occurred during json parsing";
aRetType = SmfRequestError;
return SmfPluginErrParsingFailed;
}
if(response.contains(QByteArray("fail")))
{
errStr.append(result["message"].toString());
}
else
{
QVariantMap map1 = result["photo"].toMap();
QVariantMap map2 = map1["description"].toMap();
description = map2["_content"].toString();
}
if(errStr.size())
{
qDebug()<<"Response error found = "<<errStr;
error = SmfPluginErrInvalidRequest;
aRetType = SmfRequestError;
aResult->setValue(errStr);
}
else
{
qDebug()<<"description = "<<description;
aResult->setValue(description);
aRetType = SmfRequestComplete;
error = SmfPluginErrNone;
}
}
else if (SmfPictureUpload == aOperation)
{
#if 1
qDebug()<<"Response for single photo upload";
bool uploaded = false;
QString errStr;
errStr.clear();
if(response.contains(QByteArray("err code")))
{
QXmlStreamReader xml(response);
while (!xml.atEnd())
{
xml.readNext();
if (xml.tokenType() == QXmlStreamReader::StartElement)
if (xml.name() == "err")
errStr.append(xml.attributes().value("msg"));
}
}
else
uploaded = true;
if(errStr.size())
{
qDebug()<<"Response error found = "<<errStr;
error = SmfPluginErrInvalidRequest;
aRetType = SmfRequestError;
aResult->setValue(errStr);
}
else
{
qDebug()<<"photo uploaded ? "<<uploaded;
aResult->setValue(uploaded);
aRetType = SmfRequestComplete;
error = SmfPluginErrNone;
}
#endif
}
else if (SmfPictureMultiUpload == aOperation)
{
bool result;
qDebug()<<("SmfMultiPictureUpload");
QXmlStreamReader xml(response);
while (!xml.atEnd())
{
xml.readNext();
if (xml.tokenType() == QXmlStreamReader::StartElement)
{
qDebug()<<("inside tag");
//If the tag is contact
if (xml.name() == "photoid")
{
qDebug()<<("photoid tag found");
result=TRUE;
}
else
result=FALSE;
}//end If
}//endWhile;
aResult->setValue(result);
if (listIndex < count)
{
listIndex=listIndex+1;
error = SmfPluginErrNone;
aRetType = SmfSendRequestAgain;
}
else
{
//Final result sent
count=1; //clear counter
aRetType = SmfRequestComplete;
error = SmfPluginErrNone;
}
}
else if (SmfPicturePostComment == aOperation)
{
qDebug()<<"Response for adding comment on a photo";
bool commentPosted = false;
QString errStr;
errStr.clear();
// Remove the "jsonFlickrApi(" from starting of the response and ")" from its end
response.remove(0, 14);
response.chop(1);
bool ok;
SmfPluginUtil util;
QVariantMap result = util.parse(response, &ok).toMap();
if (!ok)
{
qDebug()<<"An error occurred during json parsing";
aRetType = SmfRequestError;
return SmfPluginErrParsingFailed;
}
if(response.contains(QByteArray("fail")))
{
errStr.append(result["message"].toString());
}
else
{
qDebug()<<"Comment posted on the photo";
commentPosted = true;
}
if(errStr.size())
{
qDebug()<<"Response error found = "<<errStr;
error = SmfPluginErrInvalidRequest;
aRetType = SmfRequestError;
aResult->setValue(errStr);
}
else
{
qDebug()<<"comment posted ? "<<commentPosted;
aResult->setValue(commentPosted);
aRetType = SmfRequestComplete;
error = SmfPluginErrNone;
}
}
else
{
qDebug()<<"Service unsupported, currently only SmfContactRetrievePosts and SmfContactPostDirected!!!";
aRetType = SmfRequestError;
error = SmfPluginErrServiceNotSupported;
}
}
else if(SmfTransportOpOperationCanceledError == aTransportResult)
{
qDebug()<<"Operation Cancelled !!!";
error = SmfPluginErrCancelComplete;
aRetType = SmfRequestComplete;
}
else
{
qDebug()<<"Transport Error !!!";
error = SmfPluginErrNetworkError;
aRetType = SmfRequestError;
}
return error;
#if 0
qDebug()<<("FlickrGalleryPlugin::responseAvailable");
Q_UNUSED(aPageResult)
SmfPluginError error = SmfPluginErrNetworkError;
if( !aResponse || (0 == aResponse->size()) )
{
qDebug()<<("Response is NULL or empty");
aRetType = SmfRequestError;
return error;
}
QByteArray response(*aResponse);
delete aResponse;
//Write the response to a file
QFile file("c:\\data\\flickrresponse.txt");
qDebug()<<("response data written to c:\\data\\flickrresponse.txt");
if (!file.open(QIODevice::Append | QIODevice::Text));
file.write(response);
file.close();
qDebug()<<("Gallery response size = "+QString::number(response.size(), 10));
QList<SmfPicture> list;
if(SmfTransportOpNoError == aTransportResult)
{
qDebug()<<("No transport error");
QVariantMap map1;
bool resType=response.startsWith("<?xml");
if(resType) //XML REsponse
{
qDebug()<<("Before XML Parser--");
}
else //JSON RESPONSE
{
response.remove(0, 14);
response.chop(1);
bool ok;
qDebug()<<("Before JSON Parser--");
SmfPluginUtil util;
QVariant result= util.parse(response, &ok);
if (!ok)
{
qDebug()<<("An error occurred during json parsing");
aRetType = SmfRequestError;
return SmfPluginErrParsingFailed;
}
QVariantMap map1 = result.toMap();
}
if( SmfPictureGetAlbums == aOperation )
{}
}
else if(SmfPictureGetPictures == aOperation)
{}//end of if(SmfPictureGetPictures == aOperation)
else if(SmfPicturePostComment == aOperation)
{}
else if(SmfPictureDescription == aOperation)
{}
else if(SmfPictureUpload == aOperation)
{
bool result;
qDebug()<<("SmfPictureUpload");
QXmlStreamReader xml(response);
while (!xml.atEnd())
{
xml.readNext();
if (xml.tokenType() == QXmlStreamReader::StartElement)
{
qDebug()<<("inside tag");
//If the tag is contact
if (xml.name() == "photoid")
{
qDebug()<<("photoid tag found");
result=TRUE;
}
else
result=FALSE;
}
}
aResult->setValue(result);
aRetType = SmfRequestComplete;
error = SmfPluginErrNone;
}
else if (SmfPictureMultiUpload == aOperation)
{
bool result;
qDebug()<<("SmfPictureUpload");
QXmlStreamReader xml(response);
while (!xml.atEnd())
{
xml.readNext();
if (xml.tokenType() == QXmlStreamReader::StartElement)
{
qDebug()<<("inside tag");
//If the tag is contact
if (xml.name() == "photoid")
{
qDebug()<<("photoid tag found");
result=TRUE;
}
else
result=FALSE;
}//end If
}//endWhile;
aResult->setValue(result);
if (listIndex < count)
{
listIndex=listIndex+1;
error = SmfPluginErrNone;
aRetType = SmfSendRequestAgain;
}
else
{
//Final result sent
count=1; //clear counter
aRetType = SmfRequestComplete;
error = SmfPluginErrNone;
}
}
else
{
qDebug()<<("Service unsupported!!!");
aRetType = SmfRequestError;
error = SmfPluginErrServiceNotSupported;
}
}//end if of if(SmfTransportOpNoError == aTransportResult)
else if(SmfTransportOpOperationCanceledError == aTransportResult)
{
qDebug()<<("Operation Cancelled !!!");
error = SmfPluginErrCancelComplete;
aRetType = SmfRequestComplete;
}
else
{
qDebug()<<("Transport Error !!!");
error = SmfPluginErrNetworkError;
aRetType = SmfRequestError;
}
return error;
#endif
}
/**
* Destructor
*/
FlickrProviderBase::~FlickrProviderBase( )
{
}
/**
* Method to get the Localisable name of the service.
* @return The Localisable name of the service.
*/
QString FlickrProviderBase::serviceName( ) const
{
return m_serviceName;
}
/**
* Method to get the Logo of the service
* @return The Logo of the service
*/
QImage FlickrProviderBase::serviceIcon( ) const
{
return m_serviceIcon;
}
/**
* Method to get the Readable service description
* @return The Readable service description
*/
QString FlickrProviderBase::description( ) const
{
return m_description;
}
/**
* Method to get the Website of the service
* @return The Website of the service
*/
QUrl FlickrProviderBase::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 FlickrProviderBase::applicationUrl( ) const
{
return m_applicationUrl;
}
/**
* Method to get the Icon of the application
* @return The Icon of the application
*/
QImage FlickrProviderBase::applicationIcon( ) const
{
return m_applicationIcon;
}
/**
* Method to get the list of interfaces that this provider support
* @return List of supported Interafces
*/
QList<QString> FlickrProviderBase::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 FlickrProviderBase::supportedLanguages( ) const
{
return m_supportedLangs;
}
/**
* Method to get the Plugin specific ID
* @return The Plugin specific ID
*/
QString FlickrProviderBase::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 FlickrProviderBase::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 authentication application process name
* @return The authentication application process name (eg: "FlickrAuthApp.exe")
*/
QString FlickrProviderBase::authenticationAppName( ) const
{
return m_authAppName;
}
/**
* 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 FlickrProviderBase::smfRegistrationId( ) const
{
return m_smfRegToken;
}
void FlickrProviderBase::initialize()
{
m_serviceName = "Flickr";
m_description = "Flickr gallery plugin description";
m_serviceUrl = QUrl(QString("http://api.flickr.com"));
m_pluginId = "flickrgalleryplugin.qtplugin";
m_authAppId = "0xE1D8C7D7";
m_authAppName = "Flickr.exe";
m_supportedInterfaces.append("org.symbian.smf.plugin.gallery/v0.2");
QSettings iSettings;
m_smfRegToken = iSettings.value("CMFlickrRegToken").toString();
m_validity = iSettings.value("FlckrExpiryTime").toDateTime();
}
/*
* Export Macro
* plugin name : flickrGalleryplugin
* plugin class : FlickrGalleryPlugin
*/
Q_EXPORT_PLUGIN2( flickrgalleryplugin, FlickrGalleryPlugin )