Merged branch v0.5-gxs-b1 into trunk (from -r 5351 -> 5995)

This brings a huge amount of goodness into the trunk,
but there is still a big chunk todo before it can be released.

 * GXS Backend.
 * GXS Services:
	- Identities.
	- Circles
	- Photos
	- Wiki
	- GxsForums
	- Posted.
 * SSH no-gui server.

See branch commits for more info.

To switch on GXS stuff, enable CONFIG += gxs
in both libretroshare.pro and retroshare-gui.pro



git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@5996 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
drbob 2012-12-16 19:17:11 +00:00
commit 069b72e0b2
549 changed files with 111171 additions and 25579 deletions

View file

@ -1,805 +0,0 @@
/*
* libretroshare/src/services p3forumsv2.cc
*
* ForumsV2 interface for RetroShare.
*
* Copyright 2012-2012 by Robert Fernie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2.1 as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
#include "services/p3forumsv2.h"
#include "util/rsrandom.h"
#include <stdio.h>
/****
* #define FORUMV2_DEBUG 1
****/
RsForumsV2 *rsForumsV2 = NULL;
/********************************************************************************/
/******************* Startup / Tick ******************************************/
/********************************************************************************/
p3ForumsV2::p3ForumsV2(uint16_t type)
:p3GxsDataService(type, new ForumDataProxy()), mForumMtx("p3ForumsV2"), mUpdated(true)
{
{
RsStackMutex stack(mForumMtx); /********** STACK LOCKED MTX ******/
mForumProxy = (ForumDataProxy *) mProxy;
}
generateDummyData();
return;
}
int p3ForumsV2::tick()
{
std::cerr << "p3ForumsV2::tick()";
std::cerr << std::endl;
fakeprocessrequests();
return 0;
}
bool p3ForumsV2::updated()
{
RsStackMutex stack(mForumMtx); /********** STACK LOCKED MTX ******/
if (mUpdated)
{
mUpdated = false;
return true;
}
return false;
}
/* Data Requests */
bool p3ForumsV2::requestGroupInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list<std::string> &groupIds)
{
generateToken(token);
std::cerr << "p3ForumsV2::requestGroupInfo() gets Token: " << token << std::endl;
storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_GROUPS, groupIds);
return true;
}
bool p3ForumsV2::requestMsgInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list<std::string> &groupIds)
{
generateToken(token);
std::cerr << "p3ForumsV2::requestMsgInfo() gets Token: " << token << std::endl;
storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_MSGS, groupIds);
return true;
}
bool p3ForumsV2::requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list<std::string> &msgIds)
{
generateToken(token);
std::cerr << "p3ForumsV2::requestMsgRelatedInfo() gets Token: " << token << std::endl;
storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_MSGRELATED, msgIds);
return true;
}
/* Generic Lists */
bool p3ForumsV2::getGroupList( const uint32_t &token, std::list<std::string> &groupIds)
{
uint32_t status;
uint32_t reqtype;
uint32_t anstype;
time_t ts;
checkRequestStatus(token, status, reqtype, anstype, ts);
if (anstype != RS_TOKREQ_ANSTYPE_LIST)
{
std::cerr << "p3ForumsV2::getGroupList() ERROR AnsType Wrong" << std::endl;
return false;
}
if (reqtype != GXS_REQUEST_TYPE_GROUPS)
{
std::cerr << "p3ForumsV2::getGroupList() ERROR ReqType Wrong" << std::endl;
return false;
}
if (status != GXS_REQUEST_STATUS_COMPLETE)
{
std::cerr << "p3ForumsV2::getGroupList() ERROR Status Incomplete" << std::endl;
return false;
}
bool ans = loadRequestOutList(token, groupIds);
updateRequestStatus(token, GXS_REQUEST_STATUS_DONE);
return ans;
}
bool p3ForumsV2::getMsgList( const uint32_t &token, std::list<std::string> &msgIds)
{
uint32_t status;
uint32_t reqtype;
uint32_t anstype;
time_t ts;
checkRequestStatus(token, status, reqtype, anstype, ts);
if (anstype != RS_TOKREQ_ANSTYPE_LIST)
{
std::cerr << "p3ForumsV2::getMsgList() ERROR AnsType Wrong" << std::endl;
return false;
}
if ((reqtype != GXS_REQUEST_TYPE_MSGS) && (reqtype != GXS_REQUEST_TYPE_MSGRELATED))
{
std::cerr << "p3ForumsV2::getMsgList() ERROR ReqType Wrong" << std::endl;
return false;
}
if (status != GXS_REQUEST_STATUS_COMPLETE)
{
std::cerr << "p3ForumsV2::getMsgList() ERROR Status Incomplete" << std::endl;
return false;
}
bool ans = loadRequestOutList(token, msgIds);
updateRequestStatus(token, GXS_REQUEST_STATUS_DONE);
return ans;
}
/* Generic Summary */
bool p3ForumsV2::getGroupSummary( const uint32_t &token, std::list<RsGroupMetaData> &groupInfo)
{
uint32_t status;
uint32_t reqtype;
uint32_t anstype;
time_t ts;
checkRequestStatus(token, status, reqtype, anstype, ts);
if (anstype != RS_TOKREQ_ANSTYPE_SUMMARY)
{
std::cerr << "p3ForumsV2::getGroupSummary() ERROR AnsType Wrong" << std::endl;
return false;
}
if (reqtype != GXS_REQUEST_TYPE_GROUPS)
{
std::cerr << "p3ForumsV2::getGroupSummary() ERROR ReqType Wrong" << std::endl;
return false;
}
if (status != GXS_REQUEST_STATUS_COMPLETE)
{
std::cerr << "p3ForumsV2::getGroupSummary() ERROR Status Incomplete" << std::endl;
return false;
}
std::list<std::string> groupIds;
bool ans = loadRequestOutList(token, groupIds);
updateRequestStatus(token, GXS_REQUEST_STATUS_DONE);
/* convert to RsGroupMetaData */
mProxy->getGroupSummary(groupIds, groupInfo);
return ans;
}
bool p3ForumsV2::getMsgSummary( const uint32_t &token, std::list<RsMsgMetaData> &msgInfo)
{
uint32_t status;
uint32_t reqtype;
uint32_t anstype;
time_t ts;
checkRequestStatus(token, status, reqtype, anstype, ts);
if (anstype != RS_TOKREQ_ANSTYPE_SUMMARY)
{
std::cerr << "p3ForumsV2::getMsgSummary() ERROR AnsType Wrong" << std::endl;
return false;
}
if ((reqtype != GXS_REQUEST_TYPE_MSGS) && (reqtype != GXS_REQUEST_TYPE_MSGRELATED))
{
std::cerr << "p3ForumsV2::getMsgSummary() ERROR ReqType Wrong" << std::endl;
return false;
}
if (status != GXS_REQUEST_STATUS_COMPLETE)
{
std::cerr << "p3ForumsV2::getMsgSummary() ERROR Status Incomplete" << std::endl;
return false;
}
std::list<std::string> msgIds;
bool ans = loadRequestOutList(token, msgIds);
updateRequestStatus(token, GXS_REQUEST_STATUS_DONE);
/* convert to RsMsgMetaData */
mProxy->getMsgSummary(msgIds, msgInfo);
return ans;
}
/* Specific Service Data */
bool p3ForumsV2::getGroupData(const uint32_t &token, RsForumV2Group &group)
{
uint32_t status;
uint32_t reqtype;
uint32_t anstype;
time_t ts;
checkRequestStatus(token, status, reqtype, anstype, ts);
if (anstype != RS_TOKREQ_ANSTYPE_DATA)
{
std::cerr << "p3ForumsV2::getGroupData() ERROR AnsType Wrong" << std::endl;
return false;
}
if (reqtype != GXS_REQUEST_TYPE_GROUPS)
{
std::cerr << "p3ForumsV2::getGroupData() ERROR ReqType Wrong" << std::endl;
return false;
}
if (status != GXS_REQUEST_STATUS_COMPLETE)
{
std::cerr << "p3ForumsV2::getGroupData() ERROR Status Incomplete" << std::endl;
return false;
}
std::string id;
if (!popRequestOutList(token, id))
{
/* finished */
updateRequestStatus(token, GXS_REQUEST_STATUS_DONE);
return false;
}
/* convert to RsForumAlbum */
bool ans = mForumProxy->getForumGroup(id, group);
return ans;
}
bool p3ForumsV2::getMsgData(const uint32_t &token, RsForumV2Msg &msg)
{
uint32_t status;
uint32_t reqtype;
uint32_t anstype;
time_t ts;
checkRequestStatus(token, status, reqtype, anstype, ts);
if (anstype != RS_TOKREQ_ANSTYPE_DATA)
{
std::cerr << "p3ForumsV2::getMsgData() ERROR AnsType Wrong" << std::endl;
return false;
}
if ((reqtype != GXS_REQUEST_TYPE_MSGS) && (reqtype != GXS_REQUEST_TYPE_MSGRELATED))
{
std::cerr << "p3ForumsV2::getMsgData() ERROR ReqType Wrong" << std::endl;
return false;
}
if (status != GXS_REQUEST_STATUS_COMPLETE)
{
std::cerr << "p3ForumsV2::getMsgData() ERROR Status Incomplete" << std::endl;
return false;
}
std::string id;
if (!popRequestOutList(token, id))
{
/* finished */
updateRequestStatus(token, GXS_REQUEST_STATUS_DONE);
return false;
}
/* convert to RsForumAlbum */
bool ans = mForumProxy->getForumMsg(id, msg);
return ans;
}
/* Poll */
uint32_t p3ForumsV2::requestStatus(const uint32_t token)
{
uint32_t status;
uint32_t reqtype;
uint32_t anstype;
time_t ts;
checkRequestStatus(token, status, reqtype, anstype, ts);
return status;
}
/* Cancel Request */
bool p3ForumsV2::cancelRequest(const uint32_t &token)
{
return clearRequest(token);
}
//////////////////////////////////////////////////////////////////////////////
bool p3ForumsV2::setMessageStatus(const std::string &msgId, const uint32_t status, const uint32_t statusMask)
{
return mForumProxy->setMessageStatus(msgId, status, statusMask);
}
bool p3ForumsV2::setGroupStatus(const std::string &groupId, const uint32_t status, const uint32_t statusMask)
{
return mForumProxy->setGroupStatus(groupId, status, statusMask);
}
bool p3ForumsV2::setGroupSubscribeFlags(const std::string &groupId, uint32_t subscribeFlags, uint32_t subscribeMask)
{
return mForumProxy->setGroupSubscribeFlags(groupId, subscribeFlags, subscribeMask);
}
bool p3ForumsV2::setMessageServiceString(const std::string &msgId, const std::string &str)
{
return mForumProxy->setMessageServiceString(msgId, str);
}
bool p3ForumsV2::setGroupServiceString(const std::string &grpId, const std::string &str)
{
return mForumProxy->setGroupServiceString(grpId, str);
}
bool p3ForumsV2::groupRestoreKeys(const std::string &groupId)
{
return false;
}
bool p3ForumsV2::groupShareKeys(const std::string &groupId, std::list<std::string>& peers)
{
return false;
}
/********************************************************************************************/
std::string p3ForumsV2::genRandomId()
{
std::string randomId;
for(int i = 0; i < 20; i++)
{
randomId += (char) ('a' + (RSRandom::random_u32() % 26));
}
return randomId;
}
bool p3ForumsV2::createGroup(uint32_t &token, RsForumV2Group &group, bool isNew)
{
if (group.mMeta.mGroupId.empty())
{
/* new photo */
/* generate a temp id */
group.mMeta.mGroupId = genRandomId();
}
else
{
std::cerr << "p3ForumsV2::createGroup() Group with existing Id... dropping";
std::cerr << std::endl;
return false;
}
{
RsStackMutex stack(mForumMtx); /********** STACK LOCKED MTX ******/
mUpdated = true;
mForumProxy->addForumGroup(group);
}
// Fake a request to return the GroupMetaData.
generateToken(token);
uint32_t ansType = RS_TOKREQ_ANSTYPE_SUMMARY;
RsTokReqOptions opts; // NULL is good.
std::list<std::string> groupIds;
groupIds.push_back(group.mMeta.mGroupId); // It will just return this one.
std::cerr << "p3ForumsV2::createGroup() Generating Request Token: " << token << std::endl;
storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_GROUPS, groupIds);
return true;
}
bool p3ForumsV2::createMsg(uint32_t &token, RsForumV2Msg &msg, bool isNew)
{
if (msg.mMeta.mGroupId.empty())
{
/* new photo */
std::cerr << "p3ForumsV2::createForumMsg() Missing MsgID";
std::cerr << std::endl;
return false;
}
/* check if its a mod or new msg */
if (msg.mMeta.mOrigMsgId.empty())
{
std::cerr << "p3ForumsV2::createForumMsg() New Msg";
std::cerr << std::endl;
/* new msg, generate a new OrigMsgId */
msg.mMeta.mOrigMsgId = genRandomId();
msg.mMeta.mMsgId = msg.mMeta.mOrigMsgId;
}
else
{
std::cerr << "p3ForumsV2::createForumMsg() Modified Msg";
std::cerr << std::endl;
/* mod msg, keep orig msg id, generate a new MsgId */
msg.mMeta.mMsgId = genRandomId();
}
std::cerr << "p3ForumsV2::createForumMsg() GroupId: " << msg.mMeta.mGroupId;
std::cerr << std::endl;
std::cerr << "p3ForumsV2::createForumMsg() MsgId: " << msg.mMeta.mMsgId;
std::cerr << std::endl;
std::cerr << "p3ForumsV2::createForumMsg() OrigMsgId: " << msg.mMeta.mOrigMsgId;
std::cerr << std::endl;
{
RsStackMutex stack(mForumMtx); /********** STACK LOCKED MTX ******/
mUpdated = true;
mForumProxy->addForumMsg(msg);
}
// Fake a request to return the MsgMetaData.
generateToken(token);
uint32_t ansType = RS_TOKREQ_ANSTYPE_SUMMARY;
RsTokReqOptions opts; // NULL is good.
std::list<std::string> msgIds;
msgIds.push_back(msg.mMeta.mMsgId); // It will just return this one.
std::cerr << "p3ForumsV2::createMsg() Generating Request Token: " << token << std::endl;
storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_MSGRELATED, msgIds);
return true;
}
/********************************************************************************************/
bool ForumDataProxy::getForumGroup(const std::string &id, RsForumV2Group &group)
{
void *groupData = NULL;
RsGroupMetaData meta;
if (getGroupData(id, groupData) && getGroupSummary(id, meta))
{
RsForumV2Group *pG = (RsForumV2Group *) groupData;
group = *pG;
// update definitive version of the metadata.
group.mMeta = meta;
std::cerr << "ForumDataProxy::getForumGroup() Id: " << id;
std::cerr << " MetaData: " << meta << " DataPointer: " << groupData;
std::cerr << std::endl;
return true;
}
std::cerr << "ForumDataProxy::getForumGroup() FAILED Id: " << id;
std::cerr << std::endl;
return false;
}
bool ForumDataProxy::getForumMsg(const std::string &id, RsForumV2Msg &page)
{
void *msgData = NULL;
RsMsgMetaData meta;
if (getMsgData(id, msgData) && getMsgSummary(id, meta))
{
RsForumV2Msg *pP = (RsForumV2Msg *) msgData;
// Shallow copy of thumbnail.
page = *pP;
// update definitive version of the metadata.
page.mMeta = meta;
std::cerr << "ForumDataProxy::getForumMsg() Id: " << id;
std::cerr << " MetaData: " << meta << " DataPointer: " << msgData;
std::cerr << std::endl;
return true;
}
std::cerr << "ForumDataProxy::getForumMsg() FAILED Id: " << id;
std::cerr << std::endl;
return false;
}
bool ForumDataProxy::addForumGroup(const RsForumV2Group &group)
{
// Make duplicate.
RsForumV2Group *pG = new RsForumV2Group();
*pG = group;
std::cerr << "ForumDataProxy::addForumGroup()";
std::cerr << " MetaData: " << pG->mMeta << " DataPointer: " << pG;
std::cerr << std::endl;
return createGroup(pG);
}
bool ForumDataProxy::addForumMsg(const RsForumV2Msg &msg)
{
// Make duplicate.
RsForumV2Msg *pM = new RsForumV2Msg();
*pM = msg;
std::cerr << "ForumDataProxy::addForumMsg()";
std::cerr << " MetaData: " << pM->mMeta << " DataPointer: " << pM;
std::cerr << std::endl;
return createMsg(pM);
}
/* These Functions must be overloaded to complete the service */
bool ForumDataProxy::convertGroupToMetaData(void *groupData, RsGroupMetaData &meta)
{
RsForumV2Group *group = (RsForumV2Group *) groupData;
meta = group->mMeta;
return true;
}
bool ForumDataProxy::convertMsgToMetaData(void *msgData, RsMsgMetaData &meta)
{
RsForumV2Msg *page = (RsForumV2Msg *) msgData;
meta = page->mMeta;
return true;
}
/********************************************************************************************/
bool p3ForumsV2::generateDummyData()
{
/* so we want to generate 100's of forums */
#define MAX_FORUMS 10 //100
#define MAX_THREADS 10 //1000
#define MAX_MSGS 100 //10000
std::list<RsForumV2Group> mGroups;
std::list<RsForumV2Group>::iterator git;
std::list<RsForumV2Msg> mMsgs;
std::list<RsForumV2Msg>::iterator mit;
#define DUMMY_NAME_MAX_LEN 10000
char name[DUMMY_NAME_MAX_LEN];
int i, j;
time_t now = time(NULL);
for(i = 0; i < MAX_FORUMS; i++)
{
/* generate a new forum */
RsForumV2Group forum;
/* generate a temp id */
forum.mMeta.mGroupId = genRandomId();
snprintf(name, DUMMY_NAME_MAX_LEN, "TestForum_%d", i+1);
forum.mMeta.mGroupId = genRandomId();
forum.mMeta.mGroupName = name;
forum.mMeta.mPublishTs = now - (RSRandom::random_f32() * 100000);
/* key fields to fill in:
* GroupId.
* Name.
* Flags.
* Pop.
*/
/* use probability to decide which are subscribed / own / popularity.
*/
float rnd = RSRandom::random_f32();
if (rnd < 0.1)
{
forum.mMeta.mSubscribeFlags = RSGXS_GROUP_SUBSCRIBE_ADMIN;
}
else if (rnd < 0.3)
{
forum.mMeta.mSubscribeFlags = RSGXS_GROUP_SUBSCRIBE_SUBSCRIBED;
}
else
{
forum.mMeta.mSubscribeFlags = 0;
}
forum.mMeta.mPop = (int) (RSRandom::random_f32() * 10.0);
mGroups.push_back(forum);
//std::cerr << "p3ForumsV2::generateDummyData() Generated Forum: " << forum.mMeta;
//std::cerr << std::endl;
}
for(i = 0; i < MAX_THREADS; i++)
{
/* generate a base thread */
/* rotate the Forum Groups Around, then pick one.
*/
int rnd = (int) (RSRandom::random_f32() * 10.0);
for(j = 0; j < rnd; j++)
{
RsForumV2Group head = mGroups.front();
mGroups.pop_front();
mGroups.push_back(head);
}
RsForumV2Group forum = mGroups.front();
/* now create a new thread */
RsForumV2Msg msg;
/* fill in key data
* GroupId
* MsgId
* OrigMsgId
* ThreadId
* ParentId
* PublishTS (take Forum TS + a bit ).
*
* ChildTS ????
*/
snprintf(name, DUMMY_NAME_MAX_LEN, "%s => ThreadMsg_%d", forum.mMeta.mGroupName.c_str(), i+1);
msg.mMeta.mMsgName = name;
msg.mMeta.mGroupId = forum.mMeta.mGroupId;
msg.mMeta.mMsgId = genRandomId();
msg.mMeta.mOrigMsgId = msg.mMeta.mMsgId;
msg.mMeta.mThreadId = msg.mMeta.mMsgId;
msg.mMeta.mParentId = "";
msg.mMeta.mPublishTs = forum.mMeta.mPublishTs + (RSRandom::random_f32() * 10000);
if (msg.mMeta.mPublishTs > now)
msg.mMeta.mPublishTs = now - 1;
mMsgs.push_back(msg);
//std::cerr << "p3ForumsV2::generateDummyData() Generated Thread: " << msg.mMeta;
//std::cerr << std::endl;
}
for(i = 0; i < MAX_MSGS; i++)
{
/* generate a base thread */
/* rotate the Forum Groups Around, then pick one.
*/
int rnd = (int) (RSRandom::random_f32() * 10.0);
for(j = 0; j < rnd; j++)
{
RsForumV2Msg head = mMsgs.front();
mMsgs.pop_front();
mMsgs.push_back(head);
}
RsForumV2Msg parent = mMsgs.front();
/* now create a new child msg */
RsForumV2Msg msg;
/* fill in key data
* GroupId
* MsgId
* OrigMsgId
* ThreadId
* ParentId
* PublishTS (take Forum TS + a bit ).
*
* ChildTS ????
*/
snprintf(name, DUMMY_NAME_MAX_LEN, "%s => Msg_%d", parent.mMeta.mMsgName.c_str(), i+1);
msg.mMeta.mMsgName = name;
msg.mMsg = name;
msg.mMeta.mGroupId = parent.mMeta.mGroupId;
msg.mMeta.mMsgId = genRandomId();
msg.mMeta.mOrigMsgId = msg.mMeta.mMsgId;
msg.mMeta.mThreadId = parent.mMeta.mThreadId;
msg.mMeta.mParentId = parent.mMeta.mOrigMsgId;
msg.mMeta.mPublishTs = parent.mMeta.mPublishTs + (RSRandom::random_f32() * 10000);
if (msg.mMeta.mPublishTs > now)
msg.mMeta.mPublishTs = now - 1;
mMsgs.push_back(msg);
//std::cerr << "p3ForumsV2::generateDummyData() Generated Child Msg: " << msg.mMeta;
//std::cerr << std::endl;
}
mUpdated = true;
/* Then - at the end, we push them all into the Proxy */
for(git = mGroups.begin(); git != mGroups.end(); git++)
{
/* pushback */
mForumProxy->addForumGroup(*git);
}
for(mit = mMsgs.begin(); mit != mMsgs.end(); mit++)
{
/* pushback */
mForumProxy->addForumMsg(*mit);
}
return true;
}

View file

@ -1,126 +0,0 @@
/*
* libretroshare/src/services: p3forumsv2.h
*
* Wiki interface for RetroShare.
*
* Copyright 2012-2012 by Robert Fernie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2 as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
#ifndef P3_FORUMSV2_SERVICE_HEADER
#define P3_FORUMSV2_SERVICE_HEADER
#include "services/p3gxsservice.h"
#include "retroshare/rsforumsv2.h"
#include <map>
#include <string>
/*
*
*/
class ForumDataProxy: public GxsDataProxy
{
public:
bool getForumGroup(const std::string &id, RsForumV2Group &group);
bool getForumMsg(const std::string &id, RsForumV2Msg &msg);
bool addForumGroup(const RsForumV2Group &group);
bool addForumMsg(const RsForumV2Msg &msg);
/* These Functions must be overloaded to complete the service */
virtual bool convertGroupToMetaData(void *groupData, RsGroupMetaData &meta);
virtual bool convertMsgToMetaData(void *msgData, RsMsgMetaData &meta);
};
class p3ForumsV2: public p3GxsDataService, public RsForumsV2
{
public:
p3ForumsV2(uint16_t type);
virtual int tick();
public:
virtual bool updated();
/* Data Requests */
virtual bool requestGroupInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list<std::string> &groupIds);
virtual bool requestMsgInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list<std::string> &groupIds);
virtual bool requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list<std::string> &msgIds);
/* Generic Lists */
virtual bool getGroupList( const uint32_t &token, std::list<std::string> &groupIds);
virtual bool getMsgList( const uint32_t &token, std::list<std::string> &msgIds);
/* Generic Summary */
virtual bool getGroupSummary( const uint32_t &token, std::list<RsGroupMetaData> &groupInfo);
virtual bool getMsgSummary( const uint32_t &token, std::list<RsMsgMetaData> &msgInfo);
/* Actual Data -> specific to Interface */
/* Specific Service Data */
virtual bool getGroupData(const uint32_t &token, RsForumV2Group &group);
virtual bool getMsgData(const uint32_t &token, RsForumV2Msg &msg);
/* Poll */
virtual uint32_t requestStatus(const uint32_t token);
/* Cancel Request */
virtual bool cancelRequest(const uint32_t &token);
//////////////////////////////////////////////////////////////////////////////
virtual bool setMessageStatus(const std::string &msgId, const uint32_t status, const uint32_t statusMask);
virtual bool setGroupStatus(const std::string &groupId, const uint32_t status, const uint32_t statusMask);
virtual bool setGroupSubscribeFlags(const std::string &groupId, uint32_t subscribeFlags, uint32_t subscribeMask);
virtual bool setMessageServiceString(const std::string &msgId, const std::string &str);
virtual bool setGroupServiceString(const std::string &grpId, const std::string &str);
virtual bool groupRestoreKeys(const std::string &groupId);
virtual bool groupShareKeys(const std::string &groupId, std::list<std::string>& peers);
virtual bool createGroup(uint32_t &token, RsForumV2Group &group, bool isNew);
virtual bool createMsg(uint32_t &token, RsForumV2Msg &msg, bool isNew);
private:
std::string genRandomId();
bool generateDummyData();
ForumDataProxy *mForumProxy;
RsMutex mForumMtx;
/***** below here is locked *****/
bool mUpdated;
};
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,246 @@
/*
* libretroshare/src/services: p3circles.h
*
* Identity interface for RetroShare.
*
* Copyright 2012-2012 by Robert Fernie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2.1 as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
#ifndef P3_CIRCLES_SERVICE_HEADER
#define P3_CIRCLES_SERVICE_HEADER
#include "retroshare/rsgxscircles.h" // External Interfaces.
#include "gxs/rsgenexchange.h" // GXS service.
#include "gxs/rsgixs.h" // Internal Interfaces.
#include "services/p3idservice.h" // For constructing Caches
#include "gxs/gxstokenqueue.h"
#include "util/rstickevent.h"
#include "util/rsmemcache.h"
#include <map>
#include <string>
/*
* Circles Identity Service
*
* A collection of notes:
*
* We want to be able to express the following types of Circles.
*
* - Public
* - Groups & Messages can be passed onto anyone. ( No Restrictions. )
* - GXS Notes:
* - This is what we have currently.
*
* - External Circle
* - List of Identities that can receive the Group / Messages.
* - This list will be defined via a set of RsIdentities - which have PGPHashes set.
* - We need the PGPHashes to be able to identify which peers can receive msgs.
* - Messages are passed to the Intersection of (Identified PGPHashes & Friends)
* - Distribution of Circle Definitions can be also be restricted via circles.
* - You can have Public External Groups, or Groups that only the Members know about.
* - Control of these External Groups is determined by Admin / Publish Keys.
* - The Danger with External Groups, is your ID wll be associated with other people...
* - Leaking information!!!
* - GXS Notes:
* - p3Circles will provide a distrib list for a given Circle Group.
*
* - Personal Circle or "Your Eyes Only".
* - Same as an Internal Circle Definition. (What will be used for File Sharing initially)
* - Each peer will have a bunch of these, Friends, Family, etc.
*
* - The list is not publically shared, only the originator of the message will distribute.
* - You can communicate back to the originator, who will share with the other members.
* but you mustn't discuss / share content with anyone else.
* - This is quite a Weak / Fragile Group, as there is only one distributor.
* - GXS NOTES:
* - TO make this work, we need GXS or RsCircles to maintain extra info:
* - GXS stores the original source, so communications can go back there.
* - If Originator, GXS store a REFERENCE, Circles turn this into a distrib list of peers.
*
*
*
* Like RsIdentities are used to validation messages,
* RsCircles will be used to determine if a peer can receive a group / messages.
*
* bool RsCircles::canSend(RsGxsCircleId, RsPeerId)
* bool RsCircles::canSend(RsCircleInternalId, RsPeerId)
*
* or maybe just:
*
* bool RsCircles::recipients(GxsPermission &perms, std::list<RsPeerId> friendlist);
*
*/
/* Permissions is part of GroupMetaData
*/
class RsGxsCircleCache
{
public:
RsGxsCircleCache();
bool loadBaseCircle(const RsGxsCircleGroup &circle);
bool loadSubCircle(const RsGxsCircleCache &subcircle);
bool getAllowedPeersList(std::list<RsPgpId> &friendlist);
bool isAllowedPeer(const RsPgpId &id);
bool addAllowedPeer(const RsPgpId &pgpid, const RsGxsId &gxsId);
RsGxsCircleId mCircleId;
std::string mCircleName;
time_t mUpdateTime;
std::set<RsGxsCircleId> mUnprocessedCircles;
std::set<RsGxsId> mUnprocessedPeers;
std::set<RsGxsCircleId> mProcessedCircles;
std::set<RsGxsId> mUnknownPeers;
std::map<RsPgpId, std::list<RsGxsId> > mAllowedPeers;
};
class RsCircles
{
/* Functions to handle Local / Internal Circles == Same as for file permissions. */
public:
virtual void createLocalCircle() = 0;
virtual void addToLocalCircle() = 0;
virtual void removeFromLocalCircle() = 0;
virtual void getLocalCirclePeers() = 0;
virtual void getListOfLocalCircles() = 0;
/* similar functions for External Groups */
virtual bool createGroup(uint32_t& token, RsGxsCircleGroup &group) = 0;
virtual bool getGroupData(const uint32_t &token, std::vector<RsGxsCircleGroup> &groups) = 0;
};
class p3GxsCircles: public RsGxsCircleExchange, public RsGxsCircles,
public GxsTokenQueue, public RsTickEvent
{
public:
p3GxsCircles(RsGeneralDataService* gds, RsNetworkExchangeService* nes,
p3IdService *identities);
/*********** External Interface ***************/
virtual bool getCircleDetails(const RsGxsCircleId &id, RsGxsCircleDetails &details);
virtual bool getCircleIdList(std::list<RsGxsCircleId> &circleIds);
virtual bool isLoaded(const RsGxsCircleId &circleId);
virtual bool loadCircle(const RsGxsCircleId &circleId);
virtual int canSend(const RsGxsCircleId &circleId, const RsPgpId &id);
virtual bool recipients(const RsGxsCircleId &circleId, std::list<RsPgpId> &friendlist);
/*******/
virtual void createLocalCircle();
virtual void addToLocalCircle();
virtual void removeFromLocalCircle();
virtual void getLocalCirclePeers();
virtual void getListOfLocalCircles();
/*******/
virtual bool getGroupData(const uint32_t &token, std::vector<RsGxsCircleGroup> &groups);
virtual bool createGroup(uint32_t& token, RsGxsCircleGroup &group);
/**********************************************/
// needed for background processing.
virtual void service_tick();
protected:
static uint32_t circleAuthenPolicy();
/** Notifications **/
virtual void notifyChanges(std::vector<RsGxsNotify*>& changes);
/** Overloaded to add PgpIdHash to Group Definition **/
virtual void service_CreateGroup(RsGxsGrpItem* grpItem, RsTlvSecurityKeySet& keySet);
// Overloaded from GxsTokenQueue for Request callbacks.
virtual void handleResponse(uint32_t token, uint32_t req_type);
// Overloaded from RsTickEvent.
virtual void handle_event(uint32_t event_type, const std::string &elabel);
private:
// Load data.
bool request_CircleIdList();
bool load_CircleIdList(uint32_t token);
// Need some crazy arsed cache to store the circle info.
// so we don't have to keep loading groups.
int cache_tick();
bool cache_request_load(const RsGxsCircleId &id);
bool cache_start_load();
bool cache_load_for_token(uint32_t token);
bool cache_reloadids(const std::string &circleId);
p3IdService *mIdentities; // Needed for constructing Circle Info,
RsMutex mCircleMtx; /* Locked Below Here */
std::list<RsGxsCircleId> mCircleIdList;
/***** Caching Circle Info, *****/
// initial load queue
std::list<RsGxsCircleId> mCacheLoad_ToCache;
// waiting for subcircle to load. (first is part of each of the second list)
// TODO.
//std::map<RsGxsCircleId, std::list<RsGxsCircleId> > mCacheLoad_SubCircle;
// Circles that are being loaded.
std::map<RsGxsCircleId, RsGxsCircleCache> mLoadingCache;
// actual cache.
RsMemCache<RsGxsCircleId, RsGxsCircleCache> mCircleCache;
private:
std::string genRandomId();
void generateDummyData();
void checkDummyIdData();
void generateDummyCircle();
uint32_t mDummyIdToken;
std::list<RsGxsId> mDummyPgpLinkedIds;
std::list<RsGxsId> mDummyOwnIds;
};
#endif // P3_CIRCLES_SERVICE_HEADER

View file

@ -0,0 +1,471 @@
/*
* libretroshare/src/services p3gxsforums.cc
*
* GxsForums interface for RetroShare.
*
* Copyright 2012-2012 by Robert Fernie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2.1 as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
#include "services/p3gxsforums.h"
#include "serialiser/rsgxsforumitems.h"
#include <retroshare/rsidentity.h>
#include "gxs/rsgxsflags.h"
#include <stdio.h>
// For Dummy Msgs.
#include "util/rsrandom.h"
#include "util/rsstring.h"
/****
* #define GXSFORUM_DEBUG 1
****/
RsGxsForums *rsGxsForums = NULL;
#define FORUM_TESTEVENT_DUMMYDATA 0x0001
#define DUMMYDATA_PERIOD 60 // long enough for some RsIdentities to be generated.
/********************************************************************************/
/******************* Startup / Tick ******************************************/
/********************************************************************************/
p3GxsForums::p3GxsForums(RsGeneralDataService *gds, RsNetworkExchangeService *nes)
: RsGenExchange(gds, nes, new RsGxsForumSerialiser(), RS_SERVICE_GXSV1_TYPE_FORUMS), RsGxsForums(this)
{
// For Dummy Msgs.
mGenActive = false;
RsTickEvent::schedule_in(FORUM_TESTEVENT_DUMMYDATA, DUMMYDATA_PERIOD);
}
void p3GxsForums::notifyChanges(std::vector<RsGxsNotify *> &changes)
{
receiveChanges(changes);
}
void p3GxsForums::service_tick()
{
dummy_tick();
RsTickEvent::tick_events();
return;
}
bool p3GxsForums::getGroupData(const uint32_t &token, std::vector<RsGxsForumGroup> &groups)
{
std::vector<RsGxsGrpItem*> grpData;
bool ok = RsGenExchange::getGroupData(token, grpData);
if(ok)
{
std::vector<RsGxsGrpItem*>::iterator vit = grpData.begin();
for(; vit != grpData.end(); vit++)
{
RsGxsForumGroupItem* item = dynamic_cast<RsGxsForumGroupItem*>(*vit);
RsGxsForumGroup grp = item->mGroup;
item->mGroup.mMeta = item->meta;
grp.mMeta = item->mGroup.mMeta;
delete item;
groups.push_back(grp);
}
}
return ok;
}
/* Okay - chris is not going to be happy with this...
* but I can't be bothered with crazy data structures
* at the moment - fix it up later
*/
bool p3GxsForums::getMsgData(const uint32_t &token, std::vector<RsGxsForumMsg> &msgs)
{
GxsMsgDataMap msgData;
bool ok = RsGenExchange::getMsgData(token, msgData);
if(ok)
{
GxsMsgDataMap::iterator mit = msgData.begin();
for(; mit != msgData.end(); mit++)
{
RsGxsGroupId grpId = mit->first;
std::vector<RsGxsMsgItem*>& msgItems = mit->second;
std::vector<RsGxsMsgItem*>::iterator vit = msgItems.begin();
for(; vit != msgItems.end(); vit++)
{
RsGxsForumMsgItem* item = dynamic_cast<RsGxsForumMsgItem*>(*vit);
if(item)
{
RsGxsForumMsg msg = item->mMsg;
msg.mMeta = item->meta;
msgs.push_back(msg);
delete item;
}
else
{
std::cerr << "Not a GxsForumMsgItem, deleting!" << std::endl;
delete *vit;
}
}
}
}
return ok;
}
bool p3GxsForums::getRelatedMessages(const uint32_t &token, std::vector<RsGxsForumMsg> &msgs)
{
GxsMsgRelatedDataMap msgData;
bool ok = RsGenExchange::getMsgRelatedData(token, msgData);
if(ok)
{
GxsMsgRelatedDataMap::iterator mit = msgData.begin();
for(; mit != msgData.end(); mit++)
{
std::vector<RsGxsMsgItem*>& msgItems = mit->second;
std::vector<RsGxsMsgItem*>::iterator vit = msgItems.begin();
for(; vit != msgItems.end(); vit++)
{
RsGxsForumMsgItem* item = dynamic_cast<RsGxsForumMsgItem*>(*vit);
if(item)
{
/* HACK UNTIL CHRIS FIXES RELATED MSGS in GXS */
if (item->meta.mMsgId == (mit->first).second)
{
std::cerr << "p3GxsForums::getRelatedMessages()";
std::cerr << " ERROR Found Original - discarding";
std::cerr << " Id: " << item->meta.mMsgId;
std::cerr << std::endl;
delete item;
continue;
}
if (item->meta.mParentId != (mit->first).second)
{
std::cerr << "p3GxsForums::getRelatedMessages()";
std::cerr << " ERROR Found !CHILD - discarding";
std::cerr << " Id: " << item->meta.mMsgId;
std::cerr << std::endl;
delete item;
continue;
}
RsGxsForumMsg msg = item->mMsg;
msg.mMeta = item->meta;
msgs.push_back(msg);
delete item;
}
else
{
std::cerr << "Not a GxsForumMsgItem, deleting!" << std::endl;
delete *vit;
}
}
}
}
return ok;
}
/********************************************************************************************/
bool p3GxsForums::createGroup(uint32_t &token, RsGxsForumGroup &group)
{
std::cerr << "p3GxsForums::createGroup()" << std::endl;
RsGxsForumGroupItem* grpItem = new RsGxsForumGroupItem();
grpItem->mGroup = group;
grpItem->meta = group.mMeta;
RsGenExchange::publishGroup(token, grpItem);
return true;
}
bool p3GxsForums::createMsg(uint32_t &token, RsGxsForumMsg &msg)
{
std::cerr << "p3GxsForums::createForumMsg() GroupId: " << msg.mMeta.mGroupId;
std::cerr << std::endl;
RsGxsForumMsgItem* msgItem = new RsGxsForumMsgItem();
msgItem->mMsg = msg;
msgItem->meta = msg.mMeta;
RsGenExchange::publishMsg(token, msgItem);
return true;
}
/********************************************************************************************/
/********************************************************************************************/
void p3GxsForums::setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool read)
{
uint32_t mask = GXS_SERV::GXS_MSG_STATUS_UNREAD | GXS_SERV::GXS_MSG_STATUS_UNPROCESSED;
uint32_t status = GXS_SERV::GXS_MSG_STATUS_UNREAD;
if (read)
{
status = 0;
}
setMsgStatusFlags(token, msgId, status, mask);
}
/********************************************************************************************/
/********************************************************************************************/
/* so we need the same tick idea as wiki for generating dummy forums
*/
#define MAX_GEN_GROUPS 5
#define MAX_GEN_MESSAGES 100
std::string p3GxsForums::genRandomId()
{
std::string randomId;
for(int i = 0; i < 20; i++)
{
randomId += (char) ('a' + (RSRandom::random_u32() % 26));
}
return randomId;
}
bool p3GxsForums::generateDummyData()
{
mGenCount = 0;
mGenRefs.resize(MAX_GEN_MESSAGES);
std::string groupName;
rs_sprintf(groupName, "TestForum_%d", mGenCount);
std::cerr << "p3GxsForums::generateDummyData() Starting off with Group: " << groupName;
std::cerr << std::endl;
/* create a new group */
generateGroup(mGenToken, groupName);
mGenActive = true;
return true;
}
void p3GxsForums::dummy_tick()
{
/* check for a new callback */
if (mGenActive)
{
std::cerr << "p3GxsForums::dummyTick() AboutActive";
std::cerr << std::endl;
uint32_t status = RsGenExchange::getTokenService()->requestStatus(mGenToken);
if (status != RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE)
{
std::cerr << "p3GxsForums::dummy_tick() Status: " << status;
std::cerr << std::endl;
if (status == RsTokenService::GXS_REQUEST_V2_STATUS_FAILED)
{
std::cerr << "p3GxsForums::dummy_tick() generateDummyMsgs() FAILED";
std::cerr << std::endl;
mGenActive = false;
}
return;
}
if (mGenCount < MAX_GEN_GROUPS)
{
/* get the group Id */
RsGxsGroupId groupId;
RsGxsMessageId emptyId;
if (!acknowledgeTokenGrp(mGenToken, groupId))
{
std::cerr << " ERROR ";
std::cerr << std::endl;
mGenActive = false;
return;
}
std::cerr << "p3GxsForums::dummy_tick() Acknowledged GroupId: " << groupId;
std::cerr << std::endl;
ForumDummyRef ref(groupId, emptyId, emptyId);
mGenRefs[mGenCount] = ref;
}
else if (mGenCount < MAX_GEN_MESSAGES)
{
/* get the msg Id, and generate next snapshot */
RsGxsGrpMsgIdPair msgId;
if (!acknowledgeTokenMsg(mGenToken, msgId))
{
std::cerr << " ERROR ";
std::cerr << std::endl;
mGenActive = false;
return;
}
std::cerr << "p3GxsForums::dummy_tick() Acknowledged <GroupId: " << msgId.first << ", MsgId: " << msgId.second << ">";
std::cerr << std::endl;
/* store results for later selection */
ForumDummyRef ref(msgId.first, mGenThreadId, msgId.second);
mGenRefs[mGenCount] = ref;
}
else
{
std::cerr << "p3GxsForums::dummy_tick() Finished";
std::cerr << std::endl;
/* done */
mGenActive = false;
return;
}
mGenCount++;
if (mGenCount < MAX_GEN_GROUPS)
{
std::string groupName;
rs_sprintf(groupName, "TestForum_%d", mGenCount);
std::cerr << "p3GxsForums::dummy_tick() Generating Group: " << groupName;
std::cerr << std::endl;
/* create a new group */
generateGroup(mGenToken, groupName);
}
else
{
/* create a new message */
uint32_t idx = (uint32_t) (mGenCount * RSRandom::random_f32());
ForumDummyRef &ref = mGenRefs[idx];
RsGxsGroupId grpId = ref.mGroupId;
RsGxsMessageId parentId = ref.mMsgId;
mGenThreadId = ref.mThreadId;
if (mGenThreadId.empty())
{
mGenThreadId = parentId;
}
std::cerr << "p3GxsForums::dummy_tick() Generating Msg ... ";
std::cerr << " GroupId: " << grpId;
std::cerr << " ThreadId: " << mGenThreadId;
std::cerr << " ParentId: " << parentId;
std::cerr << std::endl;
generateMessage(mGenToken, grpId, parentId, mGenThreadId);
}
}
}
bool p3GxsForums::generateMessage(uint32_t &token, const RsGxsGroupId &grpId, const RsGxsMessageId &parentId, const RsGxsMessageId &threadId)
{
RsGxsForumMsg msg;
std::string rndId = genRandomId();
rs_sprintf(msg.mMsg, "Forum Msg: GroupId: %s, ThreadId: %s, ParentId: %s + some randomness: %s",
grpId.c_str(), threadId.c_str(), parentId.c_str(), rndId.c_str());
msg.mMeta.mMsgName = msg.mMsg;
msg.mMeta.mGroupId = grpId;
msg.mMeta.mThreadId = threadId;
msg.mMeta.mParentId = parentId;
msg.mMeta.mMsgStatus = GXS_SERV::GXS_MSG_STATUS_UNPROCESSED | GXS_SERV::GXS_MSG_STATUS_UNREAD;
/* chose a random Id to sign with */
std::list<RsGxsId> ownIds;
std::list<RsGxsId>::iterator it;
rsIdentity->getOwnIds(ownIds);
uint32_t idx = (uint32_t) (ownIds.size() * RSRandom::random_f32());
int i = 0;
for(it = ownIds.begin(); (it != ownIds.end()) && (i < idx); it++, i++);
if (it != ownIds.end())
{
std::cerr << "p3GxsForums::generateMessage() Author: " << *it;
std::cerr << std::endl;
msg.mMeta.mAuthorId = *it;
}
else
{
std::cerr << "p3GxsForums::generateMessage() No Author!";
std::cerr << std::endl;
}
createMsg(token, msg);
return true;
}
bool p3GxsForums::generateGroup(uint32_t &token, std::string groupName)
{
/* generate a new forum */
RsGxsForumGroup forum;
forum.mMeta.mGroupName = groupName;
createGroup(token, forum);
return true;
}
// Overloaded from RsTickEvent for Event callbacks.
void p3GxsForums::handle_event(uint32_t event_type, const std::string &elabel)
{
std::cerr << "p3GxsForums::handle_event(" << event_type << ")";
std::cerr << std::endl;
// stuff.
switch(event_type)
{
case FORUM_TESTEVENT_DUMMYDATA:
generateDummyData();
break;
default:
/* error */
std::cerr << "p3GxsForums::handle_event() Unknown Event Type: " << event_type;
std::cerr << std::endl;
break;
}
}

View file

@ -0,0 +1,111 @@
/*
* libretroshare/src/services: p3gxsforums.h
*
* GxsForum interface for RetroShare.
*
* Copyright 2012-2012 by Robert Fernie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2 as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
#ifndef P3_GXSFORUMS_SERVICE_HEADER
#define P3_GXSFORUMS_SERVICE_HEADER
#include "retroshare/rsgxsforums.h"
#include "gxs/rsgenexchange.h"
#include "util/rstickevent.h"
#include <map>
#include <string>
/*
*
*/
class p3GxsForums: public RsGenExchange, public RsGxsForums,
public RsTickEvent /* only needed for testing - remove after */
{
public:
p3GxsForums(RsGeneralDataService* gds, RsNetworkExchangeService* nes);
virtual void service_tick();
protected:
virtual void notifyChanges(std::vector<RsGxsNotify*>& changes);
// Overloaded from RsTickEvent.
virtual void handle_event(uint32_t event_type, const std::string &elabel);
public:
virtual bool getGroupData(const uint32_t &token, std::vector<RsGxsForumGroup> &groups);
virtual bool getMsgData(const uint32_t &token, std::vector<RsGxsForumMsg> &msgs);
virtual bool getRelatedMessages(const uint32_t &token, std::vector<RsGxsForumMsg> &msgs);
//////////////////////////////////////////////////////////////////////////////
virtual void setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool read);
//virtual bool setMessageStatus(const std::string &msgId, const uint32_t status, const uint32_t statusMask);
//virtual bool setGroupSubscribeFlags(const std::string &groupId, uint32_t subscribeFlags, uint32_t subscribeMask);
//virtual bool groupRestoreKeys(const std::string &groupId);
//virtual bool groupShareKeys(const std::string &groupId, std::list<std::string>& peers);
virtual bool createGroup(uint32_t &token, RsGxsForumGroup &group);
virtual bool createMsg(uint32_t &token, RsGxsForumMsg &msg);
private:
virtual bool generateDummyData();
std::string genRandomId();
void dummy_tick();
bool generateMessage(uint32_t &token, const RsGxsGroupId &grpId,
const RsGxsMessageId &parentId, const RsGxsMessageId &threadId);
bool generateGroup(uint32_t &token, std::string groupName);
class ForumDummyRef
{
public:
ForumDummyRef() { return; }
ForumDummyRef(const RsGxsGroupId &grpId, const RsGxsMessageId &threadId, const RsGxsMessageId &msgId)
:mGroupId(grpId), mThreadId(threadId), mMsgId(msgId) { return; }
RsGxsGroupId mGroupId;
RsGxsMessageId mThreadId;
RsGxsMessageId mMsgId;
};
uint32_t mGenToken;
bool mGenActive;
int mGenCount;
std::vector<ForumDummyRef> mGenRefs;
RsGxsMessageId mGenThreadId;
};
#endif

View file

@ -23,16 +23,16 @@
*
*/
#include "services/p3gxsservice.h"
#include "services/p3gxsserviceVEG.h"
p3GxsService::p3GxsService(uint16_t type)
p3GxsServiceVEG::p3GxsServiceVEG(uint16_t type)
:p3Service(type), mReqMtx("p3GxsService")
{
mNextToken = 0;
return;
}
bool p3GxsService::generateToken(uint32_t &token)
bool p3GxsServiceVEG::generateToken(uint32_t &token)
{
RsStackMutex stack(mReqMtx); /****** LOCKED *****/
@ -41,7 +41,7 @@ bool p3GxsService::generateToken(uint32_t &token)
return true;
}
bool p3GxsService::storeRequest(const uint32_t &token, const uint32_t &ansType, const RsTokReqOptions &opts, const uint32_t &type, const std::list<std::string> &ids)
bool p3GxsServiceVEG::storeRequest(const uint32_t &token, const uint32_t &ansType, const RsTokReqOptionsVEG &opts, const uint32_t &type, const std::list<std::string> &ids)
{
RsStackMutex stack(mReqMtx); /****** LOCKED *****/
@ -60,7 +60,7 @@ bool p3GxsService::storeRequest(const uint32_t &token, const uint32_t &ansTyp
}
bool p3GxsService::clearRequest(const uint32_t &token)
bool p3GxsServiceVEG::clearRequest(const uint32_t &token)
{
RsStackMutex stack(mReqMtx); /****** LOCKED *****/
@ -77,7 +77,7 @@ bool p3GxsService::clearRequest(const uint32_t &token)
return true;
}
bool p3GxsService::updateRequestStatus(const uint32_t &token, const uint32_t &status)
bool p3GxsServiceVEG::updateRequestStatus(const uint32_t &token, const uint32_t &status)
{
RsStackMutex stack(mReqMtx); /****** LOCKED *****/
@ -94,7 +94,7 @@ bool p3GxsService::updateRequestStatus(const uint32_t &token, const uint32_t &st
return true;
}
bool p3GxsService::updateRequestInList(const uint32_t &token, std::list<std::string> ids)
bool p3GxsServiceVEG::updateRequestInList(const uint32_t &token, std::list<std::string> ids)
{
RsStackMutex stack(mReqMtx); /****** LOCKED *****/
@ -116,7 +116,7 @@ bool p3GxsService::updateRequestInList(const uint32_t &token, std::list<std::str
}
bool p3GxsService::updateRequestOutList(const uint32_t &token, std::list<std::string> ids)
bool p3GxsServiceVEG::updateRequestOutList(const uint32_t &token, std::list<std::string> ids)
{
RsStackMutex stack(mReqMtx); /****** LOCKED *****/
@ -138,7 +138,7 @@ bool p3GxsService::updateRequestOutList(const uint32_t &token, std::list<std::st
}
#if 0
bool p3GxsService::updateRequestData(const uint32_t &token, std::map<std::string, void *> data)
bool p3GxsServiceVEG::updateRequestData(const uint32_t &token, std::map<std::string, void *> data)
{
RsStackMutex stack(mReqMtx); /****** LOCKED *****/
@ -160,7 +160,7 @@ bool p3GxsService::updateRequestData(const uint32_t &token, std::map<std::string
}
#endif
bool p3GxsService::checkRequestStatus(const uint32_t &token, uint32_t &status, uint32_t &reqtype, uint32_t &anstype, time_t &ts)
bool p3GxsServiceVEG::checkRequestStatus(const uint32_t &token, uint32_t &status, uint32_t &reqtype, uint32_t &anstype, time_t &ts)
{
RsStackMutex stack(mReqMtx); /****** LOCKED *****/
@ -182,7 +182,7 @@ bool p3GxsService::checkRequestStatus(const uint32_t &token, uint32_t &status
// special ones for testing (not in final design)
bool p3GxsService::tokenList(std::list<uint32_t> &tokens)
bool p3GxsServiceVEG::tokenList(std::list<uint32_t> &tokens)
{
RsStackMutex stack(mReqMtx); /****** LOCKED *****/
@ -196,7 +196,7 @@ bool p3GxsService::tokenList(std::list<uint32_t> &tokens)
return true;
}
bool p3GxsService::popRequestInList(const uint32_t &token, std::string &id)
bool p3GxsServiceVEG::popRequestInList(const uint32_t &token, std::string &id)
{
RsStackMutex stack(mReqMtx); /****** LOCKED *****/
@ -220,7 +220,7 @@ bool p3GxsService::popRequestInList(const uint32_t &token, std::string &id)
}
bool p3GxsService::popRequestOutList(const uint32_t &token, std::string &id)
bool p3GxsServiceVEG::popRequestOutList(const uint32_t &token, std::string &id)
{
RsStackMutex stack(mReqMtx); /****** LOCKED *****/
@ -244,7 +244,7 @@ bool p3GxsService::popRequestOutList(const uint32_t &token, std::string &id)
}
bool p3GxsService::loadRequestOutList(const uint32_t &token, std::list<std::string> &ids)
bool p3GxsServiceVEG::loadRequestOutList(const uint32_t &token, std::list<std::string> &ids)
{
RsStackMutex stack(mReqMtx); /****** LOCKED *****/
@ -270,7 +270,7 @@ bool p3GxsService::loadRequestOutList(const uint32_t &token, std::list<std::s
#define MAX_REQUEST_AGE 10
bool p3GxsService::fakeprocessrequests()
bool p3GxsServiceVEG::fakeprocessrequests()
{
std::list<uint32_t>::iterator it;
std::list<uint32_t> tokens;
@ -287,7 +287,7 @@ bool p3GxsService::fakeprocessrequests()
time_t ts;
checkRequestStatus(token, status, reqtype, anstype, ts);
std::cerr << "p3GxsService::fakeprocessrequests() Token: " << token << " Status: " << status << " ReqType: " << reqtype << "Age: " << now - ts << std::endl;
std::cerr << "p3GxsServiceVEG::fakeprocessrequests() Token: " << token << " Status: " << status << " ReqType: " << reqtype << "Age: " << now - ts << std::endl;
if (status == GXS_REQUEST_STATUS_PENDING)
{
@ -299,13 +299,13 @@ bool p3GxsService::fakeprocessrequests()
}
else if (status == GXS_REQUEST_STATUS_DONE)
{
std::cerr << "p3GxsService::fakeprocessrequests() Clearing Done Request Token: " << token;
std::cerr << "p3GxsServiceVEG::fakeprocessrequests() Clearing Done Request Token: " << token;
std::cerr << std::endl;
clearRequest(token);
}
else if (now - ts > MAX_REQUEST_AGE)
{
std::cerr << "p3GxsService::fakeprocessrequests() Clearing Old Request Token: " << token;
std::cerr << "p3GxsServiceVEG::fakeprocessrequests() Clearing Old Request Token: " << token;
std::cerr << std::endl;
clearRequest(token);
}
@ -334,14 +334,14 @@ bool p3GxsService::fakeprocessrequests()
*
****/
GxsDataProxy::GxsDataProxy()
GxsDataProxyVEG::GxsDataProxyVEG()
:mDataMtx("GxsDataProxyMtx")
{
return;
}
static bool checkGroupFilter(const RsTokReqOptions &opts, const RsGroupMetaData &group)
static bool checkGroupFilter(const RsTokReqOptionsVEG &opts, const RsGroupMetaData &group)
{
bool statusMatch = false;
if (opts.mStatusMask)
@ -370,6 +370,33 @@ static bool checkGroupFilter(const RsTokReqOptions &opts, const RsGroupMetaData
statusMatch = true;
}
bool flagsMatch = false;
if (opts.mFlagsMask)
{
// Exact Flags match required.
if ((opts.mFlagsMask & opts.mFlagsFilter) == (opts.mFlagsMask & group.mGroupFlags))
{
std::cerr << "checkGroupFilter() Accepting Group as Flags Match: ";
std::cerr << " Mask: " << opts.mFlagsMask << " FlagsFilter: " << opts.mFlagsFilter;
std::cerr << " GroupFlags: " << group.mGroupFlags << " GroupId: " << group.mGroupId;
std::cerr << std::endl;
flagsMatch = true;
}
else
{
std::cerr << "checkGroupFilter() Dropping Group due to !Flags Match ";
std::cerr << " Mask: " << opts.mFlagsMask << " FlagsFilter: " << opts.mFlagsFilter;
std::cerr << " GroupFlags: " << group.mGroupFlags << " GroupId: " << group.mGroupId;
std::cerr << std::endl;
}
}
else
{
// no status comparision,
flagsMatch = true;
}
bool subMatch = false;
if (opts.mSubscribeFilter)
{
@ -397,11 +424,11 @@ static bool checkGroupFilter(const RsTokReqOptions &opts, const RsGroupMetaData
subMatch = true;
}
return (statusMatch && subMatch);
return (statusMatch && flagsMatch && subMatch);
}
static bool checkMsgFilter(const RsTokReqOptions &opts, const RsMsgMetaData &msg)
static bool checkMsgFilter(const RsTokReqOptionsVEG &opts, const RsMsgMetaData &msg)
{
bool statusMatch = false;
if (opts.mStatusMask)
@ -429,11 +456,39 @@ static bool checkMsgFilter(const RsTokReqOptions &opts, const RsMsgMetaData &msg
// no status comparision,
statusMatch = true;
}
return statusMatch;
bool flagsMatch = false;
if (opts.mFlagsMask)
{
// Exact Flags match required.
if ((opts.mFlagsMask & opts.mFlagsFilter) == (opts.mFlagsMask & msg.mMsgFlags))
{
std::cerr << "checkMsgFilter() Accepting Msg as Flags Match: ";
std::cerr << " Mask: " << opts.mFlagsMask << " FlagsFilter: " << opts.mFlagsFilter;
std::cerr << " MsgFlags: " << msg.mMsgFlags << " MsgId: " << msg.mMsgId;
std::cerr << std::endl;
flagsMatch = true;
}
else
{
std::cerr << "checkMsgFilter() Dropping Msg due to !Flags Match ";
std::cerr << " Mask: " << opts.mFlagsMask << " FlagsFilter: " << opts.mFlagsFilter;
std::cerr << " MsgFlags: " << msg.mMsgFlags << " MsgId: " << msg.mMsgId;
std::cerr << std::endl;
}
}
else
{
// no status comparision,
flagsMatch = true;
}
return (statusMatch && flagsMatch);
}
bool GxsDataProxy::filterGroupList(const RsTokReqOptions &opts, std::list<std::string> &groupIds)
bool GxsDataProxyVEG::filterGroupList(const RsTokReqOptionsVEG &opts, std::list<std::string> &groupIds)
{
std::list<std::string>::iterator it;
for(it = groupIds.begin(); it != groupIds.end(); )
@ -462,7 +517,7 @@ bool GxsDataProxy::filterGroupList(const RsTokReqOptions &opts, std::list<std::s
}
bool GxsDataProxy::filterMsgList(const RsTokReqOptions &opts, std::list<std::string> &msgIds)
bool GxsDataProxyVEG::filterMsgList(const RsTokReqOptionsVEG &opts, std::list<std::string> &msgIds)
{
std::list<std::string>::iterator it;
for(it = msgIds.begin(); it != msgIds.end(); )
@ -492,14 +547,14 @@ bool GxsDataProxy::filterMsgList(const RsTokReqOptions &opts, std::list<std::str
bool GxsDataProxy::getGroupList( uint32_t &token, const RsTokReqOptions &opts, const std::list<std::string> &groupIds, std::list<std::string> &outGroupIds)
bool GxsDataProxyVEG::getGroupList( uint32_t &token, const RsTokReqOptionsVEG &opts, const std::list<std::string> &groupIds, std::list<std::string> &outGroupIds)
{
/* CASEs that this handles ...
* 1) if groupIds is Empty... return all groupIds.
* 2) else copy list.
*
*/
std::cerr << "GxsDataProxy::getGroupList()";
std::cerr << "GxsDataProxyVEG::getGroupList()";
std::cerr << std::endl;
if (groupIds.size() == 0)
@ -524,14 +579,14 @@ bool GxsDataProxy::getGroupList( uint32_t &token, const RsTokReqOptions &opt
}
bool GxsDataProxy::getMsgList( uint32_t &token, const RsTokReqOptions &opts, const std::list<std::string> &groupIds, std::list<std::string> &outMsgIds)
bool GxsDataProxyVEG::getMsgList( uint32_t &token, const RsTokReqOptionsVEG &opts, const std::list<std::string> &groupIds, std::list<std::string> &outMsgIds)
{
/* CASEs this handles.
* Input is groupList + Flags.
* 1) No Flags => All Messages in those Groups.
*
*/
std::cerr << "GxsDataProxy::getMsgList()";
std::cerr << "GxsDataProxyVEG::getMsgList()";
std::cerr << std::endl;
@ -542,20 +597,20 @@ bool GxsDataProxy::getMsgList( uint32_t &token, const RsTokReqOptions &opt
// Can only choose one of these two.
if (opts.mOptions & RS_TOKREQOPT_MSG_ORIGMSG)
{
std::cerr << "GxsDataProxy::getMsgList() MSG_ORIGMSG";
std::cerr << "GxsDataProxyVEG::getMsgList() MSG_ORIGMSG";
std::cerr << std::endl;
onlyOrigMsgs = true;
}
else if (opts.mOptions & RS_TOKREQOPT_MSG_LATEST)
{
std::cerr << "GxsDataProxy::getMsgList() MSG_LATEST";
std::cerr << "GxsDataProxyVEG::getMsgList() MSG_LATEST";
std::cerr << std::endl;
onlyLatestMsgs = true;
}
if (opts.mOptions & RS_TOKREQOPT_MSG_THREAD)
{
std::cerr << "GxsDataProxy::getMsgList() MSG_THREAD";
std::cerr << "GxsDataProxyVEG::getMsgList() MSG_THREAD";
std::cerr << std::endl;
onlyThreadHeadMsgs = true;
}
@ -593,7 +648,7 @@ bool GxsDataProxy::getMsgList( uint32_t &token, const RsTokReqOptions &opt
bool addMsg = false;
if (oit == origMsgTs.end())
{
std::cerr << "GxsDataProxy::getMsgList() Found New OrigMsgId: ";
std::cerr << "GxsDataProxyVEG::getMsgList() Found New OrigMsgId: ";
std::cerr << mit->second.mOrigMsgId;
std::cerr << " MsgId: " << mit->second.mMsgId;
std::cerr << " TS: " << mit->second.mPublishTs;
@ -604,7 +659,7 @@ bool GxsDataProxy::getMsgList( uint32_t &token, const RsTokReqOptions &opt
// check timestamps.
else if (oit->second.second < mit->second.mPublishTs)
{
std::cerr << "GxsDataProxy::getMsgList() Found Later Msg. OrigMsgId: ";
std::cerr << "GxsDataProxyVEG::getMsgList() Found Later Msg. OrigMsgId: ";
std::cerr << mit->second.mOrigMsgId;
std::cerr << " MsgId: " << mit->second.mMsgId;
std::cerr << " TS: " << mit->second.mPublishTs;
@ -673,7 +728,7 @@ bool GxsDataProxy::getMsgList( uint32_t &token, const RsTokReqOptions &opt
}
bool GxsDataProxy::getMsgRelatedList(uint32_t &token, const RsTokReqOptions &opts, const std::list<std::string> &msgIds, std::list<std::string> &outMsgIds)
bool GxsDataProxyVEG::getMsgRelatedList(uint32_t &token, const RsTokReqOptionsVEG &opts, const std::list<std::string> &msgIds, std::list<std::string> &outMsgIds)
{
/* CASEs this handles.
* Input is msgList + Flags.
@ -681,36 +736,52 @@ bool GxsDataProxy::getMsgRelatedList(uint32_t &token, const RsTokReqOptions &opt
*
*/
std::cerr << "GxsDataProxy::getMsgRelatedList()";
std::cerr << "GxsDataProxyVEG::getMsgRelatedList()";
std::cerr << std::endl;
bool onlyLatestMsgs = false;
bool onlyAllVersions = false;
bool onlyChildMsgs = false;
bool onlyThreadMsgs = false;
if (opts.mOptions & RS_TOKREQOPT_MSG_LATEST)
{
std::cerr << "GxsDataProxy::getMsgRelatedList() MSG_LATEST";
std::cerr << "GxsDataProxyVEG::getMsgRelatedList() MSG_LATEST";
std::cerr << std::endl;
onlyLatestMsgs = true;
}
else if (opts.mOptions & RS_TOKREQOPT_MSG_VERSIONS)
{
std::cerr << "GxsDataProxy::getMsgRelatedList() MSG_VERSIONS";
std::cerr << "GxsDataProxyVEG::getMsgRelatedList() MSG_VERSIONS";
std::cerr << std::endl;
onlyAllVersions = true;
}
if (opts.mOptions & RS_TOKREQOPT_MSG_PARENT)
{
std::cerr << "GxsDataProxy::getMsgRelatedList() MSG_PARENTS";
std::cerr << "GxsDataProxyVEG::getMsgRelatedList() MSG_PARENTS";
std::cerr << std::endl;
onlyChildMsgs = true;
}
if (opts.mOptions & RS_TOKREQOPT_MSG_THREAD)
{
std::cerr << "GxsDataProxyVEG::getMsgRelatedList() MSG_THREAD";
std::cerr << std::endl;
onlyThreadMsgs = true;
}
if (onlyAllVersions && onlyChildMsgs)
{
std::cerr << "GxsDataProxy::getMsgRelatedList() ERROR Incompatible FLAGS (VERSIONS & PARENT)";
std::cerr << "GxsDataProxyVEG::getMsgRelatedList() ERROR Incompatible FLAGS (VERSIONS & PARENT)";
std::cerr << std::endl;
return false;
}
if (onlyAllVersions && onlyThreadMsgs)
{
std::cerr << "GxsDataProxyVEG::getMsgRelatedList() ERROR Incompatible FLAGS (VERSIONS & THREAD)";
std::cerr << std::endl;
return false;
@ -718,7 +789,23 @@ bool GxsDataProxy::getMsgRelatedList(uint32_t &token, const RsTokReqOptions &opt
if ((!onlyLatestMsgs) && onlyChildMsgs)
{
std::cerr << "GxsDataProxy::getMsgRelatedList() ERROR Incompatible FLAGS (!LATEST & PARENT)";
std::cerr << "GxsDataProxyVEG::getMsgRelatedList() ERROR Incompatible FLAGS (!LATEST & PARENT)";
std::cerr << std::endl;
return false;
}
if ((!onlyLatestMsgs) && onlyThreadMsgs)
{
std::cerr << "GxsDataProxyVEG::getMsgRelatedList() ERROR Incompatible FLAGS (!LATEST & THREAD)";
std::cerr << std::endl;
return false;
}
if (onlyChildMsgs && onlyThreadMsgs)
{
std::cerr << "GxsDataProxyVEG::getMsgRelatedList() ERROR Incompatible FLAGS (PARENT & THREAD)";
std::cerr << std::endl;
return false;
@ -726,9 +813,9 @@ bool GxsDataProxy::getMsgRelatedList(uint32_t &token, const RsTokReqOptions &opt
/* FALL BACK OPTION */
if ((!onlyLatestMsgs) && (!onlyAllVersions) && (!onlyChildMsgs))
if ((!onlyLatestMsgs) && (!onlyAllVersions) && (!onlyChildMsgs) && (!onlyThreadMsgs))
{
std::cerr << "GxsDataProxy::getMsgRelatedList() FALLBACK -> NO FLAGS -> JUST COPY";
std::cerr << "GxsDataProxyVEG::getMsgRelatedList() FALLBACK -> NO FLAGS -> JUST COPY";
std::cerr << std::endl;
/* just copy */
outMsgIds = msgIds;
@ -755,7 +842,7 @@ bool GxsDataProxy::getMsgRelatedList(uint32_t &token, const RsTokReqOptions &opt
if (onlyLatestMsgs)
{
if (onlyChildMsgs)
if (onlyChildMsgs || onlyThreadMsgs)
{
// RUN THROUGH ALL MSGS... in map origId -> TS.
std::map<std::string, std::pair<std::string, time_t> > origMsgTs;
@ -763,16 +850,27 @@ bool GxsDataProxy::getMsgRelatedList(uint32_t &token, const RsTokReqOptions &opt
for(mit = mMsgMetaData.begin(); mit != mMsgMetaData.end(); mit++)
{
// skip msgs that aren't children.
if (mit->second.mParentId != origMsgId)
if (onlyChildMsgs)
{
continue;
if (mit->second.mParentId != origMsgId)
{
continue;
}
}
else /* onlyThreadMsgs */
{
if (mit->second.mThreadId != (*it))
{
continue;
}
}
oit = origMsgTs.find(mit->second.mOrigMsgId);
bool addMsg = false;
if (oit == origMsgTs.end())
{
std::cerr << "GxsDataProxy::getMsgList() Found New OrigMsgId: ";
std::cerr << "GxsDataProxyVEG::getMsgRelatedList() Found New OrigMsgId: ";
std::cerr << mit->second.mOrigMsgId;
std::cerr << " MsgId: " << mit->second.mMsgId;
std::cerr << " TS: " << mit->second.mPublishTs;
@ -783,7 +881,7 @@ bool GxsDataProxy::getMsgRelatedList(uint32_t &token, const RsTokReqOptions &opt
// check timestamps.
else if (oit->second.second < mit->second.mPublishTs)
{
std::cerr << "GxsDataProxy::getMsgList() Found Later Msg. OrigMsgId: ";
std::cerr << "GxsDataProxyVEG::getMsgRelatedList() Found Later Msg. OrigMsgId: ";
std::cerr << mit->second.mOrigMsgId;
std::cerr << " MsgId: " << mit->second.mMsgId;
std::cerr << " TS: " << mit->second.mPublishTs;
@ -843,14 +941,14 @@ bool GxsDataProxy::getMsgRelatedList(uint32_t &token, const RsTokReqOptions &opt
}
bool GxsDataProxy::createGroup(void *groupData)
bool GxsDataProxyVEG::createGroup(void *groupData)
{
RsGroupMetaData meta;
if (convertGroupToMetaData(groupData, meta))
{
if (!isUniqueGroup(meta.mGroupId))
{
std::cerr << "GxsDataProxy::createGroup() ERROR GroupId Clashes, discarding";
std::cerr << "GxsDataProxyVEG::createGroup() ERROR GroupId Clashes, discarding";
std::cerr << std::endl;
return false;
}
@ -869,20 +967,20 @@ bool GxsDataProxy::createGroup(void *groupData)
return true;
}
std::cerr << "GxsDataProxy::createGroup() ERROR Failed to convert Data";
std::cerr << "GxsDataProxyVEG::createGroup() ERROR Failed to convert Data";
std::cerr << std::endl;
return false;
}
bool GxsDataProxy::createMsg(void *msgData)
bool GxsDataProxyVEG::createMsg(void *msgData)
{
RsMsgMetaData meta;
if (convertMsgToMetaData(msgData, meta))
{
if (!isUniqueMsg(meta.mMsgId))
{
std::cerr << "GxsDataProxy::createMsg() ERROR MsgId Clashes, discarding";
std::cerr << "GxsDataProxyVEG::createMsg() ERROR MsgId Clashes, discarding";
std::cerr << std::endl;
return false;
}
@ -895,7 +993,7 @@ bool GxsDataProxy::createMsg(void *msgData)
git = mGroupMetaData.find(meta.mGroupId);
if (git == mGroupMetaData.end())
{
std::cerr << "GxsDataProxy::createMsg() ERROR GroupId Doesn't exist, discarding";
std::cerr << "GxsDataProxyVEG::createMsg() ERROR GroupId Doesn't exist, discarding";
std::cerr << std::endl;
return false;
}
@ -915,14 +1013,14 @@ bool GxsDataProxy::createMsg(void *msgData)
return true;
}
std::cerr << "GxsDataProxy::createMsg() ERROR Failed to convert Data";
std::cerr << "GxsDataProxyVEG::createMsg() ERROR Failed to convert Data";
std::cerr << std::endl;
return false;
}
// Get Message Status - is retrived via MessageSummary.
bool GxsDataProxy::setMessageStatus(const std::string &msgId,const uint32_t status, const uint32_t statusMask)
bool GxsDataProxyVEG::setMessageStatus(const std::string &msgId,const uint32_t status, const uint32_t statusMask)
{
RsStackMutex stack(mDataMtx); /***** LOCKED *****/
@ -932,7 +1030,7 @@ bool GxsDataProxy::setMessageStatus(const std::string &msgId,const uint32_t stat
if (mit == mMsgMetaData.end())
{
// error.
std::cerr << "GxsDataProxy::getMsgSummary() Error Finding MsgId: " << msgId;
std::cerr << "GxsDataProxyVEG::getMsgSummary() Error Finding MsgId: " << msgId;
std::cerr << std::endl;
}
else
@ -946,7 +1044,7 @@ bool GxsDataProxy::setMessageStatus(const std::string &msgId,const uint32_t stat
return true;
}
bool GxsDataProxy::setGroupStatus(const std::string &groupId, const uint32_t status, const uint32_t statusMask)
bool GxsDataProxyVEG::setGroupStatus(const std::string &groupId, const uint32_t status, const uint32_t statusMask)
{
RsStackMutex stack(mDataMtx); /***** LOCKED *****/
@ -956,7 +1054,7 @@ bool GxsDataProxy::setGroupStatus(const std::string &groupId, const uint32_t sta
if (git == mGroupMetaData.end())
{
// error.
std::cerr << "GxsDataProxy::setGroupStatus() Error Finding GroupId: " << groupId;
std::cerr << "GxsDataProxyVEG::setGroupStatus() Error Finding GroupId: " << groupId;
std::cerr << std::endl;
}
else
@ -971,7 +1069,7 @@ bool GxsDataProxy::setGroupStatus(const std::string &groupId, const uint32_t sta
}
bool GxsDataProxy::setGroupSubscribeFlags(const std::string &groupId, uint32_t subscribeFlags, uint32_t subscribeMask)
bool GxsDataProxyVEG::setGroupSubscribeFlags(const std::string &groupId, uint32_t subscribeFlags, uint32_t subscribeMask)
{
RsStackMutex stack(mDataMtx); /***** LOCKED *****/
@ -981,7 +1079,7 @@ bool GxsDataProxy::setGroupSubscribeFlags(const std::string &groupId, uint32_t s
if (git == mGroupMetaData.end())
{
// error.
std::cerr << "GxsDataProxy::setGroupSubscribeFlags() Error Finding GroupId: " << groupId;
std::cerr << "GxsDataProxyVEG::setGroupSubscribeFlags() Error Finding GroupId: " << groupId;
std::cerr << std::endl;
}
else
@ -995,7 +1093,7 @@ bool GxsDataProxy::setGroupSubscribeFlags(const std::string &groupId, uint32_t s
return true;
}
bool GxsDataProxy::setMessageServiceString(const std::string &msgId, const std::string &str)
bool GxsDataProxyVEG::setMessageServiceString(const std::string &msgId, const std::string &str)
{
RsStackMutex stack(mDataMtx); /***** LOCKED *****/
@ -1005,7 +1103,7 @@ bool GxsDataProxy::setMessageServiceString(const std::string &msgId, const std::
if (mit == mMsgMetaData.end())
{
// error.
std::cerr << "GxsDataProxy::setMessageServiceString() Error Finding MsgId: " << msgId;
std::cerr << "GxsDataProxyVEG::setMessageServiceString() Error Finding MsgId: " << msgId;
std::cerr << std::endl;
}
else
@ -1017,7 +1115,7 @@ bool GxsDataProxy::setMessageServiceString(const std::string &msgId, const std::
return true;
}
bool GxsDataProxy::setGroupServiceString(const std::string &groupId, const std::string &str)
bool GxsDataProxyVEG::setGroupServiceString(const std::string &groupId, const std::string &str)
{
RsStackMutex stack(mDataMtx); /***** LOCKED *****/
@ -1027,7 +1125,7 @@ bool GxsDataProxy::setGroupServiceString(const std::string &groupId, const std::
if (git == mGroupMetaData.end())
{
// error.
std::cerr << "GxsDataProxy::setGroupServiceString() Error Finding GroupId: " << groupId;
std::cerr << "GxsDataProxyVEG::setGroupServiceString() Error Finding GroupId: " << groupId;
std::cerr << std::endl;
}
else
@ -1041,22 +1139,22 @@ bool GxsDataProxy::setGroupServiceString(const std::string &groupId, const std::
/* These Functions must be overloaded to complete the service */
bool GxsDataProxy::convertGroupToMetaData(void *groupData, RsGroupMetaData &meta)
bool GxsDataProxyVEG::convertGroupToMetaData(void *groupData, RsGroupMetaData &meta)
{
std::cerr << "GxsDataProxy::convert fn ... please implement!";
std::cerr << "GxsDataProxyVEG::convert fn ... please implement!";
std::cerr << std::endl;
return false;
}
bool GxsDataProxy::convertMsgToMetaData(void *groupData, RsMsgMetaData &meta)
bool GxsDataProxyVEG::convertMsgToMetaData(void *groupData, RsMsgMetaData &meta)
{
std::cerr << "GxsDataProxy::convert fn ... please implement!";
std::cerr << "GxsDataProxyVEG::convert fn ... please implement!";
std::cerr << std::endl;
return false;
}
/* extract Data */
bool GxsDataProxy::getGroupSummary(const std::string &groupId, RsGroupMetaData &groupSummary)
bool GxsDataProxyVEG::getGroupSummary(const std::string &groupId, RsGroupMetaData &groupSummary)
{
RsStackMutex stack(mDataMtx); /***** LOCKED *****/
@ -1066,7 +1164,7 @@ bool GxsDataProxy::getGroupSummary(const std::string &groupId, RsGroupMetaData &
if (mit == mGroupMetaData.end())
{
// error.
std::cerr << "GxsDataProxy::getGroupMetaData() Error Finding GroupId: " << groupId;
std::cerr << "GxsDataProxyVEG::getGroupMetaData() Error Finding GroupId: " << groupId;
std::cerr << std::endl;
return false;
}
@ -1078,7 +1176,7 @@ bool GxsDataProxy::getGroupSummary(const std::string &groupId, RsGroupMetaData &
}
bool GxsDataProxy::getMsgSummary(const std::string &msgId, RsMsgMetaData &msgSummary)
bool GxsDataProxyVEG::getMsgSummary(const std::string &msgId, RsMsgMetaData &msgSummary)
{
RsStackMutex stack(mDataMtx); /***** LOCKED *****/
@ -1088,7 +1186,7 @@ bool GxsDataProxy::getMsgSummary(const std::string &msgId, RsMsgMetaData &msgSum
if (mit == mMsgMetaData.end())
{
// error.
std::cerr << "GxsDataProxy::getMsgSummary() Error Finding MsgId: " << msgId;
std::cerr << "GxsDataProxyVEG::getMsgSummary() Error Finding MsgId: " << msgId;
std::cerr << std::endl;
}
else
@ -1100,7 +1198,7 @@ bool GxsDataProxy::getMsgSummary(const std::string &msgId, RsMsgMetaData &msgSum
/* extract Data */
bool GxsDataProxy::getGroupSummary(const std::list<std::string> &groupIds, std::list<RsGroupMetaData> &groupSummary)
bool GxsDataProxyVEG::getGroupSummary(const std::list<std::string> &groupIds, std::list<RsGroupMetaData> &groupSummary)
{
std::list<std::string>::const_iterator it;
for(it = groupIds.begin(); it != groupIds.end(); it++)
@ -1113,7 +1211,7 @@ bool GxsDataProxy::getGroupSummary(const std::list<std::string> &groupIds, std::
if (mit == mGroupMetaData.end())
{
// error.
std::cerr << "GxsDataProxy::getGroupMetaData() Error Finding GroupId: " << *it;
std::cerr << "GxsDataProxyVEG::getGroupMetaData() Error Finding GroupId: " << *it;
std::cerr << std::endl;
}
else
@ -1125,7 +1223,7 @@ bool GxsDataProxy::getGroupSummary(const std::list<std::string> &groupIds, std::
}
bool GxsDataProxy::getMsgSummary(const std::list<std::string> &msgIds, std::list<RsMsgMetaData> &msgSummary)
bool GxsDataProxyVEG::getMsgSummary(const std::list<std::string> &msgIds, std::list<RsMsgMetaData> &msgSummary)
{
std::list<std::string>::const_iterator it;
for(it = msgIds.begin(); it != msgIds.end(); it++)
@ -1138,7 +1236,7 @@ bool GxsDataProxy::getMsgSummary(const std::list<std::string> &msgIds, std::list
if (mit == mMsgMetaData.end())
{
// error.
std::cerr << "GxsDataProxy::getMsgSummary() Error Finding MsgId: " << *it;
std::cerr << "GxsDataProxyVEG::getMsgSummary() Error Finding MsgId: " << *it;
std::cerr << std::endl;
}
else
@ -1150,7 +1248,7 @@ bool GxsDataProxy::getMsgSummary(const std::list<std::string> &msgIds, std::list
}
bool GxsDataProxy::getGroupData(const std::string &groupId, void * &groupData)
bool GxsDataProxyVEG::getGroupData(const std::string &groupId, void * &groupData)
{
RsStackMutex stack(mDataMtx); /***** LOCKED *****/
@ -1160,7 +1258,7 @@ bool GxsDataProxy::getGroupData(const std::string &groupId, void * &groupData)
if (mit == mGroupData.end())
{
// error.
std::cerr << "GxsDataProxy::getGroupData() Error Finding GroupId: " << groupId;
std::cerr << "GxsDataProxyVEG::getGroupData() Error Finding GroupId: " << groupId;
std::cerr << std::endl;
return false;
}
@ -1171,7 +1269,7 @@ bool GxsDataProxy::getGroupData(const std::string &groupId, void * &groupData)
return true;
}
bool GxsDataProxy::getMsgData(const std::string &msgId, void * &msgData)
bool GxsDataProxyVEG::getMsgData(const std::string &msgId, void * &msgData)
{
RsStackMutex stack(mDataMtx); /***** LOCKED *****/
@ -1181,7 +1279,7 @@ bool GxsDataProxy::getMsgData(const std::string &msgId, void * &msgData)
if (mit == mMsgData.end())
{
// error.
std::cerr << "GxsDataProxy::getMsgData() Error Finding MsgId: " << msgId;
std::cerr << "GxsDataProxyVEG::getMsgData() Error Finding MsgId: " << msgId;
std::cerr << std::endl;
return false;
}
@ -1193,7 +1291,7 @@ bool GxsDataProxy::getMsgData(const std::string &msgId, void * &msgData)
}
#if 0
bool GxsDataProxy::getGroupData(const std::list<std::string> &groupIds, std::list<void *> &groupData)
bool GxsDataProxyVEG::getGroupData(const std::list<std::string> &groupIds, std::list<void *> &groupData)
{
std::list<std::string>::const_iterator it;
for(it = groupIds.begin(); it != groupIds.end(); it++)
@ -1206,7 +1304,7 @@ bool GxsDataProxy::getGroupData(const std::list<std::string> &groupIds, std::lis
if (mit == mGroupData.end())
{
// error.
std::cerr << "GxsDataProxy::getGroupData() Error Finding GroupId: " << *it;
std::cerr << "GxsDataProxyVEG::getGroupData() Error Finding GroupId: " << *it;
std::cerr << std::endl;
}
else
@ -1217,7 +1315,7 @@ bool GxsDataProxy::getGroupData(const std::list<std::string> &groupIds, std::lis
return true;
}
bool GxsDataProxy::getMsgData(const std::list<std::string> &msgIds, std::list<void *> &msgData)
bool GxsDataProxyVEG::getMsgData(const std::list<std::string> &msgIds, std::list<void *> &msgData)
{
std::list<std::string>::const_iterator it;
for(it = msgIds.begin(); it != msgIds.end(); it++)
@ -1230,7 +1328,7 @@ bool GxsDataProxy::getMsgData(const std::list<std::string> &msgIds, std::list<vo
if (mit == mMsgData.end())
{
// error.
std::cerr << "GxsDataProxy::getMsgData() Error Finding MsgId: " << *it;
std::cerr << "GxsDataProxyVEG::getMsgData() Error Finding MsgId: " << *it;
std::cerr << std::endl;
}
else
@ -1242,7 +1340,7 @@ bool GxsDataProxy::getMsgData(const std::list<std::string> &msgIds, std::list<vo
}
#endif
bool GxsDataProxy::isUniqueMsg(const std::string &msgId)
bool GxsDataProxyVEG::isUniqueMsg(const std::string &msgId)
{
RsStackMutex stack(mDataMtx); /***** LOCKED *****/
@ -1253,7 +1351,7 @@ bool GxsDataProxy::isUniqueMsg(const std::string &msgId)
}
bool GxsDataProxy::isUniqueGroup(const std::string &groupId)
bool GxsDataProxyVEG::isUniqueGroup(const std::string &groupId)
{
RsStackMutex stack(mDataMtx); /***** LOCKED *****/
@ -1272,8 +1370,8 @@ bool GxsDataProxy::isUniqueGroup(const std::string &groupId)
/*********************************************************************************************************/
p3GxsDataService::p3GxsDataService(uint16_t type, GxsDataProxy *proxy)
:p3GxsService(type), mProxy(proxy)
p3GxsDataServiceVEG::p3GxsDataServiceVEG(uint16_t type, GxsDataProxyVEG *proxy)
:p3GxsServiceVEG(type), mProxy(proxy)
{
return;
}
@ -1282,7 +1380,7 @@ p3GxsDataService::p3GxsDataService(uint16_t type, GxsDataProxy *proxy)
bool p3GxsDataService::fakeprocessrequests()
bool p3GxsDataServiceVEG::fakeprocessrequests()
{
std::list<uint32_t> toClear;
std::list<uint32_t>::iterator cit;
@ -1294,11 +1392,11 @@ bool p3GxsDataService::fakeprocessrequests()
for(it = mRequests.begin(); it != mRequests.end(); it++)
{
//std::cerr << "p3GxsDataService::fakeprocessrequests() Token: " << it->second.token << " Status: " << it->second.status << " ReqType: " << it->second.reqType << " Age: " << now - it->second.reqTime << std::endl;
//std::cerr << "p3GxsDataServiceVEG::fakeprocessrequests() Token: " << it->second.token << " Status: " << it->second.status << " ReqType: " << it->second.reqType << " Age: " << now - it->second.reqTime << std::endl;
if (it->second.status == GXS_REQUEST_STATUS_PENDING)
{
std::cerr << "p3GxsDataService::fakeprocessrequests() Processing Token: " << it->second.token << " Status: " << it->second.status << " ReqType: " << it->second.reqType << " Age: " << now - it->second.reqTime << std::endl;
std::cerr << "p3GxsDataServiceVEG::fakeprocessrequests() Processing Token: " << it->second.token << " Status: " << it->second.status << " ReqType: " << it->second.reqType << " Age: " << now - it->second.reqTime << std::endl;
it->second.status = GXS_REQUEST_STATUS_PARTIAL;
/* PROCESS REQUEST! */
switch(it->second.reqType)
@ -1323,13 +1421,13 @@ bool p3GxsDataService::fakeprocessrequests()
}
else if (it->second.status == GXS_REQUEST_STATUS_DONE)
{
std::cerr << "p3GxsDataService::fakeprocessrequests() Clearing Done Request Token: " << it->second.token;
std::cerr << "p3GxsDataServiceVEG::fakeprocessrequests() Clearing Done Request Token: " << it->second.token;
std::cerr << std::endl;
toClear.push_back(it->second.token);
}
else if (now - it->second.reqTime > MAX_REQUEST_AGE)
{
std::cerr << "p3GxsDataService::fakeprocessrequests() Clearing Old Request Token: " << it->second.token;
std::cerr << "p3GxsDataServiceVEG::fakeprocessrequests() Clearing Old Request Token: " << it->second.token;
std::cerr << std::endl;
toClear.push_back(it->second.token);
}
@ -1345,23 +1443,25 @@ bool p3GxsDataService::fakeprocessrequests()
return true;
}
#if 0 // DISABLED AND MOVED TO GXS CODE.
std::ostream &operator<<(std::ostream &out, const RsGroupMetaData &meta)
{
out << "[ GroupId: " << meta.mGroupId << " Name: " << meta.mGroupName << " ]";
return out;
}
//std::ostream &operator<<(std::ostream &out, const RsGroupMetaData &meta)
//{
// out << "[ GroupId: " << meta.mGroupId << " Name: " << meta.mGroupName << " ]";
// return out;
//}
std::ostream &operator<<(std::ostream &out, const RsMsgMetaData &meta)
{
out << "[ GroupId: " << meta.mGroupId << " MsgId: " << meta.mMsgId;
out << " Name: " << meta.mMsgName;
out << " OrigMsgId: " << meta.mOrigMsgId;
out << " ThreadId: " << meta.mThreadId;
out << " ParentId: " << meta.mParentId;
out << " AuthorId: " << meta.mAuthorId;
out << " Name: " << meta.mMsgName << " ]";
return out;
}
//std::ostream &operator<<(std::ostream &out, const RsMsgMetaData &meta)
//{
// out << "[ GroupId: " << meta.mGroupId << " MsgId: " << meta.mMsgId;
// out << " Name: " << meta.mMsgName;
// out << " OrigMsgId: " << meta.mOrigMsgId;
// out << " ThreadId: " << meta.mThreadId;
// out << " ParentId: " << meta.mParentId;
// out << " AuthorId: " << meta.mAuthorId;
// out << " Name: " << meta.mMsgName << " ]";
// return out;
//}
#endif

View file

@ -27,7 +27,7 @@
#define P3_GXS_SERVICE_HEADER
#include "services/p3service.h"
#include "retroshare/rsidentity.h"
#include "retroshare/rsidentityVEG.h"
/*
* This class provides useful generic support for GXS style services.
@ -54,7 +54,7 @@ class gxsRequest
uint32_t ansType;
uint32_t reqType;
RsTokReqOptions Options;
RsTokReqOptionsVEG Options;
uint32_t status;
@ -64,18 +64,18 @@ class gxsRequest
};
class p3GxsService: public p3Service
class p3GxsServiceVEG: public p3Service
{
protected:
p3GxsService(uint16_t type);
p3GxsServiceVEG(uint16_t type);
public:
//virtual ~p3Service() { p3Service::~p3Service(); return; }
bool generateToken(uint32_t &token);
bool storeRequest(const uint32_t &token, const uint32_t &ansType, const RsTokReqOptions &opts, const uint32_t &type, const std::list<std::string> &ids);
bool storeRequest(const uint32_t &token, const uint32_t &ansType, const RsTokReqOptionsVEG &opts, const uint32_t &type, const std::list<std::string> &ids);
bool clearRequest(const uint32_t &token);
bool updateRequestStatus(const uint32_t &token, const uint32_t &status);
@ -103,15 +103,15 @@ virtual bool fakeprocessrequests();
};
class GxsDataProxy
class GxsDataProxyVEG
{
public:
GxsDataProxy();
GxsDataProxyVEG();
virtual bool getGroupList( uint32_t &token, const RsTokReqOptions &opts, const std::list<std::string> &groupIds, std::list<std::string> &outGroupIds);
virtual bool getMsgList( uint32_t &token, const RsTokReqOptions &opts, const std::list<std::string> &groupIds, std::list<std::string> &outMsgIds);
virtual bool getMsgRelatedList(uint32_t &token, const RsTokReqOptions &opts, const std::list<std::string> &msgIds, std::list<std::string> &outMsgIds);
virtual bool getGroupList( uint32_t &token, const RsTokReqOptionsVEG &opts, const std::list<std::string> &groupIds, std::list<std::string> &outGroupIds);
virtual bool getMsgList( uint32_t &token, const RsTokReqOptionsVEG &opts, const std::list<std::string> &groupIds, std::list<std::string> &outMsgIds);
virtual bool getMsgRelatedList(uint32_t &token, const RsTokReqOptionsVEG &opts, const std::list<std::string> &msgIds, std::list<std::string> &outMsgIds);
/* This functions return a token - which can be used to retrieve the RsGroupMetaData, later
@ -157,8 +157,8 @@ virtual bool setGroupServiceString(const std::string &grpId, const std::string &
protected:
bool filterGroupList(const RsTokReqOptions &opts, std::list<std::string> &groupIds);
bool filterMsgList(const RsTokReqOptions &opts, std::list<std::string> &msgIds);
bool filterGroupList(const RsTokReqOptionsVEG &opts, std::list<std::string> &groupIds);
bool filterMsgList(const RsTokReqOptionsVEG &opts, std::list<std::string> &msgIds);
RsMutex mDataMtx;
@ -172,17 +172,17 @@ virtual bool setGroupServiceString(const std::string &grpId, const std::string &
};
class p3GxsDataService: public p3GxsService
class p3GxsDataServiceVEG: public p3GxsServiceVEG
{
public:
p3GxsDataService(uint16_t type, GxsDataProxy *proxy);
p3GxsDataServiceVEG(uint16_t type, GxsDataProxyVEG *proxy);
virtual bool fakeprocessrequests();
protected:
GxsDataProxy *mProxy;
GxsDataProxyVEG *mProxy;
};

File diff suppressed because it is too large Load diff

View file

@ -7,7 +7,7 @@
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2 as published by the Free Software Foundation.
* License Version 2.1 as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@ -26,41 +26,74 @@
#ifndef P3_IDENTITY_SERVICE_HEADER
#define P3_IDENTITY_SERVICE_HEADER
#include "services/p3service.h"
#include "services/p3gxsservice.h"
#include "retroshare/rsidentity.h"
#include "retroshare/rsidentity.h" // External Interfaces.
#include "gxs/rsgenexchange.h" // GXS service.
#include "gxs/rsgixs.h" // Internal Interfaces.
#include "gxs/gxstokenqueue.h"
#include <map>
#include <string>
#include "util/rsmemcache.h"
#include "util/rstickevent.h"
#include "pqi/authgpg.h"
/*
* Identity Service
*
*/
class IdDataProxy: public GxsDataProxy
// INTERNAL DATA TYPES.
// Describes data stored in GroupServiceString.
class SSBit
{
public:
bool getGroup(const std::string &id, RsIdGroup &group);
bool getMsg(const std::string &id, RsIdMsg &msg);
bool addGroup(const RsIdGroup &group);
bool addMsg(const RsIdMsg &msg);
/* These Functions must be overloaded to complete the service */
virtual bool convertGroupToMetaData(void *groupData, RsGroupMetaData &meta);
virtual bool convertMsgToMetaData(void *msgData, RsMsgMetaData &meta);
public:
virtual bool load(const std::string &input) = 0;
virtual std::string save() const = 0;
};
// INTERNAL DATA TYPES...
// Describes data stored in GroupServiceString.
class IdRepCumulScore
class SSGxsIdPgp: public SSBit
{
public:
SSGxsIdPgp()
:idKnown(false), lastCheckTs(0), checkAttempts(0) { return; }
virtual bool load(const std::string &input);
virtual std::string save() const;
bool idKnown;
time_t lastCheckTs;
uint32_t checkAttempts;
std::string pgpId;
};
class SSGxsIdScore: public SSBit
{
public:
SSGxsIdScore()
:score(0) { return; }
virtual bool load(const std::string &input);
virtual std::string save() const;
int score;
};
class SSGxsIdCumulator: public SSBit
{
public:
SSGxsIdCumulator()
:count(0), nullcount(0), sum(0), sumsq(0) { return; }
virtual bool load(const std::string &input);
virtual std::string save() const;
uint32_t count;
uint32_t nullcount;
double sum;
@ -69,80 +102,220 @@ public:
// derived parameters:
};
class IdGroupServiceStrData
class SSGxsIdGroup: public SSBit
{
public:
IdGroupServiceStrData() { pgpIdKnown = false; }
bool pgpIdKnown;
std::string pgpId;
uint32_t ownScore;
IdRepCumulScore opinion;
IdRepCumulScore reputation;
SSGxsIdGroup() { return; }
virtual bool load(const std::string &input);
virtual std::string save() const;
// pgphash status
SSGxsIdPgp pgp;
// reputation score.
SSGxsIdScore score;
SSGxsIdCumulator opinion;
SSGxsIdCumulator reputation;
};
#define ID_LOCAL_STATUS_FULL_CALC_FLAG 0x00010000
#define ID_LOCAL_STATUS_INC_CALC_FLAG 0x00020000
class p3IdService: public p3GxsDataService, public RsIdentity
#define MAX_CACHE_SIZE 100 // Small for testing..
//#define MAX_CACHE_SIZE 10000 // More useful size
class RsGxsIdGroupItem;
class RsGxsIdCache
{
public:
RsGxsIdCache();
RsGxsIdCache(const RsGxsIdGroupItem *item, const RsTlvSecurityKey &in_pkey);
p3IdService(uint16_t type);
void updateServiceString(std::string serviceString);
virtual int tick();
RsIdentityDetails details;
RsTlvSecurityKey pubkey;
};
#if 0
class LruData
{
public:
RsGxsId key;
};
#endif
// Not sure exactly what should be inherited here?
// Chris - please correct as necessary.
class p3IdService: public RsGxsIdExchange, public RsIdentity,
public GxsTokenQueue, public RsTickEvent
{
public:
p3IdService(RsGeneralDataService* gds, RsNetworkExchangeService* nes);
/* changed? */
virtual bool updated();
virtual void service_tick(); // needed for background processing.
/* From RsTokenService */
/* Data Requests */
virtual bool requestGroupInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list<std::string> &groupIds);
virtual bool requestMsgInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list<std::string> &groupIds);
virtual bool requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list<std::string> &msgIds);
/* Generic Lists */
virtual bool getGroupList( const uint32_t &token, std::list<std::string> &groupIds);
virtual bool getMsgList( const uint32_t &token, std::list<std::string> &msgIds);
/* General Interface is provided by RsIdentity / RsGxsIfaceImpl. */
/* Generic Summary */
virtual bool getGroupSummary( const uint32_t &token, std::list<RsGroupMetaData> &groupInfo);
virtual bool getMsgSummary( const uint32_t &token, std::list<RsMsgMetaData> &msgInfo);
/* Data Specific Interface */
/* Actual Data -> specific to Interface */
virtual bool getGroupData(const uint32_t &token, RsIdGroup &group);
virtual bool getMsgData(const uint32_t &token, RsIdMsg &msg);
// These are exposed via RsIdentity.
virtual bool getGroupData(const uint32_t &token, std::vector<RsGxsIdGroup> &groups);
/* Poll */
virtual uint32_t requestStatus(const uint32_t token);
// These are local - and not exposed via RsIdentity.
virtual bool getMsgData(const uint32_t &token, std::vector<RsGxsIdOpinion> &opinions);
virtual bool createGroup(uint32_t& token, RsGxsIdGroup &group);
virtual bool createMsg(uint32_t& token, RsGxsIdOpinion &opinion);
/* Cancel Request */
virtual bool cancelRequest(const uint32_t &token);
/**************** RsIdentity External Interface.
* Notes:
*
* All the data is cached together for the moment - We should probably
* seperate and sort this out.
*
* Also need to handle Cache updates / invalidation from internal changes.
*
*/
//////////////////////////////////////////////////////////////////////////////
virtual bool setMessageStatus(const std::string &msgId, const uint32_t status, const uint32_t statusMask);
virtual bool setGroupStatus(const std::string &groupId, const uint32_t status, const uint32_t statusMask);
virtual bool setGroupSubscribeFlags(const std::string &groupId, uint32_t subscribeFlags, uint32_t subscribeMask);
virtual bool setMessageServiceString(const std::string &msgId, const std::string &str);
virtual bool setGroupServiceString(const std::string &grpId, const std::string &str);
//virtual bool getNickname(const RsGxsId &id, std::string &nickname);
virtual bool getIdDetails(const RsGxsId &id, RsIdentityDetails &details);
virtual bool getOwnIds(std::list<RsGxsId> &ownIds);
virtual bool groupRestoreKeys(const std::string &groupId);
virtual bool groupShareKeys(const std::string &groupId, std::list<std::string>& peers);
virtual bool createGroup(uint32_t &token, RsIdGroup &group, bool isNew);
virtual bool createMsg(uint32_t &token, RsIdMsg &msg, bool isNew);
//
virtual bool submitOpinion(uint32_t& token, RsIdOpinion &opinion);
virtual bool createIdentity(uint32_t& token, RsIdentityParameters &params);
/**************** RsGixs Implementation
* Notes:
* Interface is only suggestion at the moment, will be changed as necessary.
* Results should be cached / preloaded for maximum speed.
*
*/
virtual bool haveKey(const RsGxsId &id);
virtual bool requestKey(const RsGxsId &id, const std::list<PeerId> &peers);
virtual int getKey(const RsGxsId &id, RsTlvSecurityKey &key);
virtual bool havePrivateKey(const RsGxsId &id);
virtual bool requestPrivateKey(const RsGxsId &id);
virtual int getPrivateKey(const RsGxsId &id, RsTlvSecurityKey &key);
/**************** RsGixsReputation Implementation
* Notes:
* Again should be cached if possible.
*/
// get Reputation.
virtual bool getReputation(const RsGxsId &id, const GixsReputation &rep);
protected:
/** Notifications **/
virtual void notifyChanges(std::vector<RsGxsNotify*>& changes);
/** Overloaded to add PgpIdHash to Group Definition **/
virtual void service_CreateGroup(RsGxsGrpItem* grpItem, RsTlvSecurityKeySet& keySet);
// Overloaded from GxsTokenQueue for Request callbacks.
virtual void handleResponse(uint32_t token, uint32_t req_type);
// Overloaded from RsTickEvent.
virtual void handle_event(uint32_t event_type, const std::string &elabel);
private:
virtual void generateDummyData();
/************************************************************************
* This is the Cache for minimising calls to the DataStore.
*
*/
int cache_tick();
std::string genRandomId();
bool cache_request_load(const RsGxsId &id);
bool cache_start_load();
bool cache_load_for_token(uint32_t token);
bool cache_store(const RsGxsIdGroupItem *item);
bool cache_update_if_cached(const RsGxsId &id, std::string serviceString);
// Mutex protected.
std::list<RsGxsId> mCacheLoad_ToCache;
// Switching to RsMemCache for Key Caching.
RsMemCache<RsGxsId, RsGxsIdCache> mPublicKeyCache;
RsMemCache<RsGxsId, RsGxsIdCache> mPrivateKeyCache;
/************************************************************************
* Refreshing own Ids.
*
*/
bool cache_request_ownids();
bool cache_load_ownids(uint32_t token);
std::list<RsGxsId> mOwnIds;
/************************************************************************
* Test fns for Caching.
*
*/
bool cachetest_tick();
bool cachetest_getlist();
bool cachetest_handlerequest(uint32_t token);
/************************************************************************
* for processing background tasks that use the serviceString.
* - must be mutually exclusive to avoid clashes.
*/
bool CacheArbitration(uint32_t mode);
void CacheArbitrationDone(uint32_t mode);
bool mBgSchedule_Active;
uint32_t mBgSchedule_Mode;
/************************************************************************
* pgphash processing.
*
*/
bool pgphash_start();
bool pgphash_handlerequest(uint32_t token);
bool pgphash_process();
bool checkId(const RsGxsIdGroup &grp, PGPIdType &pgp_id);
void getPgpIdList();
/* MUTEX PROTECTED DATA (mIdMtx - maybe should use a 2nd?) */
std::map<PGPIdType, PGPFingerprintType> mPgpFingerprintMap;
std::list<RsGxsIdGroup> mGroupsToProcess;
/************************************************************************
* Below is the background task for processing opinions => reputations
*
*/
virtual void generateDummyData();
void generateDummy_OwnIds();
void generateDummy_FriendPGP();
void generateDummy_UnknownPGP();
void generateDummy_UnknownPseudo();
std::string genRandomId(int len = 20);
bool reputation_start();
bool reputation_continue();
int background_tick();
bool background_checkTokenRequest();
@ -154,11 +327,6 @@ std::string genRandomId();
bool background_cleanup();
bool encodeIdGroupCache(std::string &str, const IdGroupServiceStrData &data);
bool extractIdGroupCache(std::string &str, IdGroupServiceStrData &data);
IdDataProxy *mIdProxy;
RsMutex mIdMtx;
/***** below here is locked *****/
@ -170,17 +338,17 @@ std::string genRandomId();
std::map<std::string, RsGroupMetaData> mBgGroupMap;
std::list<std::string> mBgFullCalcGroups;
bool mUpdated;
#if 0
std::map<std::string, RsIdData> mIds;
std::map<std::string, std::map<std::string, RsIdOpinion> > mOpinions;
/************************************************************************
* Other Data that is protected by the Mutex.
*/
std::map<std::string, RsIdReputation> mReputations; // this is created locally.
#endif
std::vector<RsGxsGroupChange*> mGroupChange;
std::vector<RsGxsMsgChange*> mMsgChange;
};
#endif
#endif // P3_IDENTITY_SERVICE_HEADER

File diff suppressed because it is too large Load diff

View file

@ -1,9 +1,12 @@
#ifndef P3PHOTOSERVICEV2_H
#define P3PHOTOSERVICEV2_H
/*
* libretroshare/src/services: p3photoservice.h
* libretroshare/src/retroshare: rsphoto.h
*
* 3P/PQI network interface for RetroShare.
* RetroShare C++ Interface.
*
* Copyright 2012-2012 by Robert Fernie.
* Copyright 2008-2012 by Robert Fernie, Christopher Evi-Parker
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@ -23,116 +26,123 @@
*
*/
#ifndef P3_PHOTO_SERVICE_HEADER
#define P3_PHOTO_SERVICE_HEADER
#include "services/p3gxsservice.h"
#include "gxs/rsgenexchange.h"
#include "retroshare/rsphoto.h"
#include <map>
#include <string>
/*
* Photo Service
*
* This is an example service for the new cache system.
* For the moment, it will only hold data passed to it from the GUI.
* and spew that back when asked....
*
* We are doing it like this - so we can check the required interface functionality.
*
* Expect it won't take long before it'll be properly linked into the backend!
*
* This will be transformed into a Plugin Service, once the basics have been worked out.
*
*/
class PhotoDataProxy: public GxsDataProxy
class p3PhotoService : public RsPhoto, public RsGenExchange
{
public:
public:
bool addAlbum(const RsPhotoAlbum &album);
bool addPhoto(const RsPhotoPhoto &photo);
p3PhotoService(RsGeneralDataService* gds, RsNetworkExchangeService* nes, RsGixs* gixs,
uint32_t authenPolicy);
bool getAlbum(const std::string &id, RsPhotoAlbum &album);
bool getPhoto(const std::string &id, RsPhotoPhoto &photo);
public:
/* These Functions must be overloaded to complete the service */
virtual bool convertGroupToMetaData(void *groupData, RsGroupMetaData &meta);
virtual bool convertMsgToMetaData(void *groupData, RsMsgMetaData &meta);
/*!
* @return true if a change has occured
*/
bool updated();
/*!
*
*/
void service_tick();
protected:
void notifyChanges(std::vector<RsGxsNotify*>& changes);
public:
/** Requests **/
void groupsChanged(std::list<RsGxsGroupId>& grpIds);
void msgsChanged(std::map<RsGxsGroupId,
std::vector<RsGxsMessageId> >& msgs);
RsTokenService* getTokenService();
bool getGroupList(const uint32_t &token,
std::list<RsGxsGroupId> &groupIds);
bool getMsgList(const uint32_t &token,
GxsMsgIdResult& msgIds);
/* Generic Summary */
bool getGroupSummary(const uint32_t &token,
std::list<RsGroupMetaData> &groupInfo);
bool getMsgSummary(const uint32_t &token,
MsgMetaResult &msgInfo);
/* Specific Service Data */
bool getAlbum(const uint32_t &token, std::vector<RsPhotoAlbum> &albums);
bool getPhoto(const uint32_t &token, PhotoResult &photos);
bool getPhotoComment(const uint32_t &token, PhotoCommentResult &comments);
bool getPhotoRelatedComment(const uint32_t &token, PhotoRelatedCommentResult &comments);
public:
/** Modifications **/
/*!
* submits album, which returns a token that needs
* to be acknowledge to get album grp id
* @param token token to redeem for acknowledgement
* @param album album to be submitted
*/
bool submitAlbumDetails(uint32_t& token, RsPhotoAlbum &album);
/*!
* submits photo, which returns a token that needs
* to be acknowledge to get photo msg-grp id pair
* @param token token to redeem for acknowledgement
* @param photo photo to be submitted
*/
bool submitPhoto(uint32_t& token, RsPhotoPhoto &photo);
/*!
* submits photo comment, which returns a token that needs
* to be acknowledged to get photo msg-grp id pair
* The mParentId needs to be set to an existing msg for which
* commenting is enabled
* @param token token to redeem for acknowledgement
* @param comment comment to be submitted
*/
bool submitComment(uint32_t& token, RsPhotoComment &photo);
/*!
* subscribes to group, and returns token which can be used
* to be acknowledged to get group Id
* @param token token to redeem for acknowledgement
* @param grpId the id of the group to subscribe to
*/
bool subscribeToAlbum(uint32_t& token, const RsGxsGroupId& grpId, bool subscribe);
/*!
* This allows the client service to acknowledge that their msgs has
* been created/modified and retrieve the create/modified msg ids
* @param token the token related to modification/create request
* @param msgIds map of grpid->msgIds of message created/modified
* @return true if token exists false otherwise
*/
bool acknowledgeMsg(const uint32_t& token, std::pair<RsGxsGroupId, RsGxsMessageId>& msgId);
/*!
* This allows the client service to acknowledge that their grps has
* been created/modified and retrieve the create/modified grp ids
* @param token the token related to modification/create request
* @param msgIds vector of ids of groups created/modified
* @return true if token exists false otherwise
*/
bool acknowledgeGrp(const uint32_t& token, RsGxsGroupId& grpId);
private:
std::vector<RsGxsGroupChange*> mGroupChange;
std::vector<RsGxsMsgChange*> mMsgChange;
RsMutex mPhotoMutex;
};
class p3PhotoService: public p3GxsDataService, public RsPhoto
{
public:
p3PhotoService(uint16_t type);
virtual int tick();
public:
// NEW INTERFACE.
/************* Extern Interface *******/
/* changed? */
virtual bool updated();
/* Data Requests */
virtual bool requestGroupInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list<std::string> &groupIds);
virtual bool requestMsgInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list<std::string> &groupIds);
virtual bool requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list<std::string> &msgIds);
/* Generic Lists */
virtual bool getGroupList( const uint32_t &token, std::list<std::string> &groupIds);
virtual bool getMsgList( const uint32_t &token, std::list<std::string> &msgIds);
/* Generic Summary */
virtual bool getGroupSummary( const uint32_t &token, std::list<RsGroupMetaData> &groupInfo);
virtual bool getMsgSummary( const uint32_t &token, std::list<RsMsgMetaData> &msgInfo);
/* Actual Data -> specific to Interface */
/* Specific Service Data */
virtual bool getAlbum(const uint32_t &token, RsPhotoAlbum &album);
virtual bool getPhoto(const uint32_t &token, RsPhotoPhoto &photo);
/* Poll */
virtual uint32_t requestStatus(const uint32_t token);
/* Cancel Request */
virtual bool cancelRequest(const uint32_t &token);
//////////////////////////////////////////////////////////////////////////////
virtual bool setMessageStatus(const std::string &msgId, const uint32_t status, const uint32_t statusMask);
virtual bool setGroupStatus(const std::string &groupId, const uint32_t status, const uint32_t statusMask);
virtual bool setGroupSubscribeFlags(const std::string &groupId, uint32_t subscribeFlags, uint32_t subscribeMask);
virtual bool setMessageServiceString(const std::string &msgId, const std::string &str);
virtual bool setGroupServiceString(const std::string &grpId, const std::string &str);
virtual bool groupRestoreKeys(const std::string &groupId);
virtual bool groupShareKeys(const std::string &groupId, std::list<std::string>& peers);
/* details are updated in album - to choose Album ID, and storage path */
virtual bool submitAlbumDetails(uint32_t &token, RsPhotoAlbum &album, bool isNew);
virtual bool submitPhoto(uint32_t &token, RsPhotoPhoto &photo, bool isNew);
private:
std::string genRandomId();
PhotoDataProxy *mPhotoProxy;
RsMutex mPhotoMtx;
bool mUpdated;
};
#endif
#endif // P3PHOTOSERVICEV2_H

View file

@ -1,132 +0,0 @@
#include "p3photoserviceV2.h"
#include "serialiser/rsphotov2items.h"
p3PhotoServiceV2::p3PhotoServiceV2(RsGeneralDataService* gds, RsNetworkExchangeService* nes)
: RsGenExchange(gds, nes, new RsGxsPhotoSerialiser(), RS_SERVICE_TYPE_PHOTO)
{
}
bool p3PhotoServiceV2::updated()
{
return false;
}
void p3PhotoServiceV2::groupsChanged(std::list<std::string>& grpIds) {
}
void p3PhotoServiceV2::msgsChanged(
std::map<std::string, std::vector<std::string> >& msgs)
{
}
RsTokenServiceV2* p3PhotoServiceV2::getTokenService() {
return RsGenExchange::getTokenService();
}
bool p3PhotoServiceV2::getGroupList(const uint32_t& token,
std::list<std::string>& groupIds)
{
return RsGenExchange::getGroupList(token, groupIds);
}
bool p3PhotoServiceV2::getMsgList(const uint32_t& token,
GxsMsgIdResult& msgIds)
{
return RsGenExchange::getMsgList(token, msgIds);
}
bool p3PhotoServiceV2::getGroupSummary(const uint32_t& token,
std::list<RsGroupMetaData>& groupInfo)
{
return RsGenExchange::getGroupMeta(token, groupInfo);
}
bool p3PhotoServiceV2::getMsgSummary(const uint32_t& token,
MsgMetaResult& msgInfo)
{
return RsGenExchange::getMsgMeta(token, msgInfo);
}
bool p3PhotoServiceV2::getAlbum(const uint32_t& token, std::vector<RsPhotoAlbum>& albums)
{
std::vector<RsGxsGrpItem*> grpData;
bool ok = RsGenExchange::getGroupData(token, grpData);
if(ok)
{
std::vector<RsGxsGrpItem*>::iterator vit = grpData.begin();
for(; vit != grpData.end(); vit++)
{
RsGxsPhotoAlbumItem* item = dynamic_cast<RsGxsPhotoAlbumItem*>(*vit);
RsPhotoAlbum album = item->album;
delete item;
albums.push_back(album);
}
}
return ok;
}
bool p3PhotoServiceV2::getPhoto(const uint32_t& token, PhotoResult& photos)
{
GxsMsgDataMap msgData;
bool ok = RsGenExchange::getMsgData(token, msgData);
if(ok)
{
GxsMsgDataMap::iterator mit = msgData.begin();
for(; mit != msgData.end(); mit++)
{
RsGxsGroupId grpId = mit->first;
std::vector<RsGxsMsgItem*>& msgItems = mit->second;
std::vector<RsGxsMsgItem*>::iterator vit = msgItems.begin();
for(; vit != msgItems.end(); vit++)
{
RsGxsPhotoPhotoItem* item = dynamic_cast<RsGxsPhotoPhotoItem*>(*vit);
if(item)
{
RsPhotoPhoto photo = item->photo;
photos[grpId].push_back(photo);
delete item;
}else
{
delete *vit;
}
}
}
}
return ok;
}
bool p3PhotoServiceV2::submitAlbumDetails(RsPhotoAlbum& album)
{
return false;
}
bool p3PhotoServiceV2::submitPhoto(RsPhotoPhoto& photo)
{
return false;
}

View file

@ -1,82 +0,0 @@
#ifndef P3PHOTOSERVICEV2_H
#define P3PHOTOSERVICEV2_H
/*
* libretroshare/src/retroshare: rsphoto.h
*
* RetroShare C++ Interface.
*
* Copyright 2008-2012 by Robert Fernie, Christopher Evi-Parker
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2 as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
#include "gxs/rsgenexchange.h"
#include "retroshare/rsphotoV2.h"
class p3PhotoServiceV2 : public RsPhotoV2, public RsGenExchange
{
public:
p3PhotoServiceV2(RsGeneralDataService* gds, RsNetworkExchangeService* nes);
public:
/*!
* @return
*/
bool updated();
public:
/** Requests **/
void groupsChanged(std::list<std::string>& grpIds);
void msgsChanged(std::map<std::string,
std::vector<std::string> >& msgs);
RsTokenServiceV2* getTokenService();
bool getGroupList(const uint32_t &token,
std::list<std::string> &groupIds);
bool getMsgList(const uint32_t &token,
GxsMsgIdResult& msgIds);
/* Generic Summary */
bool getGroupSummary(const uint32_t &token,
std::list<RsGroupMetaData> &groupInfo);
bool getMsgSummary(const uint32_t &token,
MsgMetaResult &msgInfo);
/* Specific Service Data */
bool getAlbum(const uint32_t &token, std::vector<RsPhotoAlbum> &albums);
bool getPhoto(const uint32_t &token, PhotoResult &photos);
public:
/** Modifications **/
bool submitAlbumDetails(RsPhotoAlbum &album);
bool submitPhoto(RsPhotoPhoto &photo);
};
#endif // P3PHOTOSERVICEV2_H

File diff suppressed because it is too large Load diff

View file

@ -1,190 +1,175 @@
/*
* libretroshare/src/services: p3posted.h
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2012-2012 by Robert Fernie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2 as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
#ifndef P3_POSTED_SERVICE_HEADER
#define P3_POSTED_SERVICE_HEADER
#include "services/p3gxsservice.h"
#include "retroshare/rsposted.h"
#include <map>
#include <string>
/*
* Posted Service
*
*/
class PostedDataProxy: public GxsDataProxy
{
public:
bool addGroup(const RsPostedGroup &group);
bool addPost(const RsPostedPost &post);
bool addVote(const RsPostedVote &vote);
bool addComment(const RsPostedComment &comment);
bool getGroup(const std::string &id, RsPostedGroup &group);
bool getPost(const std::string &id, RsPostedPost &post);
bool getVote(const std::string &id, RsPostedVote &vote);
bool getComment(const std::string &id, RsPostedComment &comment);
/* These Functions must be overloaded to complete the service */
virtual bool convertGroupToMetaData(void *groupData, RsGroupMetaData &meta);
virtual bool convertMsgToMetaData(void *groupData, RsMsgMetaData &meta);
};
class p3PostedService: public p3GxsDataService, public RsPosted
{
public:
p3PostedService(uint16_t type);
virtual int tick();
public:
// NEW INTERFACE.
/************* Extern Interface *******/
virtual bool updated();
/* Data Requests */
virtual bool requestGroupInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list<std::string> &groupIds);
virtual bool requestMsgInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list<std::string> &groupIds);
virtual bool requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list<std::string> &msgIds);
/* Generic Lists */
virtual bool getGroupList( const uint32_t &token, std::list<std::string> &groupIds);
virtual bool getMsgList( const uint32_t &token, std::list<std::string> &msgIds);
/* Generic Summary */
virtual bool getGroupSummary( const uint32_t &token, std::list<RsGroupMetaData> &groupInfo);
virtual bool getMsgSummary( const uint32_t &token, std::list<RsMsgMetaData> &msgInfo);
/* Actual Data -> specific to Interface */
/* Specific Service Data */
virtual bool getGroup(const uint32_t &token, RsPostedGroup &group);
virtual bool getPost(const uint32_t &token, RsPostedPost &post);
virtual bool getComment(const uint32_t &token, RsPostedComment &comment);
/* Poll */
virtual uint32_t requestStatus(const uint32_t token);
/* Cancel Request */
virtual bool cancelRequest(const uint32_t &token);
//////////////////////////////////////////////////////////////////////////////
virtual bool setMessageStatus(const std::string &msgId, const uint32_t status, const uint32_t statusMask);
virtual bool setGroupStatus(const std::string &groupId, const uint32_t status, const uint32_t statusMask);
virtual bool setGroupSubscribeFlags(const std::string &groupId, uint32_t subscribeFlags, uint32_t subscribeMask);
virtual bool setMessageServiceString(const std::string &msgId, const std::string &str);
virtual bool setGroupServiceString(const std::string &grpId, const std::string &str);
virtual bool groupRestoreKeys(const std::string &groupId);
virtual bool groupShareKeys(const std::string &groupId, std::list<std::string>& peers);
virtual bool submitGroup(uint32_t &token, RsPostedGroup &group, bool isNew);
virtual bool submitPost(uint32_t &token, RsPostedPost &post, bool isNew);
virtual bool submitVote(uint32_t &token, RsPostedVote &vote, bool isNew);
virtual bool submitComment(uint32_t &token, RsPostedComment &comment, bool isNew);
// Extended Interface for Collated Data View.
virtual bool setViewMode(uint32_t mode);
virtual bool setViewPeriod(uint32_t period);
virtual bool setViewRange(uint32_t first, uint32_t count);
virtual bool requestRanking(uint32_t &token, std::string groupId);
virtual bool getRankedPost(const uint32_t &token, RsPostedPost &post);
// These are exposed for GUI usage.
virtual bool encodePostedCache(std::string &str, uint32_t votes, uint32_t comments);
virtual bool extractPostedCache(const std::string &str, uint32_t &votes, uint32_t &comments);
virtual float calcPostScore(const RsMsgMetaData &meta);
private:
//
bool checkRankingRequest();
bool processPosts();
// background processing of Votes.
// NB: These should probably be handled by a background thread.
// At the moment they are run from the tick() thread.
bool background_checkTokenRequest();
bool background_requestGroups();
bool background_requestNewMessages();
bool background_processNewMessages();
bool background_updateVoteCounts();
bool background_cleanup();
std::string genRandomId();
bool generateDummyData();
bool addExtraDummyData();
PostedDataProxy *mPostedProxy;
RsMutex mPostedMtx;
bool mUpdated;
// Ranking view mode, stored here.
uint32_t mViewMode;
uint32_t mViewPeriod;
uint32_t mViewStart;
uint32_t mViewCount;
// Processing Ranking stuff.
bool mProcessingRanking;
uint32_t mRankingState;
uint32_t mRankingExternalToken;
uint32_t mRankingInternalToken;
// background processing - Mutex protected.
time_t mLastBgCheck;
bool mBgProcessing;
uint32_t mBgPhase;
uint32_t mBgToken;
std::map<std::string, uint32_t> mBgVoteMap; // ParentId -> Vote Count.
std::map<std::string, uint32_t> mBgCommentMap; // ThreadId -> Comment Count.
// extra dummy data.
std::list<RsPostedVote> mDummyLaterVotes;
std::list<RsPostedComment> mDummyLaterComments;
};
#endif
#ifndef P3POSTED_H
#define P3POSTED_H
#include <map>
#include "retroshare/rsposted.h"
#include "gxs/rsgenexchange.h"
class GxsPostedPostRanking
{
public:
uint32_t pubToken;
uint32_t reqToken;
RsPosted::RankType rType;
RsGxsGroupId grpId;
RsPostedPostRanking rankingResult;
};
class GxsPostedCommentRanking
{
public:
uint32_t pubToken;
uint32_t reqToken;
RsPosted::RankType rType;
RsGxsGrpMsgIdPair msgId;
PostedRanking result;
};
class PostedScore {
public:
PostedScore() : upVotes(0), downVotes(0), commentCount(0), date(0) {}
uint32_t upVotes, downVotes;
uint32_t commentCount;
time_t date;
RsGxsMessageId msgId;
};
class p3Posted : public RsGenExchange, public RsPosted
{
public:
p3Posted(RsGeneralDataService* gds, RsNetworkExchangeService* nes);
protected:
/*!
* This confirms this class as an abstract one that \n
* should not be instantiated \n
* The deriving class should implement this function \n
* as it is called by the backend GXS system to \n
* update client of changes which should \n
* instigate client to retrieve new content from the system
* @param changes the changes that have occured to data held by this service
*/
void notifyChanges(std::vector<RsGxsNotify*>& changes) ;
void service_tick();
public:
void generateTopics();
/*!
* Exists solely for testing
*/
void generatePosts();
/*!
* Exists solely for testing
* Generates random votes to existing posts
* in the system
*/
void generateVotesAndComments();
public:
bool getGroup(const uint32_t &token, std::vector<RsPostedGroup> &group);
bool getPost(const uint32_t &token, PostedPostResult& posts) ;
bool getComment(const uint32_t &token, PostedCommentResult& comments) ;
bool getRelatedComment(const uint32_t& token, PostedRelatedCommentResult &comments);
bool getPostRanking(const uint32_t &token, RsPostedPostRanking &ranking);
bool submitGroup(uint32_t &token, RsPostedGroup &group);
bool submitPost(uint32_t &token, RsPostedPost &post);
bool submitVote(uint32_t &token, RsPostedVote &vote);
bool submitComment(uint32_t &token, RsPostedComment &comment) ;
// Special Ranking Request.
bool requestPostRankings(uint32_t &token, const RankType &rType, const RsGxsGroupId &groupId);
bool requestCommentRankings(uint32_t &token, const RankType &rType, const RsGxsGrpMsgIdPair &msgId);
bool retrieveScores(const std::string& serviceString, uint32_t& upVotes, uint32_t& downVotes, uint32_t& nComments) const;
private:
/* Functions for processing rankings */
void processRankings();
void processPostRanks();
void processCommentRanks();
void discardCalc(const uint32_t& token);
bool completePostedPostCalc(GxsPostedPostRanking* gpp);
void completePostedCommentRanking(GxsPostedCommentRanking* gpc);
bool storeScores(std::string& serviceString, uint32_t& upVotes, uint32_t downVotes, uint32_t nComments) const;
// for posts
void calcPostedPostRank(const std::vector<RsMsgMetaData>, PostedRanking& ranking, bool com(const PostedScore& i, const PostedScore &j)) const;
// for comments
void calcPostedCommentsRank(const std::map<RsGxsMessageId, std::vector<RsGxsMessageId> >& msgBranches, std::map<RsGxsMessageId, RsMsgMetaData>& msgMetas,
PostedRanking& ranking, bool com(const PostedScore& i, const PostedScore &j)) const;
/* Functions for maintaing vote counts in meta data */
/*!
* Update votes should only be called when a vote comes in
* Several phases to calculating votes.
* First get all messages for groups which you are subscribed
* Then for these messages get all the votes accorded to them
* Then do the calculation and update messages
* Also stores updates for messages which have new scores
*/
void updateVotes();
bool updateRequestGroups();
bool updateRequestMessages();
bool updateRequestVotesComments();
bool updateCompleteVotes();
bool updateCompleteComments();
/*!
* The aim of this is create notifications
* for the UI of changes to a post if their vote
* or comment count has changed
*/
bool updateComplete();
private:
// for calculating ranks
std::vector<GxsPostedPostRanking*> mPendingPostRanks;
std::vector<GxsPostedPostRanking*> mCompletionPostRanks;
std::map<uint32_t, RsPostedPostRanking> mCompletePostRanks;
std::map<uint32_t, GxsPostedCommentRanking*> mPendingCommentRanks;
std::map<uint32_t, GxsPostedCommentRanking*> mPendingCalculationCommentRanks;
// for maintaining vote counts in msg meta
uint32_t mUpdateRequestGroup, mUpdateRequestMessages, mUpdateRequestComments, mUpdateRequestVotes;
bool mPostUpdate;
uint32_t mUpdatePhase;
std::vector<RsGxsGrpMsgIdPair> mMsgsPendingUpdate;
time_t mLastUpdate;
GxsMsgMetaMap mMsgMetaUpdate;
std::map<RsGxsGrpMsgIdPair, PostedScore > mMsgCounts;
std::vector<uint32_t> mChangeTokens;
RsTokenService* mTokenService;
RsMutex mPostedMutex;
// for data generation
bool mGeneratingPosts, mGeneratingTopics,
mRequestPhase1, mRequestPhase2, mRequestPhase3, mGenerateVotesAndComments;
std::vector<uint32_t> mTokens;
uint32_t mToken;
std::list<RsGxsGroupId> mGrpIds;
};
#endif // P3POSTED_H

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,190 @@
/*
* libretroshare/src/services: p3posted.h
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2012-2012 by Robert Fernie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2 as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
#ifndef P3_POSTED_SERVICE_VEG_HEADER
#define P3_POSTED_SERVICE_VEG_HEADER
#include "services/p3gxsserviceVEG.h"
#include "retroshare/rspostedVEG.h"
#include <map>
#include <string>
/*
* Posted Service
*
*/
class PostedDataProxy: public GxsDataProxyVEG
{
public:
bool addGroup(const RsPostedGroup &group);
bool addPost(const RsPostedPost &post);
bool addVote(const RsPostedVote &vote);
bool addComment(const RsPostedComment &comment);
bool getGroup(const std::string &id, RsPostedGroup &group);
bool getPost(const std::string &id, RsPostedPost &post);
bool getVote(const std::string &id, RsPostedVote &vote);
bool getComment(const std::string &id, RsPostedComment &comment);
/* These Functions must be overloaded to complete the service */
virtual bool convertGroupToMetaData(void *groupData, RsGroupMetaData &meta);
virtual bool convertMsgToMetaData(void *groupData, RsMsgMetaData &meta);
};
class p3PostedServiceVEG: public p3GxsDataServiceVEG, public RsPostedVEG
{
public:
p3PostedServiceVEG(uint16_t type);
virtual int tick();
public:
// NEW INTERFACE.
/************* Extern Interface *******/
virtual bool updated();
/* Data Requests */
virtual bool requestGroupInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list<std::string> &groupIds);
virtual bool requestMsgInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list<std::string> &groupIds);
virtual bool requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list<std::string> &msgIds);
/* Generic Lists */
virtual bool getGroupList( const uint32_t &token, std::list<std::string> &groupIds);
virtual bool getMsgList( const uint32_t &token, std::list<std::string> &msgIds);
/* Generic Summary */
virtual bool getGroupSummary( const uint32_t &token, std::list<RsGroupMetaData> &groupInfo);
virtual bool getMsgSummary( const uint32_t &token, std::list<RsMsgMetaData> &msgInfo);
/* Actual Data -> specific to Interface */
/* Specific Service Data */
virtual bool getGroup(const uint32_t &token, RsPostedGroup &group);
virtual bool getPost(const uint32_t &token, RsPostedPost &post);
virtual bool getComment(const uint32_t &token, RsPostedComment &comment);
/* Poll */
virtual uint32_t requestStatus(const uint32_t token);
/* Cancel Request */
virtual bool cancelRequest(const uint32_t &token);
//////////////////////////////////////////////////////////////////////////////
virtual bool setMessageStatus(const std::string &msgId, const uint32_t status, const uint32_t statusMask);
virtual bool setGroupStatus(const std::string &groupId, const uint32_t status, const uint32_t statusMask);
virtual bool setGroupSubscribeFlags(const std::string &groupId, uint32_t subscribeFlags, uint32_t subscribeMask);
virtual bool setMessageServiceString(const std::string &msgId, const std::string &str);
virtual bool setGroupServiceString(const std::string &grpId, const std::string &str);
virtual bool groupRestoreKeys(const std::string &groupId);
virtual bool groupShareKeys(const std::string &groupId, std::list<std::string>& peers);
virtual bool submitGroup(uint32_t &token, RsPostedGroup &group, bool isNew);
virtual bool submitPost(uint32_t &token, RsPostedPost &post, bool isNew);
virtual bool submitVote(uint32_t &token, RsPostedVote &vote, bool isNew);
virtual bool submitComment(uint32_t &token, RsPostedComment &comment, bool isNew);
// Extended Interface for Collated Data View.
virtual bool setViewMode(uint32_t mode);
virtual bool setViewPeriod(uint32_t period);
virtual bool setViewRange(uint32_t first, uint32_t count);
virtual bool requestRanking(uint32_t &token, std::string groupId);
virtual bool getRankedPost(const uint32_t &token, RsPostedPost &post);
// These are exposed for GUI usage.
virtual bool encodePostedCache(std::string &str, uint32_t votes, uint32_t comments);
virtual bool extractPostedCache(const std::string &str, uint32_t &votes, uint32_t &comments);
virtual float calcPostScore(const RsMsgMetaData &meta);
private:
//
bool checkRankingRequest();
bool processPosts();
// background processing of Votes.
// NB: These should probably be handled by a background thread.
// At the moment they are run from the tick() thread.
bool background_checkTokenRequest();
bool background_requestGroups();
bool background_requestNewMessages();
bool background_processNewMessages();
bool background_updateVoteCounts();
bool background_cleanup();
std::string genRandomId();
bool generateDummyData();
bool addExtraDummyData();
PostedDataProxy *mPostedProxy;
RsMutex mPostedMtx;
bool mUpdated;
// Ranking view mode, stored here.
uint32_t mViewMode;
uint32_t mViewPeriod;
uint32_t mViewStart;
uint32_t mViewCount;
// Processing Ranking stuff.
bool mProcessingRanking;
uint32_t mRankingState;
uint32_t mRankingExternalToken;
uint32_t mRankingInternalToken;
// background processing - Mutex protected.
time_t mLastBgCheck;
bool mBgProcessing;
uint32_t mBgPhase;
uint32_t mBgToken;
std::map<std::string, uint32_t> mBgVoteMap; // ParentId -> Vote Count.
std::map<std::string, uint32_t> mBgCommentMap; // ThreadId -> Comment Count.
// extra dummy data.
std::list<RsPostedVote> mDummyLaterVotes;
std::list<RsPostedComment> mDummyLaterComments;
};
#endif

View file

@ -0,0 +1,739 @@
/*
* libretroshare/src/services p3wiki.cc
*
* Wiki interface for RetroShare.
*
* Copyright 2012-2012 by Robert Fernie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2.1 as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
#include "services/p3wiki.h"
#include "serialiser/rswikiitems.h"
#include "util/rsrandom.h"
/****
* #define WIKI_DEBUG 1
****/
RsWiki *rsWiki = NULL;
/**
* #define WIKI_GEN_DUMMY_DATA 1
**/
#define WIKI_GEN_DUMMY_DATA 1
#define WIKI_EVENT_DUMMYTICK 0x0001
#define WIKI_EVENT_DUMMYSTART 0x0002
#define DUMMYSTART_PERIOD 60 // some time for dummyIds to be generated.
#define DUMMYTICK_PERIOD 3
p3Wiki::p3Wiki(RsGeneralDataService* gds, RsNetworkExchangeService* nes)
:RsGenExchange(gds, nes, new RsGxsWikiSerialiser(), RS_SERVICE_GXSV1_TYPE_WIKI), RsWiki(this)
{
// Setup of dummy Pages.
mAboutActive = false;
mImprovActive = false;
mMarkdownActive = false;
#ifdef WIKI_GEN_DUMMY_DATA
RsTickEvent::schedule_in(WIKI_EVENT_DUMMYSTART, DUMMYSTART_PERIOD);
#endif
}
void p3Wiki::service_tick()
{
RsTickEvent::tick_events();
return;
}
void p3Wiki::notifyChanges(std::vector<RsGxsNotify*>& changes)
{
std::cerr << "p3Wiki::notifyChanges() New stuff";
std::cerr << std::endl;
receiveChanges(changes);
}
/* Specific Service Data */
bool p3Wiki::getCollections(const uint32_t &token, std::vector<RsWikiCollection> &collections)
{
std::cerr << "p3Wiki::getCollections()";
std::cerr << std::endl;
std::vector<RsGxsGrpItem*> grpData;
bool ok = RsGenExchange::getGroupData(token, grpData);
if(ok)
{
std::vector<RsGxsGrpItem*>::iterator vit = grpData.begin();
for(; vit != grpData.end(); vit++)
{
RsGxsWikiCollectionItem* item = dynamic_cast<RsGxsWikiCollectionItem*>(*vit);
if (item)
{
RsWikiCollection collection = item->collection;
collection.mMeta = item->meta;
delete item;
collections.push_back(collection);
std::cerr << "p3Wiki::getCollections() Adding Collection to Vector: ";
std::cerr << std::endl;
std::cerr << collection;
std::cerr << std::endl;
}
else
{
std::cerr << "Not a WikiCollectionItem, deleting!" << std::endl;
delete *vit;
}
}
}
return ok;
}
bool p3Wiki::getSnapshots(const uint32_t &token, std::vector<RsWikiSnapshot> &snapshots)
{
GxsMsgDataMap msgData;
bool ok = RsGenExchange::getMsgData(token, msgData);
if(ok)
{
GxsMsgDataMap::iterator mit = msgData.begin();
for(; mit != msgData.end(); mit++)
{
RsGxsGroupId grpId = mit->first;
std::vector<RsGxsMsgItem*>& msgItems = mit->second;
std::vector<RsGxsMsgItem*>::iterator vit = msgItems.begin();
for(; vit != msgItems.end(); vit++)
{
RsGxsWikiSnapshotItem* item = dynamic_cast<RsGxsWikiSnapshotItem*>(*vit);
if(item)
{
RsWikiSnapshot snapshot = item->snapshot;
snapshot.mMeta = item->meta;
snapshots.push_back(snapshot);
delete item;
}
else
{
std::cerr << "Not a WikiSnapshot Item, deleting!" << std::endl;
delete *vit;
}
}
}
}
return ok;
}
bool p3Wiki::getRelatedSnapshots(const uint32_t &token, std::vector<RsWikiSnapshot> &snapshots)
{
GxsMsgRelatedDataMap msgData;
bool ok = RsGenExchange::getMsgRelatedData(token, msgData);
if(ok)
{
GxsMsgRelatedDataMap::iterator mit = msgData.begin();
for(; mit != msgData.end(); mit++)
{
std::vector<RsGxsMsgItem*>& msgItems = mit->second;
std::vector<RsGxsMsgItem*>::iterator vit = msgItems.begin();
for(; vit != msgItems.end(); vit++)
{
RsGxsWikiSnapshotItem* item = dynamic_cast<RsGxsWikiSnapshotItem*>(*vit);
if(item)
{
RsWikiSnapshot snapshot = item->snapshot;
snapshot.mMeta = item->meta;
snapshots.push_back(snapshot);
delete item;
}
else
{
std::cerr << "Not a WikiSnapshot Item, deleting!" << std::endl;
delete *vit;
}
}
}
}
return ok;
}
bool p3Wiki::getComments(const uint32_t &token, std::vector<RsWikiComment> &comments)
{
GxsMsgDataMap msgData;
bool ok = RsGenExchange::getMsgData(token, msgData);
if(ok)
{
GxsMsgDataMap::iterator mit = msgData.begin();
for(; mit != msgData.end(); mit++)
{
RsGxsGroupId grpId = mit->first;
std::vector<RsGxsMsgItem*>& msgItems = mit->second;
std::vector<RsGxsMsgItem*>::iterator vit = msgItems.begin();
for(; vit != msgItems.end(); vit++)
{
RsGxsWikiCommentItem* item = dynamic_cast<RsGxsWikiCommentItem*>(*vit);
if(item)
{
RsWikiComment comment = item->comment;
comment.mMeta = item->meta;
comments.push_back(comment);
delete item;
}
else
{
std::cerr << "Not a WikiComment Item, deleting!" << std::endl;
delete *vit;
}
}
}
}
return ok;
return false;
}
bool p3Wiki::submitCollection(uint32_t &token, RsWikiCollection &collection)
{
RsGxsWikiCollectionItem* collectionItem = new RsGxsWikiCollectionItem();
collectionItem->collection = collection;
collectionItem->meta = collection.mMeta;
std::cerr << "p3Wiki::submitCollection(): ";
std::cerr << std::endl;
std::cerr << collection;
std::cerr << std::endl;
std::cerr << "p3Wiki::submitCollection() pushing to RsGenExchange";
std::cerr << std::endl;
RsGenExchange::publishGroup(token, collectionItem);
return true;
}
bool p3Wiki::submitSnapshot(uint32_t &token, RsWikiSnapshot &snapshot)
{
std::cerr << "p3Wiki::submitSnapshot(): " << snapshot;
std::cerr << std::endl;
RsGxsWikiSnapshotItem* snapshotItem = new RsGxsWikiSnapshotItem();
snapshotItem->snapshot = snapshot;
snapshotItem->meta = snapshot.mMeta;
snapshotItem->meta.mMsgFlags = FLAG_MSG_TYPE_WIKI_SNAPSHOT;
RsGenExchange::publishMsg(token, snapshotItem);
return true;
}
bool p3Wiki::submitComment(uint32_t &token, RsWikiComment &comment)
{
RsGxsWikiCommentItem* commentItem = new RsGxsWikiCommentItem();
commentItem->comment = comment;
commentItem->meta = comment.mMeta;
commentItem->meta.mMsgFlags = FLAG_MSG_TYPE_WIKI_COMMENT;
RsGenExchange::publishMsg(token, commentItem);
return true;
}
std::ostream &operator<<(std::ostream &out, const RsWikiCollection &group)
{
out << "RsWikiCollection [ ";
out << " Name: " << group.mMeta.mGroupName;
out << " Desc: " << group.mDescription;
out << " Category: " << group.mCategory;
out << " ]";
return out;
}
std::ostream &operator<<(std::ostream &out, const RsWikiSnapshot &shot)
{
out << "RsWikiSnapshot [ ";
out << "Title: " << shot.mMeta.mMsgName;
out << "]";
return out;
}
std::ostream &operator<<(std::ostream &out, const RsWikiComment &comment)
{
out << "RsWikiComment [ ";
out << "Title: " << comment.mMeta.mMsgName;
out << "]";
return out;
}
/***** FOR TESTING *****/
std::string p3Wiki::genRandomId()
{
std::string randomId;
for(int i = 0; i < 20; i++)
{
randomId += (char) ('a' + (RSRandom::random_u32() % 26));
}
return randomId;
}
const int about_len = 10;
const std::string about_txt[] =
{ "Welcome to RsWiki, a fully distributed Wiki system that anyone can edit.",
"Please read through these dummy Wiki pages to learn how it should work\n",
"Basic Functionality:",
" - New Group: creates a collection of Wiki Pages, the creator of group",
" and anyone they share the publish keys with) is the moderator\n",
" - New Page: Create a new Wiki Page, only Group Moderators can do this\n",
" - Edit: Anyone Can Edit the Wiki Page, and the changes form a tree under the original\n",
" - RePublish: This is used by the Moderators to accept and reject Edits.",
" the republished page becomes a new version of the Root Page, allowing more edits to be done\n",
"Please read the improvements section to see how we envision the wiki's working",
};
const int improvements_len = 14;
const std::string improvements_txt[] =
{ "As you can see, the current Wiki is a basic framework waiting to be expanded.",
"There are lots of potential improvements... some of my ideas are listed below\n",
"Ideas:",
" - Formatting: No HTML, lets use Markdown or something similar.\n",
" - Diffs, lots of edits will lead to complex merges - a robust merge tool is essential\n",
" - Read Mode... hide all the Edits, and only show the most recently published versions\n",
" - Easy Duplication - to take over an Abandoned or badly moderated Wiki. Copies All base versions to a new group\n",
" - WikiLinks. A generic Wiki Cross Linking system. This should be combined with Easy Duplication option,",
" to allow easy replacement of groups if necessary... A good design here is critical to a successful Wiki ecosystem\n",
" - work out how to include media (photos, audio, video, etc) without embedding in pages",
" this would leverage the turtle transfer system somehow - maybe like channels.\n",
" - Comments, reviews etc can be incorporated - ideas here are welcome.\n",
" - Any other suggestion???",
" - Come on more ideas!"
};
const int markdown_len = 34;
const std::string markdown_txt[] = {
"# An Example of Markdown Editing.",
"",
"Markdown is quite simple to use, and allows simple HTML.",
"",
"## Some Blocks below an H2 heading.",
"",
" * Firstly, we can put a link [in here][]",
" * Secondly, as you can see we're in a list.",
" * Thirdly, I don't know.",
"",
"### A Sub (H3) heading.",
"",
"#### If we want to get into the very small details. (H6).",
"",
" A bit of code.",
" This is a lit",
" foreach(in loop)",
" a++",
" Double quoted stuff.",
"",
"Or it can be indented like this:",
"",
"> A block of indented stuff looks like this",
"> > With double indenting and ",
"> > > triple indenting possible too",
"",
"Images can be embedded, but thats somethinng to work on in the future.",
"",
"Sadly it doesn't support tables or div's or anything that complex.",
"",
"Keep it simple and help write good wiki pages, thx.",
"",
"[in here]: http://example.com/ \"Optional Title Here\"",
""
};
void p3Wiki::generateDummyData()
{
std::cerr << "p3Wiki::generateDummyData()";
std::cerr << std::endl;
#define GEN_COLLECTIONS 0
int i;
for(i = 0; i < GEN_COLLECTIONS; i++)
{
RsWikiCollection wiki;
wiki.mMeta.mGroupId = genRandomId();
wiki.mMeta.mGroupFlags = 0;
wiki.mMeta.mGroupName = genRandomId();
uint32_t dummyToken = 0;
submitCollection(dummyToken, wiki);
}
RsWikiCollection wiki;
wiki.mMeta.mGroupFlags = 0;
wiki.mMeta.mGroupName = "About RsWiki";
submitCollection(mAboutToken, wiki);
wiki.mMeta.mGroupFlags = 0;
wiki.mMeta.mGroupName = "RsWiki Improvements";
submitCollection(mImprovToken, wiki);
wiki.mMeta.mGroupFlags = 0;
wiki.mMeta.mGroupName = "RsWiki Markdown";
submitCollection(mMarkdownToken, wiki);
mAboutLines = 0;
mImprovLines = 0;
mMarkdownLines = 0;
mAboutActive = true;
mImprovActive = true;
mMarkdownActive = true;
RsTickEvent::schedule_in(WIKI_EVENT_DUMMYTICK, DUMMYTICK_PERIOD);
}
bool generateNextDummyPage(const RsGxsMessageId &threadId, const int lines, const RsGxsGrpMsgIdPair &parentId,
const std::string *page_lines, const int num_pagelines, RsWikiSnapshot &snapshot)
{
snapshot.mMeta.mGroupId = parentId.first;
// Create an About Page.
#define NUM_SUB_PAGES 3
if ((lines % NUM_SUB_PAGES == 0) || (lines == num_pagelines))
{
/* do a new baseline */
snapshot.mMeta.mOrigMsgId = threadId;
}
else
{
snapshot.mMeta.mParentId = parentId.second;
snapshot.mMeta.mThreadId = threadId;
}
std::string page;
for(int i = 0; (i < lines) && (i < num_pagelines); i++)
{
snapshot.mPage += page_lines[i];
snapshot.mPage += '\n';
}
return (lines <= num_pagelines);
}
#include <retroshare/rsidentity.h>
std::string chooseRandomAuthorId()
{
/* chose a random Id to sign with */
std::list<RsGxsId> ownIds;
std::list<RsGxsId>::iterator it;
rsIdentity->getOwnIds(ownIds);
uint32_t idx = (uint32_t) (ownIds.size() * RSRandom::random_f32());
int i = 0;
for(it = ownIds.begin(); (it != ownIds.end()) && (i < idx); it++, i++);
std::string answer;
if (it != ownIds.end())
{
answer = *it;
}
return answer;
}
void p3Wiki::dummyTick()
{
if (mAboutActive)
{
std::cerr << "p3Wiki::dummyTick() AboutActive";
std::cerr << std::endl;
uint32_t status = RsGenExchange::getTokenService()->requestStatus(mAboutToken);
if (status == RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE)
{
std::cerr << "p3Wiki::dummyTick() AboutActive, Lines: " << mAboutLines;
std::cerr << std::endl;
if (mAboutLines == 0)
{
/* get the group Id */
RsGxsGroupId groupId;
if (!acknowledgeTokenGrp(mAboutToken, groupId))
{
std::cerr << " ERROR ";
std::cerr << std::endl;
mAboutActive = false;
}
/* create baseline snapshot */
RsWikiSnapshot page;
page.mMeta.mGroupId = groupId;
page.mPage = "Baseline page... a placeholder for About Wiki";
page.mMeta.mMsgName = "About RsWiki";
page.mMeta.mAuthorId = chooseRandomAuthorId();
submitSnapshot(mAboutToken, page);
mAboutLines++;
}
else
{
/* get the msg Id, and generate next snapshot */
RsGxsGrpMsgIdPair msgId;
if (!acknowledgeTokenMsg(mAboutToken, msgId))
{
std::cerr << " ERROR ";
std::cerr << std::endl;
mAboutActive = false;
}
if (mAboutLines == 1)
{
mAboutThreadId = msgId.second;
}
RsWikiSnapshot page;
page.mMeta.mMsgName = "About RsWiki";
page.mMeta.mAuthorId = chooseRandomAuthorId();
if (!generateNextDummyPage(mAboutThreadId, mAboutLines, msgId, about_txt, about_len, page))
{
std::cerr << "About Pages Done";
std::cerr << std::endl;
mAboutActive = false;
}
else
{
mAboutLines++;
submitSnapshot(mAboutToken, page);
}
}
}
}
if (mImprovActive)
{
std::cerr << "p3Wiki::dummyTick() ImprovActive";
std::cerr << std::endl;
uint32_t status = RsGenExchange::getTokenService()->requestStatus(mImprovToken);
if (status == RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE)
{
std::cerr << "p3Wiki::dummyTick() ImprovActive, Lines: " << mImprovLines;
std::cerr << std::endl;
if (mImprovLines == 0)
{
/* get the group Id */
RsGxsGroupId groupId;
if (!acknowledgeTokenGrp(mImprovToken, groupId))
{
std::cerr << " ERROR ";
std::cerr << std::endl;
mImprovActive = false;
}
/* create baseline snapshot */
RsWikiSnapshot page;
page.mMeta.mGroupId = groupId;
page.mPage = "Baseline page... a placeholder for Improv Wiki";
page.mMeta.mMsgName = "Improv RsWiki";
page.mMeta.mAuthorId = chooseRandomAuthorId();
submitSnapshot(mImprovToken, page);
mImprovLines++;
}
else
{
/* get the msg Id, and generate next snapshot */
RsGxsGrpMsgIdPair msgId;
if (!acknowledgeTokenMsg(mImprovToken, msgId))
{
std::cerr << " ERROR ";
std::cerr << std::endl;
mImprovActive = false;
}
if (mImprovLines == 1)
{
mImprovThreadId = msgId.second;
}
RsWikiSnapshot page;
page.mMeta.mMsgName = "Improv RsWiki";
page.mMeta.mAuthorId = chooseRandomAuthorId();
if (!generateNextDummyPage(mImprovThreadId, mImprovLines, msgId, improvements_txt, improvements_len, page))
{
std::cerr << "Improv Pages Done";
std::cerr << std::endl;
mImprovActive = false;
}
else
{
mImprovLines++;
submitSnapshot(mImprovToken, page);
}
}
}
}
if (mMarkdownActive)
{
std::cerr << "p3Wiki::dummyTick() MarkdownActive";
std::cerr << std::endl;
uint32_t status = RsGenExchange::getTokenService()->requestStatus(mMarkdownToken);
if (status == RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE)
{
std::cerr << "p3Wiki::dummyTick() MarkdownActive, Lines: " << mMarkdownLines;
std::cerr << std::endl;
if (mMarkdownLines == 0)
{
/* get the group Id */
RsGxsGroupId groupId;
if (!acknowledgeTokenGrp(mMarkdownToken, groupId))
{
std::cerr << " ERROR ";
std::cerr << std::endl;
mMarkdownActive = false;
}
/* create baseline snapshot */
RsWikiSnapshot page;
page.mMeta.mGroupId = groupId;
page.mPage = "Baseline page... a placeholder for Markdown Wiki";
page.mMeta.mMsgName = "Markdown RsWiki";
page.mMeta.mAuthorId = chooseRandomAuthorId();
submitSnapshot(mMarkdownToken, page);
mMarkdownLines++;
}
else
{
/* get the msg Id, and generate next snapshot */
RsGxsGrpMsgIdPair msgId;
if (!acknowledgeTokenMsg(mMarkdownToken, msgId))
{
std::cerr << " ERROR ";
std::cerr << std::endl;
mMarkdownActive = false;
}
if (mMarkdownLines == 1)
{
mMarkdownThreadId = msgId.second;
}
RsWikiSnapshot page;
page.mMeta.mMsgName = "Markdown RsWiki";
page.mMeta.mAuthorId = chooseRandomAuthorId();
if (!generateNextDummyPage(mMarkdownThreadId, mMarkdownLines, msgId, markdown_txt, markdown_len, page))
{
std::cerr << "Markdown Pages Done";
std::cerr << std::endl;
mMarkdownActive = false;
}
else
{
mMarkdownLines++;
submitSnapshot(mMarkdownToken, page);
}
}
}
}
if ((mAboutActive) || (mImprovActive) || (mMarkdownActive))
{
/* reschedule next one */
RsTickEvent::schedule_in(WIKI_EVENT_DUMMYTICK, DUMMYTICK_PERIOD);
}
}
// Overloaded from RsTickEvent for Event callbacks.
void p3Wiki::handle_event(uint32_t event_type, const std::string &elabel)
{
std::cerr << "p3Wiki::handle_event(" << event_type << ")";
std::cerr << std::endl;
// stuff.
switch(event_type)
{
case WIKI_EVENT_DUMMYSTART:
generateDummyData();
break;
case WIKI_EVENT_DUMMYTICK:
dummyTick();
break;
default:
/* error */
std::cerr << "p3Wiki::handle_event() Unknown Event Type: " << event_type;
std::cerr << std::endl;
break;
}
}

View file

@ -0,0 +1,99 @@
/*
* libretroshare/src/services: p3wikiservice.h
*
* Wiki interface for RetroShare.
*
* Copyright 2012-2012 by Robert Fernie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2.1 as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
#ifndef P3_WIKI_SERVICE_HEADER
#define P3_WIKI_SERVICE_HEADER
#include "retroshare/rswiki.h"
#include "gxs/rsgenexchange.h"
#include "util/rstickevent.h"
#include <map>
#include <string>
/*
* Wiki Service
*
*
*/
class p3Wiki: public RsGenExchange, public RsWiki,
public RsTickEvent
{
public:
p3Wiki(RsGeneralDataService* gds, RsNetworkExchangeService* nes);
protected:
virtual void notifyChanges(std::vector<RsGxsNotify*>& changes) ;
// Overloaded from RsTickEvent.
virtual void handle_event(uint32_t event_type, const std::string &elabel);
public:
virtual void service_tick();
/* Specific Service Data */
virtual bool getCollections(const uint32_t &token, std::vector<RsWikiCollection> &collections);
virtual bool getSnapshots(const uint32_t &token, std::vector<RsWikiSnapshot> &snapshots);
virtual bool getComments(const uint32_t &token, std::vector<RsWikiComment> &comments);
virtual bool getRelatedSnapshots(const uint32_t &token, std::vector<RsWikiSnapshot> &snapshots);
virtual bool submitCollection(uint32_t &token, RsWikiCollection &collection);
virtual bool submitSnapshot(uint32_t &token, RsWikiSnapshot &snapshot);
virtual bool submitComment(uint32_t &token, RsWikiComment &comment);
private:
std::string genRandomId();
// RsMutex mWikiMtx;
virtual void generateDummyData();
// Dummy Stuff.
void dummyTick();
bool mAboutActive;
uint32_t mAboutToken;
int mAboutLines;
RsGxsMessageId mAboutThreadId;
bool mImprovActive;
uint32_t mImprovToken;
int mImprovLines;
RsGxsMessageId mImprovThreadId;
bool mMarkdownActive;
uint32_t mMarkdownToken;
int mMarkdownLines;
RsGxsMessageId mMarkdownThreadId;
};
#endif

View file

@ -1,595 +0,0 @@
/*
* libretroshare/src/services p3wikiservice.cc
*
* Wiki interface for RetroShare.
*
* Copyright 2012-2012 by Robert Fernie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2 as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
#include "services/p3wikiservice.h"
#include "util/rsrandom.h"
/****
* #define WIKI_DEBUG 1
****/
RsWiki *rsWiki = NULL;
/********************************************************************************/
/******************* Startup / Tick ******************************************/
/********************************************************************************/
p3WikiService::p3WikiService(uint16_t type)
:p3GxsDataService(type, new WikiDataProxy()), mWikiMtx("p3WikiService"), mUpdated(true)
{
RsStackMutex stack(mWikiMtx); /********** STACK LOCKED MTX ******/
mWikiProxy = (WikiDataProxy *) mProxy;
return;
}
int p3WikiService::tick()
{
std::cerr << "p3WikiService::tick()";
std::cerr << std::endl;
fakeprocessrequests();
return 0;
}
bool p3WikiService::updated()
{
RsStackMutex stack(mWikiMtx); /********** STACK LOCKED MTX ******/
if (mUpdated)
{
mUpdated = false;
return true;
}
return false;
}
/* Data Requests */
bool p3WikiService::requestGroupInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list<std::string> &groupIds)
{
generateToken(token);
std::cerr << "p3WikiService::requestGroupInfo() gets Token: " << token << std::endl;
storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_GROUPS, groupIds);
return true;
}
bool p3WikiService::requestMsgInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list<std::string> &groupIds)
{
generateToken(token);
std::cerr << "p3WikiService::requestMsgInfo() gets Token: " << token << std::endl;
storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_MSGS, groupIds);
return true;
}
bool p3WikiService::requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list<std::string> &msgIds)
{
generateToken(token);
std::cerr << "p3WikiService::requestMsgRelatedInfo() gets Token: " << token << std::endl;
storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_MSGRELATED, msgIds);
return true;
}
/* Generic Lists */
bool p3WikiService::getGroupList( const uint32_t &token, std::list<std::string> &groupIds)
{
uint32_t status;
uint32_t reqtype;
uint32_t anstype;
time_t ts;
checkRequestStatus(token, status, reqtype, anstype, ts);
if (anstype != RS_TOKREQ_ANSTYPE_LIST)
{
std::cerr << "p3WikiService::getGroupList() ERROR AnsType Wrong" << std::endl;
return false;
}
if (reqtype != GXS_REQUEST_TYPE_GROUPS)
{
std::cerr << "p3WikiService::getGroupList() ERROR ReqType Wrong" << std::endl;
return false;
}
if (status != GXS_REQUEST_STATUS_COMPLETE)
{
std::cerr << "p3WikiService::getGroupList() ERROR Status Incomplete" << std::endl;
return false;
}
bool ans = loadRequestOutList(token, groupIds);
updateRequestStatus(token, GXS_REQUEST_STATUS_DONE);
return ans;
}
bool p3WikiService::getMsgList( const uint32_t &token, std::list<std::string> &msgIds)
{
uint32_t status;
uint32_t reqtype;
uint32_t anstype;
time_t ts;
checkRequestStatus(token, status, reqtype, anstype, ts);
if (anstype != RS_TOKREQ_ANSTYPE_LIST)
{
std::cerr << "p3WikiService::getMsgList() ERROR AnsType Wrong" << std::endl;
return false;
}
if ((reqtype != GXS_REQUEST_TYPE_MSGS) && (reqtype != GXS_REQUEST_TYPE_MSGRELATED))
{
std::cerr << "p3WikiService::getMsgList() ERROR ReqType Wrong" << std::endl;
return false;
}
if (status != GXS_REQUEST_STATUS_COMPLETE)
{
std::cerr << "p3WikiService::getMsgList() ERROR Status Incomplete" << std::endl;
return false;
}
bool ans = loadRequestOutList(token, msgIds);
updateRequestStatus(token, GXS_REQUEST_STATUS_DONE);
return ans;
}
/* Generic Summary */
bool p3WikiService::getGroupSummary( const uint32_t &token, std::list<RsGroupMetaData> &groupInfo)
{
uint32_t status;
uint32_t reqtype;
uint32_t anstype;
time_t ts;
checkRequestStatus(token, status, reqtype, anstype, ts);
if (anstype != RS_TOKREQ_ANSTYPE_SUMMARY)
{
std::cerr << "p3WikiService::getGroupSummary() ERROR AnsType Wrong" << std::endl;
return false;
}
if (reqtype != GXS_REQUEST_TYPE_GROUPS)
{
std::cerr << "p3WikiService::getGroupSummary() ERROR ReqType Wrong" << std::endl;
return false;
}
if (status != GXS_REQUEST_STATUS_COMPLETE)
{
std::cerr << "p3WikiService::getGroupSummary() ERROR Status Incomplete" << std::endl;
return false;
}
std::list<std::string> groupIds;
bool ans = loadRequestOutList(token, groupIds);
updateRequestStatus(token, GXS_REQUEST_STATUS_DONE);
/* convert to RsGroupMetaData */
mProxy->getGroupSummary(groupIds, groupInfo);
return ans;
}
bool p3WikiService::getMsgSummary( const uint32_t &token, std::list<RsMsgMetaData> &msgInfo)
{
uint32_t status;
uint32_t reqtype;
uint32_t anstype;
time_t ts;
checkRequestStatus(token, status, reqtype, anstype, ts);
if (anstype != RS_TOKREQ_ANSTYPE_SUMMARY)
{
std::cerr << "p3WikiService::getMsgSummary() ERROR AnsType Wrong" << std::endl;
return false;
}
if ((reqtype != GXS_REQUEST_TYPE_MSGS) && (reqtype != GXS_REQUEST_TYPE_MSGRELATED))
{
std::cerr << "p3WikiService::getMsgSummary() ERROR ReqType Wrong" << std::endl;
return false;
}
if (status != GXS_REQUEST_STATUS_COMPLETE)
{
std::cerr << "p3WikiService::getMsgSummary() ERROR Status Incomplete" << std::endl;
return false;
}
std::list<std::string> msgIds;
bool ans = loadRequestOutList(token, msgIds);
updateRequestStatus(token, GXS_REQUEST_STATUS_DONE);
/* convert to RsMsgMetaData */
mProxy->getMsgSummary(msgIds, msgInfo);
return ans;
}
/* Specific Service Data */
bool p3WikiService::getGroupData(const uint32_t &token, RsWikiGroup &group)
{
uint32_t status;
uint32_t reqtype;
uint32_t anstype;
time_t ts;
checkRequestStatus(token, status, reqtype, anstype, ts);
if (anstype != RS_TOKREQ_ANSTYPE_DATA)
{
std::cerr << "p3WikiService::getGroupData() ERROR AnsType Wrong" << std::endl;
return false;
}
if (reqtype != GXS_REQUEST_TYPE_GROUPS)
{
std::cerr << "p3WikiService::getGroupData() ERROR ReqType Wrong" << std::endl;
return false;
}
if (status != GXS_REQUEST_STATUS_COMPLETE)
{
std::cerr << "p3WikiService::getGroupData() ERROR Status Incomplete" << std::endl;
return false;
}
std::string id;
if (!popRequestOutList(token, id))
{
/* finished */
updateRequestStatus(token, GXS_REQUEST_STATUS_DONE);
return false;
}
/* convert to RsWikiAlbum */
bool ans = mWikiProxy->getGroup(id, group);
return ans;
}
bool p3WikiService::getMsgData(const uint32_t &token, RsWikiPage &page)
{
uint32_t status;
uint32_t reqtype;
uint32_t anstype;
time_t ts;
checkRequestStatus(token, status, reqtype, anstype, ts);
if (anstype != RS_TOKREQ_ANSTYPE_DATA)
{
std::cerr << "p3WikiService::getMsgData() ERROR AnsType Wrong" << std::endl;
return false;
}
if ((reqtype != GXS_REQUEST_TYPE_MSGS) && (reqtype != GXS_REQUEST_TYPE_MSGRELATED))
{
std::cerr << "p3WikiService::getMsgData() ERROR ReqType Wrong" << std::endl;
return false;
}
if (status != GXS_REQUEST_STATUS_COMPLETE)
{
std::cerr << "p3WikiService::getMsgData() ERROR Status Incomplete" << std::endl;
return false;
}
std::string id;
if (!popRequestOutList(token, id))
{
/* finished */
updateRequestStatus(token, GXS_REQUEST_STATUS_DONE);
return false;
}
/* convert to RsWikiAlbum */
bool ans = mWikiProxy->getPage(id, page);
return ans;
}
/* Poll */
uint32_t p3WikiService::requestStatus(const uint32_t token)
{
uint32_t status;
uint32_t reqtype;
uint32_t anstype;
time_t ts;
checkRequestStatus(token, status, reqtype, anstype, ts);
return status;
}
/* Cancel Request */
bool p3WikiService::cancelRequest(const uint32_t &token)
{
return clearRequest(token);
}
//////////////////////////////////////////////////////////////////////////////
bool p3WikiService::setMessageStatus(const std::string &msgId, const uint32_t status, const uint32_t statusMask)
{
return mWikiProxy->setMessageStatus(msgId, status, statusMask);
}
bool p3WikiService::setGroupStatus(const std::string &groupId, const uint32_t status, const uint32_t statusMask)
{
return mWikiProxy->setGroupStatus(groupId, status, statusMask);
}
bool p3WikiService::setGroupSubscribeFlags(const std::string &groupId, uint32_t subscribeFlags, uint32_t subscribeMask)
{
return mWikiProxy->setGroupSubscribeFlags(groupId, subscribeFlags, subscribeMask);
}
bool p3WikiService::setMessageServiceString(const std::string &msgId, const std::string &str)
{
return mWikiProxy->setMessageServiceString(msgId, str);
}
bool p3WikiService::setGroupServiceString(const std::string &grpId, const std::string &str)
{
return mWikiProxy->setGroupServiceString(grpId, str);
}
bool p3WikiService::groupRestoreKeys(const std::string &groupId)
{
return false;
}
bool p3WikiService::groupShareKeys(const std::string &groupId, std::list<std::string>& peers)
{
return false;
}
/********************************************************************************************/
std::string p3WikiService::genRandomId()
{
std::string randomId;
for(int i = 0; i < 20; i++)
{
randomId += (char) ('a' + (RSRandom::random_u32() % 26));
}
return randomId;
}
bool p3WikiService::createGroup(uint32_t &token, RsWikiGroup &group, bool isNew)
{
if (group.mMeta.mGroupId.empty())
{
/* new photo */
/* generate a temp id */
group.mMeta.mGroupId = genRandomId();
}
else
{
std::cerr << "p3WikiService::createGroup() Group with existing Id... dropping";
std::cerr << std::endl;
return false;
}
{
RsStackMutex stack(mWikiMtx); /********** STACK LOCKED MTX ******/
mUpdated = true;
mWikiProxy->addGroup(group);
}
// Fake a request to return the GroupMetaData.
generateToken(token);
uint32_t ansType = RS_TOKREQ_ANSTYPE_SUMMARY;
RsTokReqOptions opts; // NULL is good.
std::list<std::string> groupIds;
groupIds.push_back(group.mMeta.mGroupId); // It will just return this one.
std::cerr << "p3WikiService::createGroup() Generating Request Token: " << token << std::endl;
storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_GROUPS, groupIds);
return true;
}
bool p3WikiService::createPage(uint32_t &token, RsWikiPage &page, bool isNew)
{
if (page.mMeta.mGroupId.empty())
{
/* new photo */
std::cerr << "p3WikiService::createPage() Missing PageID";
std::cerr << std::endl;
return false;
}
/* check if its a mod or new page */
if (page.mMeta.mOrigMsgId.empty())
{
std::cerr << "p3WikiService::createPage() New Page";
std::cerr << std::endl;
/* new page, generate a new OrigPageId */
page.mMeta.mOrigMsgId = genRandomId();
page.mMeta.mMsgId = page.mMeta.mOrigMsgId;
}
else
{
std::cerr << "p3WikiService::createPage() Modified Page";
std::cerr << std::endl;
/* mod page, keep orig page id, generate a new PageId */
page.mMeta.mMsgId = genRandomId();
}
std::cerr << "p3WikiService::createPage() GroupId: " << page.mMeta.mGroupId;
std::cerr << std::endl;
std::cerr << "p3WikiService::createPage() PageId: " << page.mMeta.mMsgId;
std::cerr << std::endl;
std::cerr << "p3WikiService::createPage() OrigPageId: " << page.mMeta.mOrigMsgId;
std::cerr << std::endl;
{
RsStackMutex stack(mWikiMtx); /********** STACK LOCKED MTX ******/
mUpdated = true;
mWikiProxy->addPage(page);
}
// Fake a request to return the MsgMetaData.
generateToken(token);
uint32_t ansType = RS_TOKREQ_ANSTYPE_SUMMARY;
RsTokReqOptions opts; // NULL is good.
std::list<std::string> msgIds;
msgIds.push_back(page.mMeta.mMsgId); // It will just return this one.
std::cerr << "p3WikiService::createPage() Generating Request Token: " << token << std::endl;
storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_MSGRELATED, msgIds);
return true;
}
/********************************************************************************************/
bool WikiDataProxy::getGroup(const std::string &id, RsWikiGroup &group)
{
void *groupData = NULL;
RsGroupMetaData meta;
if (getGroupData(id, groupData) && getGroupSummary(id, meta))
{
RsWikiGroup *pG = (RsWikiGroup *) groupData;
group = *pG;
// update definitive version of the metadata.
group.mMeta = meta;
std::cerr << "WikiDataProxy::getGroup() Id: " << id;
std::cerr << " MetaData: " << meta << " DataPointer: " << groupData;
std::cerr << std::endl;
return true;
}
std::cerr << "WikiDataProxy::getGroup() FAILED Id: " << id;
std::cerr << std::endl;
return false;
}
bool WikiDataProxy::getPage(const std::string &id, RsWikiPage &page)
{
void *msgData = NULL;
RsMsgMetaData meta;
if (getMsgData(id, msgData) && getMsgSummary(id, meta))
{
RsWikiPage *pP = (RsWikiPage *) msgData;
// Shallow copy of thumbnail.
page = *pP;
// update definitive version of the metadata.
page.mMeta = meta;
std::cerr << "WikiDataProxy::getPage() Id: " << id;
std::cerr << " MetaData: " << meta << " DataPointer: " << msgData;
std::cerr << std::endl;
return true;
}
std::cerr << "WikiDataProxy::getPage() FAILED Id: " << id;
std::cerr << std::endl;
return false;
}
bool WikiDataProxy::addGroup(const RsWikiGroup &group)
{
// Make duplicate.
RsWikiGroup *pG = new RsWikiGroup();
*pG = group;
std::cerr << "WikiDataProxy::addGroup()";
std::cerr << " MetaData: " << pG->mMeta << " DataPointer: " << pG;
std::cerr << std::endl;
return createGroup(pG);
}
bool WikiDataProxy::addPage(const RsWikiPage &page)
{
// Make duplicate.
RsWikiPage *pP = new RsWikiPage();
*pP = page;
std::cerr << "WikiDataProxy::addPage()";
std::cerr << " MetaData: " << pP->mMeta << " DataPointer: " << pP;
std::cerr << std::endl;
return createMsg(pP);
}
/* These Functions must be overloaded to complete the service */
bool WikiDataProxy::convertGroupToMetaData(void *groupData, RsGroupMetaData &meta)
{
RsWikiGroup *group = (RsWikiGroup *) groupData;
meta = group->mMeta;
return true;
}
bool WikiDataProxy::convertMsgToMetaData(void *msgData, RsMsgMetaData &meta)
{
RsWikiPage *page = (RsWikiPage *) msgData;
meta = page->mMeta;
return true;
}

View file

@ -1,129 +0,0 @@
/*
* libretroshare/src/services: p3wikiservice.h
*
* Wiki interface for RetroShare.
*
* Copyright 2012-2012 by Robert Fernie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2 as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
#ifndef P3_WIKI_SERVICE_HEADER
#define P3_WIKI_SERVICE_HEADER
#include "services/p3gxsservice.h"
#include "retroshare/rswiki.h"
#include <map>
#include <string>
/*
* Wiki Service
*
* This is an example service for the new cache system.
* For the moment, it will only hold data passed to it from the GUI.
* and spew that back when asked....
*
* We are doing it like this - so we can check the required interface functionality.
*
* Expect it won't take long before it'll be properly linked into the backend!
*
* This will be transformed into a Plugin Service, once the basics have been worked out.
*
*/
class WikiDataProxy: public GxsDataProxy
{
public:
bool getGroup(const std::string &id, RsWikiGroup &group);
bool getPage(const std::string &id, RsWikiPage &wiki);
bool addGroup(const RsWikiGroup &group);
bool addPage(const RsWikiPage &page);
/* These Functions must be overloaded to complete the service */
virtual bool convertGroupToMetaData(void *groupData, RsGroupMetaData &meta);
virtual bool convertMsgToMetaData(void *msgData, RsMsgMetaData &meta);
};
class p3WikiService: public p3GxsDataService, public RsWiki
{
public:
p3WikiService(uint16_t type);
virtual int tick();
public:
virtual bool updated();
/* Data Requests */
virtual bool requestGroupInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list<std::string> &groupIds);
virtual bool requestMsgInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list<std::string> &groupIds);
virtual bool requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list<std::string> &msgIds);
/* Generic Lists */
virtual bool getGroupList( const uint32_t &token, std::list<std::string> &groupIds);
virtual bool getMsgList( const uint32_t &token, std::list<std::string> &msgIds);
/* Generic Summary */
virtual bool getGroupSummary( const uint32_t &token, std::list<RsGroupMetaData> &groupInfo);
virtual bool getMsgSummary( const uint32_t &token, std::list<RsMsgMetaData> &msgInfo);
/* Actual Data -> specific to Interface */
/* Specific Service Data */
virtual bool getGroupData(const uint32_t &token, RsWikiGroup &group);
virtual bool getMsgData(const uint32_t &token, RsWikiPage &page);
/* Poll */
virtual uint32_t requestStatus(const uint32_t token);
/* Cancel Request */
virtual bool cancelRequest(const uint32_t &token);
//////////////////////////////////////////////////////////////////////////////
virtual bool setMessageStatus(const std::string &msgId, const uint32_t status, const uint32_t statusMask);
virtual bool setGroupStatus(const std::string &groupId, const uint32_t status, const uint32_t statusMask);
virtual bool setGroupSubscribeFlags(const std::string &groupId, uint32_t subscribeFlags, uint32_t subscribeMask);
virtual bool setMessageServiceString(const std::string &msgId, const std::string &str);
virtual bool setGroupServiceString(const std::string &grpId, const std::string &str);
virtual bool groupRestoreKeys(const std::string &groupId);
virtual bool groupShareKeys(const std::string &groupId, std::list<std::string>& peers);
virtual bool createGroup(uint32_t &token, RsWikiGroup &group, bool isNew);
virtual bool createPage(uint32_t &token, RsWikiPage &page, bool isNew);
private:
std::string genRandomId();
WikiDataProxy *mWikiProxy;
RsMutex mWikiMtx;
bool mUpdated;
};
#endif

View file

@ -24,575 +24,184 @@
*/
#include "services/p3wire.h"
#include "serialiser/rswireitems.h"
#include "util/rsrandom.h"
/****
* #define WIKI_DEBUG 1
* #define WIRE_DEBUG 1
****/
RsWire *rsWire = NULL;
/********************************************************************************/
/******************* Startup / Tick ******************************************/
/********************************************************************************/
p3Wire::p3Wire(uint16_t type)
:p3GxsDataService(type, new WireDataProxy()), mWireMtx("p3Wire"), mUpdated(true)
p3Wire::p3Wire(RsGeneralDataService* gds, RsNetworkExchangeService* nes)
:RsGenExchange(gds, nes, new RsGxsWireSerialiser(), RS_SERVICE_GXSV1_TYPE_WIRE), RsWire(this), mWireMtx("WireMtx")
{
RsStackMutex stack(mWireMtx); /********** STACK LOCKED MTX ******/
mWireProxy = (WireDataProxy *) mProxy;
}
void p3Wire::service_tick()
{
return;
}
int p3Wire::tick()
void p3Wire::notifyChanges(std::vector<RsGxsNotify*>& changes)
{
std::cerr << "p3Wire::tick()";
std::cerr << "p3Wire::notifyChanges() New stuff";
std::cerr << std::endl;
fakeprocessrequests();
return 0;
receiveChanges(changes);
}
bool p3Wire::updated()
{
RsStackMutex stack(mWireMtx); /********** STACK LOCKED MTX ******/
if (mUpdated)
{
mUpdated = false;
return true;
}
return false;
}
/* Data Requests */
bool p3Wire::requestGroupInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list<std::string> &groupIds)
{
generateToken(token);
std::cerr << "p3Wire::requestGroupInfo() gets Token: " << token << std::endl;
storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_GROUPS, groupIds);
return true;
}
bool p3Wire::requestMsgInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list<std::string> &groupIds)
{
generateToken(token);
std::cerr << "p3Wire::requestMsgInfo() gets Token: " << token << std::endl;
storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_MSGS, groupIds);
return true;
}
bool p3Wire::requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list<std::string> &msgIds)
{
generateToken(token);
std::cerr << "p3Wire::requestMsgRelatedInfo() gets Token: " << token << std::endl;
storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_MSGRELATED, msgIds);
return true;
}
/* Generic Lists */
bool p3Wire::getGroupList( const uint32_t &token, std::list<std::string> &groupIds)
{
uint32_t status;
uint32_t reqtype;
uint32_t anstype;
time_t ts;
checkRequestStatus(token, status, reqtype, anstype, ts);
if (anstype != RS_TOKREQ_ANSTYPE_LIST)
{
std::cerr << "p3Wire::getGroupList() ERROR AnsType Wrong" << std::endl;
return false;
}
if (reqtype != GXS_REQUEST_TYPE_GROUPS)
{
std::cerr << "p3Wire::getGroupList() ERROR ReqType Wrong" << std::endl;
return false;
}
if (status != GXS_REQUEST_STATUS_COMPLETE)
{
std::cerr << "p3Wire::getGroupList() ERROR Status Incomplete" << std::endl;
return false;
}
bool ans = loadRequestOutList(token, groupIds);
updateRequestStatus(token, GXS_REQUEST_STATUS_DONE);
return ans;
}
bool p3Wire::getMsgList( const uint32_t &token, std::list<std::string> &msgIds)
{
uint32_t status;
uint32_t reqtype;
uint32_t anstype;
time_t ts;
checkRequestStatus(token, status, reqtype, anstype, ts);
if (anstype != RS_TOKREQ_ANSTYPE_LIST)
{
std::cerr << "p3Wire::getMsgList() ERROR AnsType Wrong" << std::endl;
return false;
}
if ((reqtype != GXS_REQUEST_TYPE_MSGS) && (reqtype != GXS_REQUEST_TYPE_MSGRELATED))
{
std::cerr << "p3Wire::getMsgList() ERROR ReqType Wrong" << std::endl;
return false;
}
if (status != GXS_REQUEST_STATUS_COMPLETE)
{
std::cerr << "p3Wire::getMsgList() ERROR Status Incomplete" << std::endl;
return false;
}
bool ans = loadRequestOutList(token, msgIds);
updateRequestStatus(token, GXS_REQUEST_STATUS_DONE);
return ans;
}
/* Generic Summary */
bool p3Wire::getGroupSummary( const uint32_t &token, std::list<RsGroupMetaData> &groupInfo)
{
uint32_t status;
uint32_t reqtype;
uint32_t anstype;
time_t ts;
checkRequestStatus(token, status, reqtype, anstype, ts);
if (anstype != RS_TOKREQ_ANSTYPE_SUMMARY)
{
std::cerr << "p3Wire::getGroupSummary() ERROR AnsType Wrong" << std::endl;
return false;
}
if (reqtype != GXS_REQUEST_TYPE_GROUPS)
{
std::cerr << "p3Wire::getGroupSummary() ERROR ReqType Wrong" << std::endl;
return false;
}
if (status != GXS_REQUEST_STATUS_COMPLETE)
{
std::cerr << "p3Wire::getGroupSummary() ERROR Status Incomplete" << std::endl;
return false;
}
std::list<std::string> groupIds;
bool ans = loadRequestOutList(token, groupIds);
updateRequestStatus(token, GXS_REQUEST_STATUS_DONE);
/* convert to RsGroupMetaData */
mProxy->getGroupSummary(groupIds, groupInfo);
return ans;
}
bool p3Wire::getMsgSummary( const uint32_t &token, std::list<RsMsgMetaData> &msgInfo)
{
uint32_t status;
uint32_t reqtype;
uint32_t anstype;
time_t ts;
checkRequestStatus(token, status, reqtype, anstype, ts);
if (anstype != RS_TOKREQ_ANSTYPE_SUMMARY)
{
std::cerr << "p3Wire::getMsgSummary() ERROR AnsType Wrong" << std::endl;
return false;
}
if ((reqtype != GXS_REQUEST_TYPE_MSGS) && (reqtype != GXS_REQUEST_TYPE_MSGRELATED))
{
std::cerr << "p3Wire::getMsgSummary() ERROR ReqType Wrong" << std::endl;
return false;
}
if (status != GXS_REQUEST_STATUS_COMPLETE)
{
std::cerr << "p3Wire::getMsgSummary() ERROR Status Incomplete" << std::endl;
return false;
}
std::list<std::string> msgIds;
bool ans = loadRequestOutList(token, msgIds);
updateRequestStatus(token, GXS_REQUEST_STATUS_DONE);
/* convert to RsMsgMetaData */
mProxy->getMsgSummary(msgIds, msgInfo);
return ans;
}
/* Specific Service Data */
bool p3Wire::getGroupData(const uint32_t &token, RsWireGroup &group)
bool p3Wire::getGroupData(const uint32_t &token, std::vector<RsWireGroup> &groups)
{
uint32_t status;
uint32_t reqtype;
uint32_t anstype;
time_t ts;
checkRequestStatus(token, status, reqtype, anstype, ts);
std::cerr << "p3Wire::getGroupData()";
std::cerr << std::endl;
if (anstype != RS_TOKREQ_ANSTYPE_DATA)
std::vector<RsGxsGrpItem*> grpData;
bool ok = RsGenExchange::getGroupData(token, grpData);
if(ok)
{
std::cerr << "p3Wire::getGroupData() ERROR AnsType Wrong" << std::endl;
return false;
std::vector<RsGxsGrpItem*>::iterator vit = grpData.begin();
for(; vit != grpData.end(); vit++)
{
RsGxsWireGroupItem* item = dynamic_cast<RsGxsWireGroupItem*>(*vit);
if (item)
{
RsWireGroup group = item->group;
group.mMeta = item->meta;
delete item;
groups.push_back(group);
std::cerr << "p3Wire::getGroupData() Adding WireGroup to Vector: ";
std::cerr << std::endl;
std::cerr << group;
std::cerr << std::endl;
}
else
{
std::cerr << "Not a WireGroupItem, deleting!" << std::endl;
delete *vit;
}
}
}
return ok;
}
bool p3Wire::getPulseData(const uint32_t &token, std::vector<RsWirePulse> &pulses)
{
GxsMsgDataMap msgData;
bool ok = RsGenExchange::getMsgData(token, msgData);
if (reqtype != GXS_REQUEST_TYPE_GROUPS)
if(ok)
{
std::cerr << "p3Wire::getGroupData() ERROR ReqType Wrong" << std::endl;
return false;
GxsMsgDataMap::iterator mit = msgData.begin();
for(; mit != msgData.end(); mit++)
{
RsGxsGroupId grpId = mit->first;
std::vector<RsGxsMsgItem*>& msgItems = mit->second;
std::vector<RsGxsMsgItem*>::iterator vit = msgItems.begin();
for(; vit != msgItems.end(); vit++)
{
RsGxsWirePulseItem* item = dynamic_cast<RsGxsWirePulseItem*>(*vit);
if(item)
{
RsWirePulse pulse = item->pulse;
pulse.mMeta = item->meta;
pulses.push_back(pulse);
delete item;
}
else
{
std::cerr << "Not a WikiPulse Item, deleting!" << std::endl;
delete *vit;
}
}
}
}
if (status != GXS_REQUEST_STATUS_COMPLETE)
{
std::cerr << "p3Wire::getGroupData() ERROR Status Incomplete" << std::endl;
return false;
}
std::string id;
if (!popRequestOutList(token, id))
{
/* finished */
updateRequestStatus(token, GXS_REQUEST_STATUS_DONE);
return false;
}
/* convert to RsWireGroup */
bool ans = mWireProxy->getGroup(id, group);
return ans;
return ok;
}
bool p3Wire::getMsgData(const uint32_t &token, RsWirePulse &pulse)
bool p3Wire::createGroup(uint32_t &token, RsWireGroup &group)
{
uint32_t status;
uint32_t reqtype;
uint32_t anstype;
time_t ts;
checkRequestStatus(token, status, reqtype, anstype, ts);
RsGxsWireGroupItem* groupItem = new RsGxsWireGroupItem();
groupItem->group = group;
groupItem->meta = group.mMeta;
if (anstype != RS_TOKREQ_ANSTYPE_DATA)
{
std::cerr << "p3Wire::getMsgData() ERROR AnsType Wrong" << std::endl;
return false;
}
if ((reqtype != GXS_REQUEST_TYPE_MSGS) && (reqtype != GXS_REQUEST_TYPE_MSGRELATED))
{
std::cerr << "p3Wire::getMsgData() ERROR ReqType Wrong" << std::endl;
return false;
}
if (status != GXS_REQUEST_STATUS_COMPLETE)
{
std::cerr << "p3Wire::getMsgData() ERROR Status Incomplete" << std::endl;
return false;
}
std::string id;
if (!popRequestOutList(token, id))
{
/* finished */
updateRequestStatus(token, GXS_REQUEST_STATUS_DONE);
return false;
}
/* convert to RsWirePulse */
bool ans = mWireProxy->getPulse(id, pulse);
return ans;
std::cerr << "p3Wire::createGroup(): ";
std::cerr << std::endl;
std::cerr << group;
std::cerr << std::endl;
std::cerr << "p3Wire::createGroup() pushing to RsGenExchange";
std::cerr << std::endl;
RsGenExchange::publishGroup(token, groupItem);
return true;
}
/* Poll */
uint32_t p3Wire::requestStatus(const uint32_t token)
bool p3Wire::createPulse(uint32_t &token, RsWirePulse &pulse)
{
uint32_t status;
uint32_t reqtype;
uint32_t anstype;
time_t ts;
checkRequestStatus(token, status, reqtype, anstype, ts);
std::cerr << "p3Wire::createPulse(): " << pulse;
std::cerr << std::endl;
return status;
RsGxsWirePulseItem* pulseItem = new RsGxsWirePulseItem();
pulseItem->pulse = pulse;
pulseItem->meta = pulse.mMeta;
RsGenExchange::publishMsg(token, pulseItem);
return true;
}
/* Cancel Request */
bool p3Wire::cancelRequest(const uint32_t &token)
std::ostream &operator<<(std::ostream &out, const RsWireGroup &group)
{
return clearRequest(token);
out << "RsWireGroup [ ";
out << " Name: " << group.mMeta.mGroupName;
out << " Desc: " << group.mDescription;
//out << " Category: " << group.mCategory;
out << " ]";
return out;
}
//////////////////////////////////////////////////////////////////////////////
bool p3Wire::setMessageStatus(const std::string &msgId, const uint32_t status, const uint32_t statusMask)
std::ostream &operator<<(std::ostream &out, const RsWirePulse &pulse)
{
return mWireProxy->setMessageStatus(msgId, status, statusMask);
out << "RsWirePulse [ ";
out << "Title: " << pulse.mMeta.mMsgName;
out << "PulseText: " << pulse.mPulseText;
out << "]";
return out;
}
/***** FOR TESTING *****/
bool p3Wire::setGroupStatus(const std::string &groupId, const uint32_t status, const uint32_t statusMask)
{
return mWireProxy->setGroupStatus(groupId, status, statusMask);
}
bool p3Wire::setGroupSubscribeFlags(const std::string &groupId, uint32_t subscribeFlags, uint32_t subscribeMask)
{
return mWireProxy->setGroupSubscribeFlags(groupId, subscribeFlags, subscribeMask);
}
bool p3Wire::setMessageServiceString(const std::string &msgId, const std::string &str)
{
return mWireProxy->setMessageServiceString(msgId, str);
}
bool p3Wire::setGroupServiceString(const std::string &grpId, const std::string &str)
{
return mWireProxy->setGroupServiceString(grpId, str);
}
bool p3Wire::groupRestoreKeys(const std::string &groupId)
{
return false;
}
bool p3Wire::groupShareKeys(const std::string &groupId, std::list<std::string>& peers)
{
return false;
}
/********************************************************************************************/
std::string p3Wire::genRandomId()
{
std::string randomId;
for(int i = 0; i < 20; i++)
{
randomId += (char) ('a' + (RSRandom::random_u32() % 26));
}
return randomId;
}
std::string randomId;
for(int i = 0; i < 20; i++)
{
randomId += (char) ('a' + (RSRandom::random_u32() % 26));
}
bool p3Wire::createGroup(uint32_t &token, RsWireGroup &group, bool isNew)
return randomId;
}
void p3Wire::generateDummyData()
{
if (group.mMeta.mGroupId.empty())
{
/* new photo */
/* generate a temp id */
group.mMeta.mGroupId = genRandomId();
}
else
{
std::cerr << "p3Wire::createGroup() Group with existing Id... dropping";
std::cerr << std::endl;
return false;
}
{
RsStackMutex stack(mWireMtx); /********** STACK LOCKED MTX ******/
mUpdated = true;
mWireProxy->addGroup(group);
}
// Fake a request to return the GroupMetaData.
generateToken(token);
uint32_t ansType = RS_TOKREQ_ANSTYPE_SUMMARY;
RsTokReqOptions opts; // NULL is good.
std::list<std::string> groupIds;
groupIds.push_back(group.mMeta.mGroupId); // It will just return this one.
std::cerr << "p3Wiree::createGroup() Generating Request Token: " << token << std::endl;
storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_GROUPS, groupIds);
return true;
}
bool p3Wire::createPulse(uint32_t &token, RsWirePulse &pulse, bool isNew)
{
if (pulse.mMeta.mGroupId.empty())
{
/* new photo */
std::cerr << "p3Wire::createPulse() Missing PulseID";
std::cerr << std::endl;
return false;
}
/* check if its a mod or new pulse */
if (pulse.mMeta.mOrigMsgId.empty())
{
std::cerr << "p3Wire::createPulse() New Pulse";
std::cerr << std::endl;
/* new pulse, generate a new OrigPulseId */
pulse.mMeta.mOrigMsgId = genRandomId();
pulse.mMeta.mMsgId = pulse.mMeta.mOrigMsgId;
}
else
{
std::cerr << "p3Wire::createPulse() Modified Pulse";
std::cerr << std::endl;
/* mod pulse, keep orig pulse id, generate a new PulseId */
pulse.mMeta.mMsgId = genRandomId();
}
std::cerr << "p3Wire::createPulse() GroupId: " << pulse.mMeta.mGroupId;
std::cerr << std::endl;
std::cerr << "p3Wire::createPulse() PulseId: " << pulse.mMeta.mMsgId;
std::cerr << std::endl;
std::cerr << "p3Wire::createPulse() OrigPulseId: " << pulse.mMeta.mOrigMsgId;
std::cerr << std::endl;
{
RsStackMutex stack(mWireMtx); /********** STACK LOCKED MTX ******/
mUpdated = true;
mWireProxy->addPulse(pulse);
}
// Fake a request to return the MsgMetaData.
generateToken(token);
uint32_t ansType = RS_TOKREQ_ANSTYPE_SUMMARY;
RsTokReqOptions opts; // NULL is good.
std::list<std::string> msgIds;
msgIds.push_back(pulse.mMeta.mMsgId); // It will just return this one.
std::cerr << "p3Wire::createPulse() Generating Request Token: " << token << std::endl;
storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_MSGRELATED, msgIds);
return true;
}
/********************************************************************************************/
bool WireDataProxy::getGroup(const std::string &id, RsWireGroup &group)
{
void *groupData = NULL;
RsGroupMetaData meta;
if (getGroupData(id, groupData) && getGroupSummary(id, meta))
{
RsWireGroup *pG = (RsWireGroup *) groupData;
group = *pG;
// update definitive version of the metadata.
group.mMeta = meta;
std::cerr << "WireDataProxy::getGroup() Id: " << id;
std::cerr << " MetaData: " << meta << " DataPointer: " << groupData;
std::cerr << std::endl;
return true;
}
std::cerr << "WireDataProxy::getGroup() FAILED Id: " << id;
std::cerr << std::endl;
return false;
}
bool WireDataProxy::getPulse(const std::string &id, RsWirePulse &pulse)
{
void *msgData = NULL;
RsMsgMetaData meta;
if (getMsgData(id, msgData) && getMsgSummary(id, meta))
{
RsWirePulse *pP = (RsWirePulse *) msgData;
// Shallow copy of thumbnail.
pulse = *pP;
// update definitive version of the metadata.
pulse.mMeta = meta;
std::cerr << "WireDataProxy::getPulse() Id: " << id;
std::cerr << " MetaData: " << meta << " DataPointer: " << msgData;
std::cerr << std::endl;
return true;
}
std::cerr << "WireDataProxy::getPulse() FAILED Id: " << id;
std::cerr << std::endl;
return false;
}
bool WireDataProxy::addGroup(const RsWireGroup &group)
{
// Make duplicate.
RsWireGroup *pG = new RsWireGroup();
*pG = group;
std::cerr << "WireDataProxy::addGroup()";
std::cerr << " MetaData: " << pG->mMeta << " DataPointer: " << pG;
std::cerr << std::endl;
return createGroup(pG);
}
bool WireDataProxy::addPulse(const RsWirePulse &pulse)
{
// Make duplicate.
RsWirePulse *pP = new RsWirePulse();
*pP = pulse;
std::cerr << "WireDataProxy::addPulse()";
std::cerr << " MetaData: " << pP->mMeta << " DataPointer: " << pP;
std::cerr << std::endl;
return createMsg(pP);
}
/* These Functions must be overloaded to complete the service */
bool WireDataProxy::convertGroupToMetaData(void *groupData, RsGroupMetaData &meta)
{
RsWireGroup *group = (RsWireGroup *) groupData;
meta = group->mMeta;
return true;
}
bool WireDataProxy::convertMsgToMetaData(void *msgData, RsMsgMetaData &meta)
{
RsWirePulse *page = (RsWirePulse *) msgData;
meta = page->mMeta;
return true;
}

View file

@ -1,13 +1,13 @@
/*
* libretroshare/src/services: p3wire.h
*
* Wire interface for RetroShare.
* Wiki interface for RetroShare.
*
* Copyright 2012-2012 by Robert Fernie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2 as published by the Free Software Foundation.
* License Version 2.1 as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@ -26,94 +26,45 @@
#ifndef P3_WIRE_SERVICE_HEADER
#define P3_WIRE_SERVICE_HEADER
#include "services/p3gxsservice.h"
#include "retroshare/rswire.h"
#include "gxs/rsgenexchange.h"
#include <map>
#include <string>
/*
* Wire Service
* Wiki Service
*
*
*/
class WireDataProxy: public GxsDataProxy
class p3Wire: public RsGenExchange, public RsWire
{
public:
public:
p3Wire(RsGeneralDataService* gds, RsNetworkExchangeService* nes);
bool getGroup(const std::string &id, RsWireGroup &group);
bool getPulse(const std::string &id, RsWirePulse &pulse);
protected:
bool addGroup(const RsWireGroup &group);
bool addPulse(const RsWirePulse &pulse);
virtual void notifyChanges(std::vector<RsGxsNotify*>& changes) ;
/* These Functions must be overloaded to complete the service */
virtual bool convertGroupToMetaData(void *groupData, RsGroupMetaData &meta);
virtual bool convertMsgToMetaData(void *msgData, RsMsgMetaData &meta);
};
public:
virtual void service_tick();
class p3Wire: public p3GxsDataService, public RsWire
{
public:
p3Wire(uint16_t type);
virtual int tick();
public:
virtual bool updated();
/* Data Requests */
virtual bool requestGroupInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list<std::string> &groupIds);
virtual bool requestMsgInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list<std::string> &groupIds);
virtual bool requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list<std::string> &msgIds);
/* Generic Lists */
virtual bool getGroupList( const uint32_t &token, std::list<std::string> &groupIds);
virtual bool getMsgList( const uint32_t &token, std::list<std::string> &msgIds);
/* Generic Summary */
virtual bool getGroupSummary( const uint32_t &token, std::list<RsGroupMetaData> &groupInfo);
virtual bool getMsgSummary( const uint32_t &token, std::list<RsMsgMetaData> &msgInfo);
/* Actual Data -> specific to Interface */
/* Specific Service Data */
virtual bool getGroupData(const uint32_t &token, RsWireGroup &group);
virtual bool getMsgData(const uint32_t &token, RsWirePulse &page);
virtual bool getGroupData(const uint32_t &token, std::vector<RsWireGroup> &groups);
virtual bool getPulseData(const uint32_t &token, std::vector<RsWirePulse> &pulses);
/* Poll */
virtual uint32_t requestStatus(const uint32_t token);
/* Cancel Request */
virtual bool cancelRequest(const uint32_t &token);
//////////////////////////////////////////////////////////////////////////////
virtual bool setMessageStatus(const std::string &msgId, const uint32_t status, const uint32_t statusMask);
virtual bool setGroupStatus(const std::string &groupId, const uint32_t status, const uint32_t statusMask);
virtual bool setGroupSubscribeFlags(const std::string &groupId, uint32_t subscribeFlags, uint32_t subscribeMask);
virtual bool setMessageServiceString(const std::string &msgId, const std::string &str);
virtual bool setGroupServiceString(const std::string &grpId, const std::string &str);
virtual bool groupRestoreKeys(const std::string &groupId);
virtual bool groupShareKeys(const std::string &groupId, std::list<std::string>& peers);
virtual bool createGroup(uint32_t &token, RsWireGroup &group, bool isNew);
virtual bool createPulse(uint32_t &token, RsWirePulse &pulse, bool isNew);
virtual bool createGroup(uint32_t &token, RsWireGroup &group);
virtual bool createPulse(uint32_t &token, RsWirePulse &pulse);
private:
virtual void generateDummyData();
std::string genRandomId();
WireDataProxy *mWireProxy;
RsMutex mWireMtx;
/***** below here is locked *****/
bool mUpdated;
};