merging gxs_phase2 branch

git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@6401 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
chrisparker126 2013-06-04 21:00:43 +00:00
parent 1150366913
commit 325fa4f222
116 changed files with 6050 additions and 3596 deletions

View file

@ -65,11 +65,11 @@ RsGxsChannels *rsGxsChannels = NULL;
/********************************************************************************/
p3GxsChannels::p3GxsChannels(RsGeneralDataService *gds, RsNetworkExchangeService *nes, RsGixs* gixs)
: RsGenExchange(gds, nes, new RsGxsChannelSerialiser(), RS_SERVICE_GXSV1_TYPE_CHANNELS, gixs, channelsAuthenPolicy()), RsGxsChannels(this), GxsTokenQueue(this)
: RsGenExchange(gds, nes, new RsGxsChannelSerialiser(), RS_SERVICE_GXSV2_TYPE_CHANNELS, gixs, channelsAuthenPolicy()), RsGxsChannels(this), GxsTokenQueue(this)
{
// For Dummy Msgs.
mGenActive = false;
mCommentService = new p3GxsCommentService(this, RS_SERVICE_GXSV1_TYPE_CHANNELS);
mCommentService = new p3GxsCommentService(this, RS_SERVICE_GXSV2_TYPE_CHANNELS);
RsTickEvent::schedule_in(CHANNEL_PROCESS, 0);
@ -473,6 +473,10 @@ void p3GxsChannels::request_SpecificUnprocessedPosts(std::list<std::pair<RsGxsGr
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA;
// Only Fetch UNPROCESSED messages.
opts.mStatusFilter = GXS_SERV::GXS_MSG_STATUS_UNPROCESSED;
opts.mStatusMask = GXS_SERV::GXS_MSG_STATUS_UNPROCESSED;
uint32_t token = 0;
/* organise Ids how they want them */
@ -500,6 +504,9 @@ void p3GxsChannels::request_GroupUnprocessedPosts(const std::list<RsGxsGroupId>
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA;
// Only Fetch UNPROCESSED messages.
opts.mStatusFilter = GXS_SERV::GXS_MSG_STATUS_UNPROCESSED;
opts.mStatusMask = GXS_SERV::GXS_MSG_STATUS_UNPROCESSED;
uint32_t token = 0;
@ -561,6 +568,8 @@ void p3GxsChannels::handleUnprocessedPost(const RsGxsChannelPost &msg)
{
std::cerr << "p3GxsChannels::handleUnprocessedPost() Msg already Processed";
std::cerr << std::endl;
std::cerr << "p3GxsChannels::handleUnprocessedPost() ERROR - this should not happen";
std::cerr << std::endl;
return;
}

View file

@ -40,6 +40,8 @@
* #define DEBUG_CIRCLES 1
****/
#define DEBUG_CIRCLES 1
RsGxsCircles *rsGxsCircles = NULL;
/******
@ -106,7 +108,7 @@ RsGxsCircles *rsGxsCircles = NULL;
p3GxsCircles::p3GxsCircles(RsGeneralDataService *gds, RsNetworkExchangeService *nes, p3IdService *identities)
: RsGxsCircleExchange(gds, nes, new RsGxsCircleSerialiser(),
RS_SERVICE_GXSV1_TYPE_GXSCIRCLE, identities, circleAuthenPolicy()),
RS_SERVICE_GXSV2_TYPE_GXSCIRCLE, identities, circleAuthenPolicy()),
RsGxsCircles(this), GxsTokenQueue(this), RsTickEvent(), mIdentities(identities),
mCircleMtx("p3GxsCircles"),
mCircleCache(DEFAULT_MEM_CACHE_SIZE, "GxsCircleCache")
@ -163,16 +165,46 @@ void p3GxsCircles::notifyChanges(std::vector<RsGxsNotify *> &changes)
std::cerr << "p3GxsCircles::notifyChanges()";
std::cerr << std::endl;
std::vector<RsGxsNotify *>::iterator it;
for(it = changes.begin(); it != changes.end(); it++)
{
RsGxsGroupChange *groupChange = dynamic_cast<RsGxsGroupChange *>(*it);
RsGxsMsgChange *msgChange = dynamic_cast<RsGxsMsgChange *>(*it);
if (msgChange)
{
std::cerr << "p3GxsCircles::notifyChanges() Found Message Change Notification";
std::cerr << std::endl;
std::map<RsGxsGroupId, std::vector<RsGxsMessageId> > &msgChangeMap = msgChange->msgChangeMap;
std::map<RsGxsGroupId, std::vector<RsGxsMessageId> >::iterator mit;
for(mit = msgChangeMap.begin(); mit != msgChangeMap.end(); mit++)
{
std::cerr << "p3GxsCircles::notifyChanges() Msgs for Group: " << mit->first;
std::cerr << std::endl;
}
}
/* add groups to ExternalIdList (Might get Personal Circles here until NetChecks in place) */
if (groupChange)
{
std::cerr << "p3GxsCircles::notifyChanges() Found Group Change Notification";
std::cerr << std::endl;
std::list<RsGxsGroupId> &groupList = groupChange->mGrpIdList;
std::list<RsGxsGroupId>::iterator git;
for(git = groupList.begin(); git != groupList.end(); git++)
{
std::cerr << "p3GxsCircles::notifyChanges() Incoming Group: " << *git;
std::cerr << std::endl;
// for new circles we need to add them to the list.
RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/
mCircleExternalIdList.push_back(*git);
}
}
}
RsGxsIfaceHelper::receiveChanges(changes);
// for new circles we need to add them to the list.
// TODO.
#if 0
{
RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/
mCircleIdList.push_back(grpItem->meta.mGroupId);
}
#endif
}
@ -180,40 +212,6 @@ void p3GxsCircles::notifyChanges(std::vector<RsGxsNotify *> &changes)
/******************* RsCircles Interface ***************************************/
/********************************************************************************/
void p3GxsCircles::createLocalCircle()
{
return;
}
void p3GxsCircles::addToLocalCircle()
{
return;
}
void p3GxsCircles::removeFromLocalCircle()
{
return;
}
void p3GxsCircles::getLocalCirclePeers()
{
return;
}
void p3GxsCircles::getListOfLocalCircles()
{
return;
}
#if 0
bool p3GxsCircles:: getNickname(const RsGxsId &id, std::string &nickname)
{
return false;
}
#endif
bool p3GxsCircles:: getCircleDetails(const RsGxsCircleId &id, RsGxsCircleDetails &details)
{
@ -231,6 +229,10 @@ bool p3GxsCircles:: getCircleDetails(const RsGxsCircleId &id, RsGxsCircleDetails
// should also have meta data....
details.mCircleId = id;
details.mCircleName = data.mCircleName;
details.mCircleType = data.mCircleType;
details.mIsExternal = data.mIsExternal;
details.mUnknownPeers = data.mUnknownPeers;
details.mAllowedPeers = data.mAllowedPeers;
return true;
@ -244,7 +246,7 @@ bool p3GxsCircles:: getCircleDetails(const RsGxsCircleId &id, RsGxsCircleDetails
}
bool p3GxsCircles:: getCircleIdList(std::list<RsGxsCircleId> &circleIds)
bool p3GxsCircles:: getCirclePersonalIdList(std::list<RsGxsCircleId> &circleIds)
{
#ifdef DEBUG_CIRCLES
std::cerr << "p3GxsCircles::getCircleIdList()";
@ -252,14 +254,50 @@ bool p3GxsCircles:: getCircleIdList(std::list<RsGxsCircleId> &circleIds)
#endif // DEBUG_CIRCLES
RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/
circleIds = mCircleIdList;
if (circleIds.empty())
{
circleIds = mCirclePersonalIdList;
}
else
{
std::list<RsGxsCircleId>::const_iterator it;
for(it = mCirclePersonalIdList.begin(); it != mCirclePersonalIdList.begin(); it++)
{
circleIds.push_back(*it);
}
}
return true;
}
bool p3GxsCircles:: getCircleExternalIdList(std::list<RsGxsCircleId> &circleIds)
{
#ifdef DEBUG_CIRCLES
std::cerr << "p3GxsCircles::getCircleIdList()";
std::cerr << std::endl;
#endif // DEBUG_CIRCLES
RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/
if (circleIds.empty())
{
circleIds = mCircleExternalIdList;
}
else
{
std::list<RsGxsCircleId>::const_iterator it;
for(it = mCircleExternalIdList.begin(); it != mCircleExternalIdList.begin(); it++)
{
circleIds.push_back(*it);
}
}
return true;
}
/********************************************************************************/
/******************* RsGixs Interface ***************************************/
/******************* RsGcxs Interface ***************************************/
/********************************************************************************/
bool p3GxsCircles::isLoaded(const RsGxsCircleId &circleId)
@ -273,7 +311,22 @@ bool p3GxsCircles::loadCircle(const RsGxsCircleId &circleId)
return cache_request_load(circleId);
}
int p3GxsCircles::canSend(const RsGxsCircleId &circleId, const RsPgpId &id)
int p3GxsCircles::canSend(const RsGxsCircleId &circleId, const std::string &id)
{
RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/
if (mCircleCache.is_cached(circleId))
{
RsGxsCircleCache &data = mCircleCache.ref(circleId);
if (data.isAllowedPeer(id))
{
return 1;
}
return 0;
}
return -1;
}
int p3GxsCircles::canReceive(const RsGxsCircleId &circleId, const RsPgpId &id)
{
RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/
if (mCircleCache.is_cached(circleId))
@ -361,18 +414,24 @@ RsGenExchange::ServiceCreate_Return p3GxsCircles::service_CreateGroup(RsGxsGrpIt
}
// Now copy the GroupId into the mCircleId, and set the mode.
// TODO.
#ifdef HAVE_CIRCLE_META_DATA
grpItem->meta.mCircleType = EXTERNAL;
grpItem->meta.mCircleId = grpItem->meta.mGroupId;
if (item->meta.mCircleType == GXS_CIRCLE_TYPE_EXT_SELF)
{
item->meta.mCircleType = GXS_CIRCLE_TYPE_EXTERNAL;
item->meta.mCircleId = item->meta.mGroupId;
}
grpItem->group.mMeta.mCircleType = grpItem->meta.mCircleType;
grpItem->group.mMeta.mCircleId = grpItem->meta.mCircleId;
#endif
{
RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/
mCircleIdList.push_back(grpItem->meta.mGroupId);
if (item->meta.mCircleType == GXS_CIRCLE_TYPE_LOCAL)
{
mCirclePersonalIdList.push_back(item->meta.mGroupId);
}
else
{
mCircleExternalIdList.push_back(item->meta.mGroupId);
}
}
return SERVICE_CREATE_SUCCESS;
@ -390,6 +449,11 @@ RsGenExchange::ServiceCreate_Return p3GxsCircles::service_CreateGroup(RsGxsGrpIt
RsGxsCircleCache::RsGxsCircleCache()
{
mCircleType = GXS_CIRCLE_TYPE_EXTERNAL;
mIsExternal = true;
mUpdateTime = 0;
mGroupStatus = 0;
return;
}
@ -402,6 +466,10 @@ bool RsGxsCircleCache::loadBaseCircle(const RsGxsCircleGroup &circle)
mUpdateTime = time(NULL);
mProcessedCircles.insert(mCircleId);
mCircleType = circle.mMeta.mCircleType;
mIsExternal = (mCircleType != GXS_CIRCLE_TYPE_LOCAL);
mGroupStatus = circle.mMeta.mGroupStatus;
#ifdef DEBUG_CIRCLES
std::cerr << "RsGxsCircleCache::loadBaseCircle(" << mCircleId << ")";
std::cerr << std::endl;
@ -416,9 +484,10 @@ bool RsGxsCircleCache::loadSubCircle(const RsGxsCircleCache &subcircle)
/* should not be any unprocessed circles or peers */
#ifdef DEBUG_CIRCLES
#endif // DEBUG_CIRCLES
std::cerr << "RsGxsCircleCache::loadSubCircle(" << subcircle.mCircleId << ") TODO";
std::cerr << std::endl;
#endif // DEBUG_CIRCLES
return true;
}
@ -452,6 +521,13 @@ bool RsGxsCircleCache::addAllowedPeer(const RsPgpId &pgpId, const RsGxsId &gxsId
}
bool RsGxsCircleCache::addLocalFriend(const RsPgpId &pgpId)
{
/* empty list as no GxsID associated */
std::list<RsGxsId> &gxsList = mAllowedPeers[pgpId];
return true;
}
/************************************************************************************/
/************************************************************************************/
@ -465,9 +541,9 @@ bool p3GxsCircles::request_CircleIdList()
std::cerr << std::endl;
#endif // DEBUG_CIRCLES
uint32_t ansType = RS_TOKREQ_ANSTYPE_LIST;
uint32_t ansType = RS_TOKREQ_ANSTYPE_SUMMARY;
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_GROUP_IDS;
opts.mReqType = GXS_REQUEST_TYPE_GROUP_META;
uint32_t token = 0;
@ -484,20 +560,28 @@ bool p3GxsCircles::load_CircleIdList(uint32_t token)
std::cerr << std::endl;
#endif // DEBUG_CIRCLES
std::list<RsGxsGroupId> groupIds;
bool ok = RsGenExchange::getGroupList(token, groupIds);
std::list<RsGroupMetaData> groups;
bool ok = RsGenExchange::getGroupMeta(token, groups);
if(ok)
{
// Save List
std::list<RsGxsGroupId>::iterator vit;
std::list<RsGroupMetaData>::iterator it;
RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/
mCircleIdList.clear();
mCirclePersonalIdList.clear();
mCircleExternalIdList.clear();
for(vit = groupIds.begin(); vit != groupIds.end(); vit++)
for(it = groups.begin(); it != groups.end(); it++)
{
mCircleIdList.push_back(*vit);
if (it->mCircleType == GXS_CIRCLE_TYPE_LOCAL)
{
mCirclePersonalIdList.push_back(it->mGroupId);
}
else
{
mCircleExternalIdList.push_back(it->mGroupId);
}
}
}
else
@ -751,10 +835,10 @@ bool p3GxsCircles::cache_load_for_token(uint32_t token)
item->convertTo(group);
#ifdef DEBUG_CIRCLES
#endif // DEBUG_CIRCLES
std::cerr << "p3GxsCircles::cache_load_for_token() Loaded Id with Meta: ";
std::cerr << item->meta;
std::cerr << std::endl;
#endif // DEBUG_CIRCLES
RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/
@ -765,6 +849,9 @@ bool p3GxsCircles::cache_load_for_token(uint32_t token)
it = mLoadingCache.find(id);
if (it == mLoadingCache.end())
{
std::cerr << "p3GxsCircles::cache_load_for_token() Load ERROR: ";
std::cerr << item->meta;
std::cerr << std::endl;
// ERROR.
continue;
}
@ -773,84 +860,132 @@ bool p3GxsCircles::cache_load_for_token(uint32_t token)
cache.loadBaseCircle(group);
delete item;
bool isComplete = true;
bool isUnprocessedPeers = false;
std::list<RsGxsId> &peers = group.mInvitedMembers;
std::list<RsGxsId>::const_iterator pit;
// need to trigger the searches.
for(pit = peers.begin(); pit != peers.end(); pit++)
if (cache.mIsExternal)
{
/* check cache */
if (mIdentities->haveKey(*pit))
std::cerr << "p3GxsCircles::cache_load_for_token() Loading External Circle";
std::cerr << std::endl;
std::list<RsGxsId> &peers = group.mInvitedMembers;
std::list<RsGxsId>::const_iterator pit;
// need to trigger the searches.
for(pit = peers.begin(); pit != peers.end(); pit++)
{
/* we can process now! */
RsIdentityDetails details;
if (mIdentities->getIdDetails(*pit, details))
std::cerr << "p3GxsCircles::cache_load_for_token() Invited Member: " << *pit;
std::cerr << std::endl;
/* check cache */
if (mIdentities->haveKey(*pit))
{
if (details.mPgpLinked && details.mPgpKnown)
/* we can process now! */
RsIdentityDetails details;
if (mIdentities->getIdDetails(*pit, details))
{
cache.addAllowedPeer(details.mPgpId, *pit);
if (details.mPgpLinked && details.mPgpKnown)
{
std::cerr << "p3GxsCircles::cache_load_for_token() Is Known -> AllowedPeer: " << *pit;
std::cerr << std::endl;
cache.addAllowedPeer(details.mPgpId, *pit);
}
else
{
std::cerr << "p3GxsCircles::cache_load_for_token() Is Unknown -> UnknownPeer: " << *pit;
std::cerr << std::endl;
cache.mUnknownPeers.insert(*pit);
}
}
else
{
cache.mUnknownPeers.insert(*pit);
std::cerr << "p3GxsCircles::cache_load_for_token() Error no details: " << *pit;
std::cerr << std::endl;
// ERROR.
}
}
else
{
// ERROR.
std::cerr << "p3GxsCircles::cache_load_for_token() Requesting UnprocessedPeer: " << *pit;
std::cerr << std::endl;
std::list<PeerId> peers;
mIdentities->requestKey(*pit, peers);
/* store in to_process queue. */
cache.mUnprocessedPeers.insert(*pit);
isComplete = false;
isUnprocessedPeers = true;
}
}
else
{
/* store in to_process queue. */
cache.mUnprocessedPeers.insert(*pit);
isComplete = false;
isUnprocessedPeers = true;
}
}
#ifdef HANDLE_SUBCIRCLES
#if 0
std::list<RsGxsCircleId> &circles = group.mSubCircles;
std::list<RsGxsCircleId>::const_iterator cit;
for(cit = circles.begin(); cit != circles.end(); cit++)
{
/* if its cached already -> then its complete. */
if (mCircleCache.is_loaded(*cit))
std::list<RsGxsCircleId> &circles = group.mSubCircles;
std::list<RsGxsCircleId>::const_iterator cit;
for(cit = circles.begin(); cit != circles.end(); cit++)
{
RsGxsCircleCache cachedCircle;
if (mCircleCache.fetch(&cit, cachedCircle))
/* if its cached already -> then its complete. */
if (mCircleCache.is_loaded(*cit))
{
/* copy cached circle into circle */
cache.loadSubCircle(cachedCircle);
RsGxsCircleCache cachedCircle;
if (mCircleCache.fetch(&cit, cachedCircle))
{
/* copy cached circle into circle */
cache.loadSubCircle(cachedCircle);
}
else
{
/* error */
continue;
}
}
else
{
/* error */
continue;
/* push into secondary processing queues */
std::list<RsGxsCircleId> &proc_circles = mCacheLoad_SubCircle[*cit];
proc_circles.push_back(id);
subCirclesToLoad.push_back(*cit);
isComplete = false;
isUnprocessedCircles = true;
}
}
else
{
/* push into secondary processing queues */
std::list<RsGxsCircleId> &proc_circles = mCacheLoad_SubCircle[*cit];
proc_circles.push_back(id);
subCirclesToLoad.push_back(*cit);
isComplete = false;
isUnprocessedCircles = true;
}
#endif
#endif
}
#endif
#endif
else
{
std::cerr << "p3GxsCircles::cache_load_for_token() Loading Personal Circle";
std::cerr << std::endl;
// LOCAL Load.
std::list<RsPgpId> &peers = group.mLocalFriends;
std::list<RsPgpId>::const_iterator pit;
// need to trigger the searches.
for(pit = peers.begin(); pit != peers.end(); pit++)
{
std::cerr << "p3GxsCircles::cache_load_for_token() Local Friend: " << *pit;
std::cerr << std::endl;
cache.addLocalFriend(*pit);
}
isComplete = true;
isUnprocessedPeers = false;
}
if (isComplete)
{
checkCircleCacheForAutoSubscribe(cache);
/* move straight into the cache */
mCircleCache.store(id, cache);
mCircleCache.resize();
@ -974,6 +1109,8 @@ bool p3GxsCircles::cache_reloadids(const std::string &circleId)
std::cerr << std::endl;
#endif // DEBUG_CIRCLES
checkCircleCacheForAutoSubscribe(cache);
// Push to Cache.
mCircleCache.store(circleId, cache);
mCircleCache.resize();
@ -992,6 +1129,69 @@ bool p3GxsCircles::cache_reloadids(const std::string &circleId)
}
/* We need to AutoSubscribe if the Circle is relevent to us */
bool p3GxsCircles::checkCircleCacheForAutoSubscribe(RsGxsCircleCache &cache)
{
std::cerr << "p3GxsCircles::checkCircleCacheForAutoSubscribe() : ";
std::cerr << cache.mCircleId;
std::cerr << std::endl;
/* if processed already - ignore */
if (!(cache.mGroupStatus & GXS_SERV::GXS_GRP_STATUS_UNPROCESSED))
{
std::cerr << "p3GxsCircles::checkCircleCacheForAutoSubscribe() : Already Processed";
std::cerr << std::endl;
return false;
}
/* if personal - we created ... is subscribed already */
if (!cache.mIsExternal)
{
std::cerr << "p3GxsCircles::checkCircleCacheForAutoSubscribe() : Personal Circle";
std::cerr << std::endl;
return false;
}
/* if we appear in the group - then autosubscribe, and mark as processed */
std::string ownId = AuthGPG::getAuthGPG()->getGPGOwnId();
std::map<RsPgpId, std::list<RsGxsId> >::iterator it = cache.mAllowedPeers.find(ownId);
if (it != cache.mAllowedPeers.end())
{
/* we are part of this group - subscribe, clear unprocessed flag */
std::cerr << "p3GxsCircles::checkCircleCacheForAutoSubscribe() Found OwnId -> AutoSubscribe!";
std::cerr << std::endl;
uint32_t token, token2;
RsGenExchange::subscribeToGroup(token, cache.mCircleId, true);
RsGenExchange::setGroupStatusFlags(token2, cache.mCircleId, 0, GXS_SERV::GXS_GRP_STATUS_UNPROCESSED);
cache.mGroupStatus ^= GXS_SERV::GXS_GRP_STATUS_UNPROCESSED;
return true;
}
else if (cache.mUnknownPeers.empty())
{
std::cerr << "p3GxsCircles::checkCircleCacheForAutoSubscribe() Know All Peers -> Processed";
std::cerr << std::endl;
/* we know all the peers - we are not part - we can flag as PROCESSED. */
uint32_t token;
RsGenExchange::setGroupStatusFlags(token, cache.mCircleId, 0, GXS_SERV::GXS_GRP_STATUS_UNPROCESSED);
cache.mGroupStatus ^= GXS_SERV::GXS_GRP_STATUS_UNPROCESSED;
}
else
{
std::cerr << "p3GxsCircles::checkCircleCacheForAutoSubscribe() Leaving Unprocessed";
std::cerr << std::endl;
// Don't clear UNPROCESSED - as we might not know all the peers.
// TODO - work out when we flag as PROCESSED.
}
return false;
}
#ifdef HANDLE_SUBCIRCLES
#if 0

View file

@ -106,10 +106,16 @@ class RsGxsCircleCache
bool getAllowedPeersList(std::list<RsPgpId> &friendlist);
bool isAllowedPeer(const RsPgpId &id);
bool addAllowedPeer(const RsPgpId &pgpid, const RsGxsId &gxsId);
bool addLocalFriend(const RsPgpId &pgpid);
RsGxsCircleId mCircleId;
std::string mCircleName;
uint32_t mCircleType;
bool mIsExternal;
uint32_t mGroupStatus;
time_t mUpdateTime;
std::set<RsGxsCircleId> mUnprocessedCircles;
std::set<RsGxsId> mUnprocessedPeers;
@ -121,22 +127,6 @@ class RsGxsCircleCache
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
@ -148,27 +138,21 @@ class p3GxsCircles: public RsGxsCircleExchange, public RsGxsCircles,
/*********** External Interface ***************/
virtual bool getCircleDetails(const RsGxsCircleId &id, RsGxsCircleDetails &details);
virtual bool getCircleIdList(std::list<RsGxsCircleId> &circleIds);
virtual bool getCircleExternalIdList(std::list<RsGxsCircleId> &circleIds);
virtual bool getCirclePersonalIdList(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 int canReceive(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.
@ -206,12 +190,15 @@ class p3GxsCircles: public RsGxsCircleExchange, public RsGxsCircles,
bool cache_load_for_token(uint32_t token);
bool cache_reloadids(const std::string &circleId);
bool checkCircleCacheForAutoSubscribe(RsGxsCircleCache &cache);
p3IdService *mIdentities; // Needed for constructing Circle Info,
RsMutex mCircleMtx; /* Locked Below Here */
std::list<RsGxsCircleId> mCircleIdList;
std::list<RsGxsCircleId> mCircleExternalIdList;
std::list<RsGxsCircleId> mCirclePersonalIdList;
/***** Caching Circle Info, *****/
// initial load queue

View file

@ -72,6 +72,7 @@ RsGxsImage::~RsGxsImage()
RsGxsImage &RsGxsImage::operator=(const RsGxsImage &a)
{
copy(a.mData, a.mSize);
return *this;
}
@ -146,31 +147,6 @@ RsGxsVote::RsGxsVote()
mVoteType = 0;
}
/********************************************************************************/
#define RSGXSCOMMENT_MAX_SERVICE_STRING 16
bool SSGxsComment::load(const std::string &input)
{
//char line[RSGXSCOMMENT_MAX_SERVICE_STRING];
int val;
mVoteValue = 0;
if (1 == sscanf(input.c_str(), "V:%d", &val))
{
mVoteValue = val;
}
return true;
}
std::string SSGxsComment::save() const
{
std::string output;
rs_sprintf(output, "V:%d", mVoteValue);
return output;
}
/********************************************************************************/
/******************* Startup / Tick ******************************************/
/********************************************************************************/
@ -255,10 +231,22 @@ bool p3GxsCommentService::getGxsCommentData(const uint32_t &token, std::vector<R
}
cit->mScore = calculateBestScore(cit->mUpVotes, cit->mDownVotes);
/* convert serviceString -> mHaveVoted */
SSGxsComment ss;
ss.load(cit->mMeta.mServiceString);
cit->mOwnVote = ss.mVoteValue;
/* convert Status -> mHaveVoted */
if (cit->mMeta.mMsgStatus & GXS_SERV::GXS_MSG_STATUS_VOTE_MASK)
{
if (cit->mMeta.mMsgStatus & GXS_SERV::GXS_MSG_STATUS_VOTE_UP)
{
cit->mOwnVote = GXS_VOTE_UP;
}
else
{
cit->mOwnVote = GXS_VOTE_DOWN;
}
}
else
{
cit->mOwnVote = GXS_VOTE_NONE;
}
}
std::cerr << "p3GxsCommentService::getGxsCommentData() Found " << comments.size() << " Comments";
@ -345,10 +333,22 @@ bool p3GxsCommentService::getGxsRelatedComments(const uint32_t &token, std::vect
}
cit->mScore = calculateBestScore(cit->mUpVotes, cit->mDownVotes);
/* convert serviceString -> mHaveVoted */
SSGxsComment ss;
ss.load(cit->mMeta.mServiceString);
cit->mOwnVote = ss.mVoteValue;
/* convert Status -> mHaveVoted */
if (cit->mMeta.mMsgStatus & GXS_SERV::GXS_MSG_STATUS_VOTE_MASK)
{
if (cit->mMeta.mMsgStatus & GXS_SERV::GXS_MSG_STATUS_VOTE_UP)
{
cit->mOwnVote = GXS_VOTE_UP;
}
else
{
cit->mOwnVote = GXS_VOTE_DOWN;
}
}
else
{
cit->mOwnVote = GXS_VOTE_NONE;
}
}
std::cerr << "p3GxsCommentService::getGxsRelatedComments() Found " << comments.size() << " Comments";
@ -392,7 +392,7 @@ double p3GxsCommentService::calculateBestScore(int upVotes, int downVotes)
bool p3GxsCommentService::createGxsComment(uint32_t &token, RsGxsComment &msg)
{
std::cerr << "p3GxsChannels::createGxsComment() GroupId: " << msg.mMeta.mGroupId;
std::cerr << "p3GxsCommentService::createGxsComment() GroupId: " << msg.mMeta.mGroupId;
std::cerr << std::endl;
RsGxsCommentItem* msgItem = new RsGxsCommentItem(mServiceType);
@ -410,34 +410,34 @@ bool p3GxsCommentService::createGxsVote(uint32_t &token, RsGxsVote &vote)
// NOTE Because we cannot do this operation immediately, we create a token,
// and monitor acknowledgeTokenMsg ... to return correct answer.
std::cerr << "p3GxsChannels::createGxsVote() GroupId: " << vote.mMeta.mGroupId;
std::cerr << "p3GxsCommentService::createGxsVote() GroupId: " << vote.mMeta.mGroupId;
std::cerr << std::endl;
/* vote must be associated with another item */
if (vote.mMeta.mThreadId.empty())
{
std::cerr << "p3GxsChannels::createGxsVote() ERROR Missing Required ThreadId";
std::cerr << "p3GxsCommentService::createGxsVote() ERROR Missing Required ThreadId";
std::cerr << std::endl;
return false;
}
if (vote.mMeta.mParentId.empty())
{
std::cerr << "p3GxsChannels::createGxsVote() ERROR Missing Required ParentId";
std::cerr << "p3GxsCommentService::createGxsVote() ERROR Missing Required ParentId";
std::cerr << std::endl;
return false;
}
if (vote.mMeta.mGroupId.empty())
{
std::cerr << "p3GxsChannels::createGxsVote() ERROR Missing Required GroupId";
std::cerr << "p3GxsCommentService::createGxsVote() ERROR Missing Required GroupId";
std::cerr << std::endl;
return false;
}
if (vote.mMeta.mAuthorId.empty())
{
std::cerr << "p3GxsChannels::createGxsVote() ERROR Missing Required AuthorId";
std::cerr << "p3GxsCommentService::createGxsVote() ERROR Missing Required AuthorId";
std::cerr << std::endl;
return false;
}
@ -451,7 +451,7 @@ bool p3GxsCommentService::createGxsVote(uint32_t &token, RsGxsVote &vote)
it = mPendingVotes.find(parentId);
if (it != mPendingVotes.end())
{
std::cerr << "p3GxsChannels::createGxsVote() ERROR Already a pending vote!";
std::cerr << "p3GxsCommentService::createGxsVote() ERROR Already a pending vote!";
std::cerr << std::endl;
return false;
}
@ -519,13 +519,8 @@ void p3GxsCommentService::load_PendingVoteParent(const uint32_t &token)
continue;
}
/* check Vote serviceString */
SSGxsComment ss;
ss.load(meta.mServiceString);
RsGxsVote vote = pit->second.mVote;
if (ss.mVoteValue)
if (meta.mMsgStatus & GXS_SERV::GXS_MSG_STATUS_VOTE_MASK)
{
std::cerr << "p3GxsCommentService::load_PendingVoteParent() ERROR Already Voted";
std::cerr << std::endl;
@ -543,11 +538,17 @@ void p3GxsCommentService::load_PendingVoteParent(const uint32_t &token)
std::cerr << "p3GxsCommentService::load_PendingVoteParent() submitting Vote";
std::cerr << std::endl;
ss.mVoteValue = vote.mVoteType;
std::string servString = ss.save();
uint32_t ss_token;
mExchange->setMsgServiceString(ss_token, parentId, servString);
uint32_t status_token;
if (vote.mVoteType == GXS_VOTE_UP)
{
mExchange->setMsgStatusFlags(status_token, parentId,
GXS_SERV::GXS_MSG_STATUS_VOTE_UP, GXS_SERV::GXS_MSG_STATUS_VOTE_MASK);
}
else
{
mExchange->setMsgStatusFlags(status_token, parentId,
GXS_SERV::GXS_MSG_STATUS_VOTE_DOWN, GXS_SERV::GXS_MSG_STATUS_VOTE_MASK);
}
uint32_t vote_token;
castVote(vote_token, vote);
@ -563,7 +564,7 @@ void p3GxsCommentService::load_PendingVoteParent(const uint32_t &token)
void p3GxsCommentService::completeInternalVote(uint32_t &token)
{
std::cerr << "p3GxsChannels::completeInternalVote() token: " << token;
std::cerr << "p3GxsCommentService::completeInternalVote() token: " << token;
std::cerr << std::endl;
std::map<RsGxsGrpMsgIdPair, VoteHolder>::iterator it;
for (it = mPendingVotes.begin(); it != mPendingVotes.end(); it++)
@ -574,7 +575,7 @@ void p3GxsCommentService::completeInternalVote(uint32_t &token)
uint32_t status = mExchange->getTokenService()->requestStatus(token);
mExchange->updatePublicRequestStatus(it->second.mReqToken, status);
std::cerr << "p3GxsChannels::completeInternalVote() Matched to PendingVote. status: " << status;
std::cerr << "p3GxsCommentService::completeInternalVote() Matched to PendingVote. status: " << status;
std::cerr << std::endl;
it->second.mStatus = VoteHolder::VOTE_READY;
@ -582,7 +583,7 @@ void p3GxsCommentService::completeInternalVote(uint32_t &token)
}
}
std::cerr << "p3GxsChannels::completeInternalVote() ERROR Failed to match PendingVote";
std::cerr << "p3GxsCommentService::completeInternalVote() ERROR Failed to match PendingVote";
std::cerr << std::endl;
return;
@ -591,7 +592,7 @@ void p3GxsCommentService::completeInternalVote(uint32_t &token)
bool p3GxsCommentService::acknowledgeVote(const uint32_t& token, RsGxsGrpMsgIdPair& msgId)
{
std::cerr << "p3GxsChannels::acknowledgeVote() token: " << token;
std::cerr << "p3GxsCommentService::acknowledgeVote() token: " << token;
std::cerr << std::endl;
std::map<RsGxsGrpMsgIdPair, VoteHolder>::iterator it;
@ -599,13 +600,13 @@ bool p3GxsCommentService::acknowledgeVote(const uint32_t& token, RsGxsGrpMsgIdPa
{
if (it->second.mReqToken == token)
{
std::cerr << "p3GxsChannels::acknowledgeVote() Matched to PendingVote";
std::cerr << "p3GxsCommentService::acknowledgeVote() Matched to PendingVote";
std::cerr << std::endl;
bool ans = false;
if (it->second.mStatus == VoteHolder::VOTE_READY)
{
std::cerr << "p3GxsChannels::acknowledgeVote() PendingVote = READY";
std::cerr << "p3GxsCommentService::acknowledgeVote() PendingVote = READY";
std::cerr << std::endl;
// Finally finish this Vote off.
@ -613,16 +614,16 @@ bool p3GxsCommentService::acknowledgeVote(const uint32_t& token, RsGxsGrpMsgIdPa
}
else if (it->second.mStatus == VoteHolder::VOTE_ERROR)
{
std::cerr << "p3GxsChannels::acknowledgeVote() PendingVote = ERROR ???";
std::cerr << "p3GxsCommentService::acknowledgeVote() PendingVote = ERROR ???";
std::cerr << std::endl;
}
else
{
std::cerr << "p3GxsChannels::acknowledgeVote() PendingVote = OTHER STATUS";
std::cerr << "p3GxsCommentService::acknowledgeVote() PendingVote = OTHER STATUS";
std::cerr << std::endl;
}
std::cerr << "p3GxsChannels::acknowledgeVote() cleanup token & PendingVote";
std::cerr << "p3GxsCommentService::acknowledgeVote() cleanup token & PendingVote";
std::cerr << std::endl;
mExchange->disposeOfPublicToken(it->second.mReqToken);
mPendingVotes.erase(it);
@ -631,7 +632,7 @@ bool p3GxsCommentService::acknowledgeVote(const uint32_t& token, RsGxsGrpMsgIdPa
}
}
std::cerr << "p3GxsChannels::acknowledgeVote() Failed to match PendingVote";
std::cerr << "p3GxsCommentService::acknowledgeVote() Failed to match PendingVote";
std::cerr << std::endl;
return false;
@ -669,7 +670,7 @@ void p3GxsCommentService::handleResponse(uint32_t token, uint32_t req_type)
bool p3GxsCommentService::castVote(uint32_t &token, RsGxsVote &msg)
{
std::cerr << "p3GxsChannels::castVote() GroupId: " << msg.mMeta.mGroupId;
std::cerr << "p3GxsCommentService::castVote() GroupId: " << msg.mMeta.mGroupId;
std::cerr << std::endl;
RsGxsVoteItem* msgItem = new RsGxsVoteItem(mServiceType);

View file

@ -57,23 +57,6 @@ class VoteHolder
uint32_t mStatus;
};
// NOTE this ServiceString class must be compatible with other classes
// that use ServiceString... i.e. it should scan to string for {V:%d }
// and remember the rest of the string - so it can maintain other settings.
// TODO.
class SSGxsComment
{
public:
SSGxsComment(): mVoteValue(0) { return; }
bool load(const std::string &input);
std::string save() const;
std::string mPreString;
std::string mPostString;
uint32_t mVoteValue;
};
class p3GxsCommentService: public GxsTokenQueue
{

View file

@ -51,7 +51,7 @@ RsGxsForums *rsGxsForums = NULL;
/********************************************************************************/
p3GxsForums::p3GxsForums(RsGeneralDataService *gds, RsNetworkExchangeService *nes, RsGixs* gixs)
: RsGenExchange(gds, nes, new RsGxsForumSerialiser(), RS_SERVICE_GXSV1_TYPE_FORUMS, gixs, forumsAuthenPolicy()), RsGxsForums(this)
: RsGenExchange(gds, nes, new RsGxsForumSerialiser(), RS_SERVICE_GXSV2_TYPE_FORUMS, gixs, forumsAuthenPolicy()), RsGxsForums(this)
{
// For Dummy Msgs.
mGenActive = false;

View file

@ -124,7 +124,7 @@ RsIdentity *rsIdentity = NULL;
/********************************************************************************/
p3IdService::p3IdService(RsGeneralDataService *gds, RsNetworkExchangeService *nes)
: RsGxsIdExchange(gds, nes, new RsGxsIdSerialiser(), RS_SERVICE_GXSV1_TYPE_GXSID, idAuthenPolicy()),
: RsGxsIdExchange(gds, nes, new RsGxsIdSerialiser(), RS_SERVICE_GXSV2_TYPE_GXSID, idAuthenPolicy()),
RsIdentity(this), GxsTokenQueue(this), RsTickEvent(), mIdMtx("p3IdService"),
mPublicKeyCache(DEFAULT_MEM_CACHE_SIZE, "GxsIdPublicKeyCache"),
mPrivateKeyCache(DEFAULT_MEM_CACHE_SIZE, "GxsIdPrivateKeyCache")
@ -205,7 +205,7 @@ void p3IdService::notifyChanges(std::vector<RsGxsNotify *> &changes)
/* shouldn't need to worry about groups - as they need to be subscribed to */
if (groupChange)
{
std::cerr << "p3IdService::notifyChanges() Found Message Change Notification";
std::cerr << "p3IdService::notifyChanges() Found Group Change Notification";
std::cerr << std::endl;
std::list<RsGxsGroupId> &groupList = groupChange->mGrpIdList;
@ -360,8 +360,33 @@ int p3IdService::getPrivateKey(const RsGxsId &id, RsTlvSecurityKey &key)
/******************* RsGixsReputation ***************************************/
/********************************************************************************/
bool p3IdService::getReputation(const RsGxsId &id, const GixsReputation &rep)
bool p3IdService::haveReputation(const RsGxsId &id)
{
return haveKey(id);
}
bool p3IdService::loadReputation(const RsGxsId &id)
{
if (haveKey(id))
return true;
return cache_request_load(id);
}
bool p3IdService::getReputation(const RsGxsId &id, GixsReputation &rep)
{
/* this is the key part for accepting messages */
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
RsGxsIdCache data;
if (mPublicKeyCache.fetch(id, data))
{
rep.id = id;
// Score > 0 is okay.
// Will extract score from Cache Info.
// For the moment just return positive number.
rep.score = 10;
return true;
}
return false;
}
@ -2107,12 +2132,9 @@ std::string rsIdTypeToString(uint32_t idtype)
* that we don't block at all. This should be in a background thread.
* Perhaps a generic method to handle this will be advisable.... but we do that later.
*
* To start with we will work from the Posted service.
*
*
*
* So Reputation....
* Three components:
* 4 components:
* 1) Your Opinion: Should override everything else.
* 2) Implicit Factors: Know the associated GPG Key.
* 3) Your Friends Opinions:
@ -2157,6 +2179,56 @@ std::string rsIdTypeToString(uint32_t idtype)
*
*/
/************************************************************************************/
/*
* Scoring system.
* -100 to 100 is expected range.
*
*
* Each Lobby has a publish threshold.
* - As part of Lobby definition. ???
* - Locally Set.
*
* Threshold:
* 50 VIP List.
* 20 Dress Code
* 10 Limit Riffraff.
* 0 Accept All.
*
* Implicit Scores:
* +50 for known PGP
* +10 for unknown PGP (want to encourage usage).
* +5 for Anon ID.
*
* Own Scores:
* +1000 Accepted
* +50 Friend
* +10 Interesting
* 0 Mostly Harmless
* -10 Annoying.
* -50 Troll
* -1000 Total Banned
*
*
*
Processing Algorithm:
* - Grab all Groups which have received messages.
* (opt 1)-> grab latest msgs for each of these and process => score.
* (opt 2)-> try incremental system (people probably won't change opinions often -> just set them once)
* --> if not possible, fallback to full calculation.
*
*
*/
bool p3IdService::reputation_start()
{
if (!CacheArbitration(BG_REPUTATION))
@ -2891,3 +2963,65 @@ void p3IdService::handle_event(uint32_t event_type, const std::string &elabel)
/***** Conversion fns for RsGxsIdOpinion ****************/
#define REP_OFFSET 10000
#define REP_RANGE 1000
int limitRep(int ans)
{
if (ans < -REP_RANGE)
{
ans = -REP_RANGE;
}
if (ans > REP_RANGE)
{
ans = REP_RANGE;
}
return ans;
}
int convertRepToInt(uint32_t rep)
{
if (rep == 0)
{
return 0;
}
return limitRep(rep - REP_OFFSET);
}
uint32_t convertRepToUint32(int rep)
{
return limitRep(rep) + REP_OFFSET;
}
int RsGxsIdOpinion::getOpinion()
{
return convertRepToInt(mOpinion);
}
int RsGxsIdOpinion::setOpinion(int op)
{
mOpinion = convertRepToUint32(op);
return op;
}
int RsGxsIdOpinion::getReputation()
{
return convertRepToInt(mReputation);
}
int RsGxsIdOpinion::setReputation(int op)
{
mReputation = convertRepToUint32(op);
return op;
}

View file

@ -171,9 +171,9 @@ static uint32_t idAuthenPolicy();
// These are exposed via RsIdentity.
virtual bool getGroupData(const uint32_t &token, std::vector<RsGxsIdGroup> &groups);
virtual bool getMsgData(const uint32_t &token, std::vector<RsGxsIdOpinion> &opinions);
// 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);
@ -218,7 +218,9 @@ virtual int getPrivateKey(const RsGxsId &id, RsTlvSecurityKey &key);
*/
// get Reputation.
virtual bool getReputation(const RsGxsId &id, const GixsReputation &rep);
virtual bool haveReputation(const RsGxsId &id);
virtual bool loadReputation(const RsGxsId &id);
virtual bool getReputation(const RsGxsId &id, GixsReputation &rep);
protected:

View file

@ -87,7 +87,7 @@ std::ostream &operator<<(std::ostream &out, const RsPhotoAlbum &album)
}
p3PhotoService::p3PhotoService(RsGeneralDataService* gds, RsNetworkExchangeService* nes, RsGixs* gixs)
: RsGenExchange(gds, nes, new RsGxsPhotoSerialiser(), RS_SERVICE_GXSV1_TYPE_PHOTO, gixs, photoAuthenPolicy()),
: RsGenExchange(gds, nes, new RsGxsPhotoSerialiser(), RS_SERVICE_GXSV2_TYPE_PHOTO, gixs, photoAuthenPolicy()),
mPhotoMutex(std::string("Photo Mutex"))
{
}

View file

@ -31,6 +31,7 @@
#include "retroshare/rsgxsflags.h"
#include <stdio.h>
#include <math.h>
// For Dummy Msgs.
#include "util/rsrandom.h"
@ -43,26 +44,38 @@
RsPosted *rsPosted = NULL;
const uint32_t RsPosted::FLAG_MSGTYPE_POST = 0x0001;
const uint32_t RsPosted::FLAG_MSGTYPE_MASK = 0x000f;
//const uint32_t RsPosted::FLAG_MSGTYPE_POST = 0x0001;
//const uint32_t RsPosted::FLAG_MSGTYPE_MASK = 0x000f;
#define POSTED_TESTEVENT_DUMMYDATA 0x0001
#define DUMMYDATA_PERIOD 60 // long enough for some RsIdentities to be generated.
#define POSTED_BACKGROUND_PROCESSING 0x0002
#define PROCESSING_START_PERIOD 30
#define PROCESSING_INC_PERIOD 15
#define POSTED_ALL_GROUPS 0x0011
#define POSTED_UNPROCESSED_MSGS 0x0012
#define POSTED_ALL_MSGS 0x0013
#define POSTED_BG_POST_META 0x0014
/********************************************************************************/
/******************* Startup / Tick ******************************************/
/********************************************************************************/
p3Posted::p3Posted(RsGeneralDataService *gds, RsNetworkExchangeService *nes, RsGixs* gixs)
: RsGenExchange(gds, nes, new RsGxsPostedSerialiser(), RS_SERVICE_GXSV1_TYPE_POSTED, gixs, postedAuthenPolicy()), RsPosted(this)
: RsGenExchange(gds, nes, new RsGxsPostedSerialiser(), RS_SERVICE_GXSV2_TYPE_POSTED, gixs, postedAuthenPolicy()), RsPosted(this), GxsTokenQueue(this), RsTickEvent(), mPostedMtx("PostedMtx")
{
mBgProcessing = false;
// For Dummy Msgs.
mGenActive = false;
mCommentService = new p3GxsCommentService(this, RS_SERVICE_GXSV1_TYPE_POSTED);
mCommentService = new p3GxsCommentService(this, RS_SERVICE_GXSV2_TYPE_POSTED);
// Test Data disabled in repo.
//RsTickEvent::schedule_in(POSTED_TESTEVENT_DUMMYDATA, DUMMYDATA_PERIOD);
RsTickEvent::schedule_in(POSTED_BACKGROUND_PROCESSING, PROCESSING_START_PERIOD);
}
@ -91,13 +104,63 @@ uint32_t p3Posted::postedAuthenPolicy()
void p3Posted::notifyChanges(std::vector<RsGxsNotify *> &changes)
{
RsGxsIfaceHelper::receiveChanges(changes);
std::cerr << "p3Posted::notifyChanges()";
std::cerr << std::endl;
std::vector<RsGxsNotify *> changesForGUI;
std::vector<RsGxsNotify *>::iterator it;
for(it = changes.begin(); it != changes.end(); it++)
{
RsGxsGroupChange *groupChange = dynamic_cast<RsGxsGroupChange *>(*it);
RsGxsMsgChange *msgChange = dynamic_cast<RsGxsMsgChange *>(*it);
if (msgChange)
{
std::cerr << "p3Posted::notifyChanges() Found Message Change Notification";
std::cerr << std::endl;
std::map<RsGxsGroupId, std::vector<RsGxsMessageId> > &msgChangeMap = msgChange->msgChangeMap;
std::map<RsGxsGroupId, std::vector<RsGxsMessageId> >::iterator mit;
for(mit = msgChangeMap.begin(); mit != msgChangeMap.end(); mit++)
{
std::cerr << "p3Posted::notifyChanges() Msgs for Group: " << mit->first;
std::cerr << std::endl;
// To start with we are just going to trigger updates on these groups.
// FUTURE OPTIMISATION.
// It could be taken a step further and directly request these msgs for an update.
addGroupForProcessing(mit->first);
}
delete msgChange;
}
/* pass on Group Changes to GUI */
if (groupChange)
{
std::cerr << "p3Posted::notifyChanges() Found Group Change Notification";
std::cerr << std::endl;
std::list<RsGxsGroupId> &groupList = groupChange->mGrpIdList;
std::list<RsGxsGroupId>::iterator git;
for(git = groupList.begin(); git != groupList.end(); git++)
{
std::cerr << "p3Posted::notifyChanges() Incoming Group: " << *git;
std::cerr << std::endl;
}
changesForGUI.push_back(groupChange);
}
}
changes.clear();
RsGxsIfaceHelper::receiveChanges(changesForGUI);
std::cerr << "p3Posted::notifyChanges() -> receiveChanges()";
std::cerr << std::endl;
}
void p3Posted::service_tick()
{
dummy_tick();
RsTickEvent::tick_events();
GxsTokenQueue::checkRequests();
mCommentService->comment_tick();
@ -130,6 +193,7 @@ bool p3Posted::getPostData(const uint32_t &token, std::vector<RsPostedPost> &msg
{
GxsMsgDataMap msgData;
bool ok = RsGenExchange::getMsgData(token, msgData);
time_t now = time(NULL);
if(ok)
{
@ -149,6 +213,8 @@ bool p3Posted::getPostData(const uint32_t &token, std::vector<RsPostedPost> &msg
{
RsPostedPost msg = item->mPost;
msg.mMeta = item->meta;
msg.calculateScores(now);
msgs.push_back(msg);
delete item;
}
@ -169,6 +235,7 @@ bool p3Posted::getRelatedPosts(const uint32_t &token, std::vector<RsPostedPost>
{
GxsMsgRelatedDataMap msgData;
bool ok = RsGenExchange::getMsgRelatedData(token, msgData);
time_t now = time(NULL);
if(ok)
{
@ -187,6 +254,8 @@ bool p3Posted::getRelatedPosts(const uint32_t &token, std::vector<RsPostedPost>
{
RsPostedPost msg = item->mPost;
msg.mMeta = item->meta;
msg.calculateScores(now);
msgs.push_back(msg);
delete item;
}
@ -207,50 +276,47 @@ bool p3Posted::getRelatedPosts(const uint32_t &token, std::vector<RsPostedPost>
/********************************************************************************************/
/********************************************************************************************/
bool p3Posted::requestPostRankings(uint32_t &token, const RankType &rType, uint32_t count, uint32_t page_no, const RsGxsGroupId &groupId)
/* Switched from having explicit Ranking calculations to calculating the set of scores
* on each RsPostedPost item.
*
* TODO: move this function to be part of RsPostedPost - then the GUI
* can reuse is as necessary.
*
*/
bool RsPostedPost::calculateScores(time_t ref_time)
{
std::cerr << "p3Posted::requestPostRankings() doing boring call for now";
std::cerr << std::endl;
/* so we want to calculate all the scores for this Post. */
/* turn it into a boring Post Request for the moment */
std::list<RsGxsGroupId> groups;
groups.push_back(groupId);
PostStats stats;
extractPostedCache(mMeta.mServiceString, stats);
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA;
opts.mMsgFlagFilter = RsPosted::FLAG_MSGTYPE_POST;
opts.mMsgFlagMask = RsPosted::FLAG_MSGTYPE_MASK;
opts.mOptions = RS_TOKREQOPT_MSG_LATEST | RS_TOKREQOPT_MSG_THREAD;
mUpVotes = stats.up_votes;
mDownVotes = stats.down_votes;
mComments = stats.comments;
mHaveVoted = (mMeta.mMsgStatus & GXS_SERV::GXS_MSG_STATUS_VOTE_MASK);
RsGenExchange::getTokenService()->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, groups);
time_t age_secs = ref_time - mMeta.mPublishTs;
#define POSTED_AGESHIFT (2.0)
#define POSTED_AGEFACTOR (3600.0)
mTopScore = ((int) mUpVotes - (int) mDownVotes);
if (mTopScore > 0)
{
// score drops with time.
mHotScore = mTopScore / pow(POSTED_AGESHIFT + age_secs / POSTED_AGEFACTOR, 1.5);
}
else
{
// gets more negative with time.
mHotScore = mTopScore * pow(POSTED_AGESHIFT + age_secs / POSTED_AGEFACTOR, 1.5);
}
mNewScore = -age_secs;
/* what this should be doing ...
* - Grab Public Token.
* Trigger search for Post MetaData.
* Score & Sort MetaData.
* get Final list.
* retrieve PostData.
*/
return true;
}
bool p3Posted::getPostRanking(const uint32_t &token, std::vector<RsPostedPost> &msgs)
{
std::cerr << "p3Posted::getPostRanking() doing boring call for now";
std::cerr << std::endl;
/* for the moment - this just returns the posts */
return getPostData(token, msgs);
}
/********************************************************************************************/
/********************************************************************************************/
/********************************************************************************************/
@ -298,6 +364,10 @@ void p3Posted::setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& ms
}
/********************************************************************************************/
/********************************************************************************************/
@ -481,7 +551,7 @@ bool p3Posted::generatePost(uint32_t &token, const RsGxsGroupId &grpId)
rsIdentity->getOwnIds(ownIds);
uint32_t idx = (uint32_t) (ownIds.size() * RSRandom::random_f32());
int i = 0;
uint32_t i = 0;
for(it = ownIds.begin(); (it != ownIds.end()) && (i < idx); it++, i++);
if (it != ownIds.end())
@ -526,7 +596,7 @@ bool p3Posted::generateComment(uint32_t &token, const RsGxsGroupId &grpId, const
rsIdentity->getOwnIds(ownIds);
uint32_t idx = (uint32_t) (ownIds.size() * RSRandom::random_f32());
int i = 0;
uint32_t i = 0;
for(it = ownIds.begin(); (it != ownIds.end()) && (i < idx); it++, i++);
if (it != ownIds.end())
@ -560,7 +630,7 @@ bool p3Posted::generateGroup(uint32_t &token, std::string groupName)
// Overloaded from RsTickEvent for Event callbacks.
void p3Posted::handle_event(uint32_t event_type, const std::string &elabel)
void p3Posted::handle_event(uint32_t event_type, const std::string & /* elabel */)
{
std::cerr << "p3Posted::handle_event(" << event_type << ")";
std::cerr << std::endl;
@ -572,6 +642,10 @@ void p3Posted::handle_event(uint32_t event_type, const std::string &elabel)
generateDummyData();
break;
case POSTED_BACKGROUND_PROCESSING:
background_tick();
break;
default:
/* error */
std::cerr << "p3Posted::handle_event() Unknown Event Type: " << event_type;
@ -580,3 +654,539 @@ void p3Posted::handle_event(uint32_t event_type, const std::string &elabel)
}
}
/*********************************************************************************
* Background Calculations.
*
* Get list of change groups from Notify....
* this doesn't imclude your own submissions (at this point).
* So they will not be processed until someone else changes something.
* TODO FIX: Must push for that change.
*
* Eventually, we should just be able to get the new messages from Notify,
* and only process them!
*/
void p3Posted::background_tick()
{
#if 0
{
RsStackMutex stack(mPostedMtx); /********** STACK LOCKED MTX ******/
if (mBgGroupList.empty())
{
background_requestAllGroups();
}
}
#endif
background_requestUnprocessedGroup();
RsTickEvent::schedule_in(POSTED_BACKGROUND_PROCESSING, PROCESSING_INC_PERIOD);
}
bool p3Posted::background_requestAllGroups()
{
std::cerr << "p3Posted::background_requestAllGroups()";
std::cerr << std::endl;
uint32_t ansType = RS_TOKREQ_ANSTYPE_LIST;
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_GROUP_IDS;
uint32_t token = 0;
RsGenExchange::getTokenService()->requestGroupInfo(token, ansType, opts);
GxsTokenQueue::queueRequest(token, POSTED_ALL_GROUPS);
return true;
}
void p3Posted::background_loadGroups(const uint32_t &token)
{
/* get messages */
std::cerr << "p3Posted::background_loadGroups()";
std::cerr << std::endl;
std::list<RsGxsGroupId> groupList;
bool ok = RsGenExchange::getGroupList(token, groupList);
if (!ok)
{
return;
}
std::list<RsGxsGroupId>::iterator it;
for(it = groupList.begin(); it != groupList.end(); it++)
{
addGroupForProcessing(*it);
}
}
void p3Posted::addGroupForProcessing(RsGxsGroupId grpId)
{
#ifdef POSTED_DEBUG
std::cerr << "p3Posted::addGroupForProcessing(" << grpId << ")";
std::cerr << std::endl;
#endif // POSTED_DEBUG
{
RsStackMutex stack(mPostedMtx); /********** STACK LOCKED MTX ******/
// no point having multiple lookups queued.
if (mBgGroupList.end() == std::find(mBgGroupList.begin(),
mBgGroupList.end(), grpId))
{
mBgGroupList.push_back(grpId);
}
}
}
void p3Posted::background_requestUnprocessedGroup()
{
#ifdef POSTED_DEBUG
std::cerr << "p3Posted::background_requestUnprocessedGroup()";
std::cerr << std::endl;
#endif // POSTED_DEBUG
RsGxsGroupId grpId;
{
RsStackMutex stack(mPostedMtx); /********** STACK LOCKED MTX ******/
if (mBgProcessing)
{
std::cerr << "p3Posted::background_requestUnprocessedGroup() Already Active";
std::cerr << std::endl;
return;
}
if (mBgGroupList.empty())
{
std::cerr << "p3Posted::background_requestUnprocessedGroup() No Groups to Process";
std::cerr << std::endl;
return;
}
grpId = mBgGroupList.front();
mBgGroupList.pop_front();
mBgProcessing = true;
}
background_requestGroupMsgs(grpId, true);
}
void p3Posted::background_requestGroupMsgs(const RsGxsGroupId &grpId, bool unprocessedOnly)
{
std::cerr << "p3Posted::background_requestGroupMsgs() id: " << grpId;
std::cerr << std::endl;
uint32_t ansType = RS_TOKREQ_ANSTYPE_DATA;
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA;
if (unprocessedOnly)
{
opts.mStatusFilter = GXS_SERV::GXS_MSG_STATUS_UNPROCESSED;
opts.mStatusMask = GXS_SERV::GXS_MSG_STATUS_UNPROCESSED;
}
std::list<RsGxsGroupId> grouplist;
grouplist.push_back(grpId);
uint32_t token = 0;
RsGenExchange::getTokenService()->requestMsgInfo(token, ansType, opts, grouplist);
if (unprocessedOnly)
{
GxsTokenQueue::queueRequest(token, POSTED_UNPROCESSED_MSGS);
}
else
{
GxsTokenQueue::queueRequest(token, POSTED_ALL_MSGS);
}
}
void p3Posted::background_loadUnprocessedMsgs(const uint32_t &token)
{
background_loadMsgs(token, true);
}
void p3Posted::background_loadAllMsgs(const uint32_t &token)
{
background_loadMsgs(token, false);
}
/* This function is generalised to support any collection of messages, across multiple groups */
void p3Posted::background_loadMsgs(const uint32_t &token, bool unprocessed)
{
/* get messages */
std::cerr << "p3Posted::background_loadMsgs()";
std::cerr << std::endl;
std::map<RsGxsGroupId, std::vector<RsGxsMsgItem*> > msgData;
bool ok = RsGenExchange::getMsgData(token, msgData);
if (!ok)
{
std::cerr << "p3Posted::background_loadMsgs() Failed to getMsgData()";
std::cerr << std::endl;
/* cleanup */
background_cleanup();
return;
}
{
RsStackMutex stack(mPostedMtx); /********** STACK LOCKED MTX ******/
mBgStatsMap.clear();
mBgIncremental = unprocessed;
}
std::map<RsGxsGroupId, std::vector<RsGxsMessageId> > postMap;
// generate vector of changes to push to the GUI.
std::vector<RsGxsNotify *> changes;
RsGxsMsgChange *msgChanges = new RsGxsMsgChange(RsGxsNotify::TYPE_PROCESSED);
RsGxsGroupId groupId;
std::map<RsGxsGroupId, std::vector<RsGxsMsgItem*> >::iterator mit;
std::vector<RsGxsMsgItem*>::iterator vit;
for (mit = msgData.begin(); mit != msgData.end(); mit++)
{
groupId = mit->first;
for (vit = mit->second.begin(); vit != mit->second.end(); vit++)
{
RsGxsMessageId parentId = (*vit)->meta.mParentId;
RsGxsMessageId threadId = (*vit)->meta.mThreadId;
bool inc_counters = false;
uint32_t vote_up_inc = 0;
uint32_t vote_down_inc = 0;
uint32_t comment_inc = 0;
bool add_voter = false;
RsGxsId voterId;
RsGxsCommentItem *commentItem;
RsGxsVoteItem *voteItem;
/* THIS Should be handled by UNPROCESSED Filter - but isn't */
if (!IS_MSG_UNPROCESSED((*vit)->meta.mMsgStatus))
{
RsStackMutex stack(mPostedMtx); /********** STACK LOCKED MTX ******/
if (mBgIncremental)
{
std::cerr << "p3Posted::background_loadMsgs() Msg already Processed - Skipping";
std::cerr << std::endl;
std::cerr << "p3Posted::background_loadMsgs() ERROR This should not happen";
std::cerr << std::endl;
continue;
}
}
/* 3 types expected: PostedPost, Comment and Vote */
if (parentId.empty())
{
/* we don't care about top-level (Posts) */
std::cerr << "\tIgnoring TopLevel Item";
std::cerr << std::endl;
/* but we need to notify GUI about them */
msgChanges->msgChangeMap[mit->first].push_back((*vit)->meta.mMsgId);
}
else if (NULL != (commentItem = dynamic_cast<RsGxsCommentItem *>(*vit)))
{
/* comment - want all */
/* Comments are counted by Thread Id */
std::cerr << "\tProcessing Comment: " << commentItem;
std::cerr << std::endl;
inc_counters = true;
comment_inc = 1;
}
else if (NULL != (voteItem = dynamic_cast<RsGxsVoteItem *>(*vit)))
{
/* vote - only care about direct children */
if (parentId == threadId)
{
/* Votes are organised by Parent Id,
* ie. you can vote for both Posts and Comments
*/
std::cerr << "\tProcessing Vote: " << voteItem;
std::cerr << std::endl;
inc_counters = true;
add_voter = true;
voterId = voteItem->meta.mAuthorId;
if (voteItem->mMsg.mVoteType == GXS_VOTE_UP)
{
vote_up_inc = 1;
}
else
{
vote_down_inc = 1;
}
}
}
else
{
/* unknown! */
std::cerr << "p3Posted::background_processNewMessages() ERROR Strange NEW Message:";
std::cerr << std::endl;
std::cerr << "\t" << (*vit)->meta;
std::cerr << std::endl;
}
if (inc_counters)
{
RsStackMutex stack(mPostedMtx); /********** STACK LOCKED MTX ******/
std::map<RsGxsMessageId, PostStats>::iterator sit = mBgStatsMap.find(threadId);
if (sit == mBgStatsMap.end())
{
// add to map of ones to update.
postMap[groupId].push_back(threadId);
mBgStatsMap[threadId] = PostStats(0,0,0);
sit = mBgStatsMap.find(threadId);
}
sit->second.comments += comment_inc;
sit->second.up_votes += vote_up_inc;
sit->second.down_votes += vote_down_inc;
if (add_voter)
{
sit->second.voters.push_back(voterId);
}
std::cerr << "\tThreadId: " << threadId;
std::cerr << " Comment Total: " << sit->second.comments;
std::cerr << " UpVote Total: " << sit->second.up_votes;
std::cerr << " DownVote Total: " << sit->second.down_votes;
std::cerr << std::endl;
}
/* flag all messages as processed */
if ((*vit)->meta.mMsgStatus & GXS_SERV::GXS_MSG_STATUS_UNPROCESSED)
{
uint32_t token_a;
RsGxsGrpMsgIdPair msgId = std::make_pair(groupId, (*vit)->meta.mMsgId);
RsGenExchange::setMsgStatusFlags(token_a, msgId, 0, GXS_SERV::GXS_MSG_STATUS_UNPROCESSED);
}
}
}
/* push updates of new Posts */
if (msgChanges->msgChangeMap.size() > 0)
{
std::cerr << "p3Posted::background_processNewMessages() -> receiveChanges()";
std::cerr << std::endl;
changes.push_back(msgChanges);
RsGxsIfaceHelper::receiveChanges(changes);
}
/* request the summary info from the parents */
uint32_t token_b;
uint32_t anstype = RS_TOKREQ_ANSTYPE_SUMMARY;
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_MSG_META;
RsGenExchange::getTokenService()->requestMsgInfo(token_b, anstype, opts, postMap);
GxsTokenQueue::queueRequest(token_b, POSTED_BG_POST_META);
return;
}
#define RSGXS_MAX_SERVICE_STRING 1024
bool encodePostedCache(std::string &str, const PostStats &s)
{
char line[RSGXS_MAX_SERVICE_STRING];
snprintf(line, RSGXS_MAX_SERVICE_STRING, "%d %d %d", s.comments, s.up_votes, s.down_votes);
str = line;
return true;
}
bool extractPostedCache(const std::string &str, PostStats &s)
{
uint32_t iupvotes, idownvotes, icomments;
if (3 == sscanf(str.c_str(), "%d %d %d", &icomments, &iupvotes, &idownvotes))
{
s.comments = icomments;
s.up_votes = iupvotes;
s.down_votes = idownvotes;
return true;
}
return false;
}
void p3Posted::background_updateVoteCounts(const uint32_t &token)
{
std::cerr << "p3Posted::background_updateVoteCounts()";
std::cerr << std::endl;
GxsMsgMetaMap parentMsgList;
GxsMsgMetaMap::iterator mit;
std::vector<RsMsgMetaData>::iterator vit;
bool ok = RsGenExchange::getMsgMeta(token, parentMsgList);
if (!ok)
{
std::cerr << "p3Posted::background_updateVoteCounts() ERROR";
std::cerr << std::endl;
background_cleanup();
return;
}
// generate vector of changes to push to the GUI.
std::vector<RsGxsNotify *> changes;
RsGxsMsgChange *msgChanges = new RsGxsMsgChange(RsGxsNotify::TYPE_PROCESSED);
for(mit = parentMsgList.begin(); mit != parentMsgList.end(); mit++)
{
for(vit = mit->second.begin(); vit != mit->second.end(); vit++)
{
std::cerr << "p3Posted::background_updateVoteCounts() Processing Msg(" << mit->first;
std::cerr << ", " << vit->mMsgId << ")";
std::cerr << std::endl;
RsStackMutex stack(mPostedMtx); /********** STACK LOCKED MTX ******/
/* extract current vote count */
PostStats stats;
if (mBgIncremental)
{
if (!extractPostedCache(vit->mServiceString, stats))
{
if (!(vit->mServiceString.empty()))
{
std::cerr << "p3Posted::background_updateVoteCounts() Failed to extract Votes";
std::cerr << std::endl;
std::cerr << "\tFrom String: " << vit->mServiceString;
std::cerr << std::endl;
}
}
}
/* get increment */
std::map<RsGxsMessageId, PostStats>::iterator it;
it = mBgStatsMap.find(vit->mMsgId);
if (it != mBgStatsMap.end())
{
std::cerr << "p3Posted::background_updateVoteCounts() Adding to msgChangeMap: ";
std::cerr << mit->first << " MsgId: " << vit->mMsgId;
std::cerr << std::endl;
stats.increment(it->second);
msgChanges->msgChangeMap[mit->first].push_back(vit->mMsgId);
}
else
{
// warning.
std::cerr << "p3Posted::background_updateVoteCounts() Warning No New Votes found.";
std::cerr << " For MsgId: " << vit->mMsgId;
std::cerr << std::endl;
}
std::string str;
if (!encodePostedCache(str, stats))
{
std::cerr << "p3Posted::background_updateVoteCounts() Failed to encode Votes";
std::cerr << std::endl;
}
else
{
std::cerr << "p3Posted::background_updateVoteCounts() Encoded String: " << str;
std::cerr << std::endl;
/* store new result */
uint32_t token_c;
RsGxsGrpMsgIdPair msgId = std::make_pair(vit->mGroupId, vit->mMsgId);
RsGenExchange::setMsgServiceString(token_c, msgId, str);
}
}
}
if (msgChanges->msgChangeMap.size() > 0)
{
std::cerr << "p3Posted::background_updateVoteCounts() -> receiveChanges()";
std::cerr << std::endl;
changes.push_back(msgChanges);
RsGxsIfaceHelper::receiveChanges(changes);
}
// DONE!.
background_cleanup();
return;
}
bool p3Posted::background_cleanup()
{
std::cerr << "p3Posted::background_cleanup()";
std::cerr << std::endl;
RsStackMutex stack(mPostedMtx); /********** STACK LOCKED MTX ******/
// Cleanup.
mBgStatsMap.clear();
mBgProcessing = false;
return true;
}
// Overloaded from GxsTokenQueue for Request callbacks.
void p3Posted::handleResponse(uint32_t token, uint32_t req_type)
{
std::cerr << "p3Posted::handleResponse(" << token << "," << req_type << ")";
std::cerr << std::endl;
// stuff.
switch(req_type)
{
case POSTED_ALL_GROUPS:
background_loadGroups(token);
break;
case POSTED_UNPROCESSED_MSGS:
background_loadUnprocessedMsgs(token);
break;
case POSTED_ALL_MSGS:
background_loadAllMsgs(token);
break;
case POSTED_BG_POST_META:
background_updateVoteCounts(token);
break;
default:
/* error */
std::cerr << "p3Posted::handleResponse() Unknown Request Type: " << req_type;
std::cerr << std::endl;
break;
}
}

View file

@ -33,14 +33,43 @@
#include "util/rstickevent.h"
#include <retroshare/rsidentity.h>
#include <map>
#include <string>
#include <list>
/*
*
*/
class PostStats
{
public:
PostStats() :up_votes(0), down_votes(0), comments(0) { return; }
PostStats(int up, int down, int c) :up_votes(up), down_votes(down), comments(c) { return; }
void increment(const PostStats &s)
{
up_votes += s.up_votes;
down_votes += s.down_votes;
comments += s.comments;
return;
}
int up_votes;
int down_votes;
int comments;
std::list<RsGxsId> voters;
};
bool encodePostedCache(std::string &str, const PostStats &s);
bool extractPostedCache(const std::string &str, PostStats &s);
class p3Posted: public RsGenExchange, public RsPosted,
public GxsTokenQueue,
public RsTickEvent /* only needed for testing - remove after */
{
public:
@ -54,6 +83,9 @@ virtual void service_tick();
virtual void notifyChanges(std::vector<RsGxsNotify*>& changes);
// 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);
@ -66,13 +98,6 @@ virtual bool getRelatedPosts(const uint32_t &token, std::vector<RsPostedPost> &p
//////////////////////////////////////////////////////////////////////////////
// SPECIAL REQUEST.
virtual bool requestPostRankings(uint32_t &token, const RankType &rType, uint32_t count, uint32_t page_no, const RsGxsGroupId &groupId);
virtual bool getPostRanking(const uint32_t &token, std::vector<RsPostedPost> &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);
@ -126,6 +151,36 @@ virtual bool acknowledgeVote(const uint32_t& token, std::pair<RsGxsGroupId, RsGx
static uint32_t postedAuthenPolicy();
bool calculateScores(RsPostedPost &post, time_t ref_time);
// Background processing.
void background_tick();
bool background_requestAllGroups();
void background_loadGroups(const uint32_t &token);
void addGroupForProcessing(RsGxsGroupId grpId);
void background_requestUnprocessedGroup();
void background_requestGroupMsgs(const RsGxsGroupId &grpId, bool unprocessedOnly);
void background_loadUnprocessedMsgs(const uint32_t &token);
void background_loadAllMsgs(const uint32_t &token);
void background_loadMsgs(const uint32_t &token, bool unprocessed);
void background_updateVoteCounts(const uint32_t &token);
bool background_cleanup();
RsMutex mPostedMtx;
bool mBgProcessing;
bool mBgIncremental;
std::list<RsGxsGroupId> mBgGroupList;
std::map<RsGxsMessageId, PostStats> mBgStatsMap;
// DUMMY DATA,
virtual bool generateDummyData();
@ -160,4 +215,12 @@ bool generateGroup(uint32_t &token, std::string groupName);
p3GxsCommentService *mCommentService;
};
#endif

View file

@ -43,7 +43,7 @@ RsWiki *rsWiki = NULL;
#define DUMMYTICK_PERIOD 3
p3Wiki::p3Wiki(RsGeneralDataService* gds, RsNetworkExchangeService* nes, RsGixs *gixs)
:RsGenExchange(gds, nes, new RsGxsWikiSerialiser(), RS_SERVICE_GXSV1_TYPE_WIKI, gixs, wikiAuthenPolicy()),
:RsGenExchange(gds, nes, new RsGxsWikiSerialiser(), RS_SERVICE_GXSV2_TYPE_WIKI, gixs, wikiAuthenPolicy()),
RsWiki(this)
{
// Setup of dummy Pages.

View file

@ -36,7 +36,7 @@ RsWire *rsWire = NULL;
p3Wire::p3Wire(RsGeneralDataService* gds, RsNetworkExchangeService* nes, RsGixs *gixs)
:RsGenExchange(gds, nes, new RsGxsWireSerialiser(), RS_SERVICE_GXSV1_TYPE_WIRE, gixs, wireAuthenPolicy()),
:RsGenExchange(gds, nes, new RsGxsWireSerialiser(), RS_SERVICE_GXSV2_TYPE_WIRE, gixs, wireAuthenPolicy()),
RsWire(this), mWireMtx("WireMtx")
{