mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-07-22 22:21:09 -04:00
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:
parent
1150366913
commit
325fa4f222
116 changed files with 6050 additions and 3596 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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"))
|
||||
{
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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")
|
||||
{
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue