mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-12-24 23:19:29 -05:00
Merge pull request #1385 from G10h4ck/safer_api
0.6.5 Safer rsGxsChannel API
This commit is contained in:
commit
8c8ce53e4b
@ -36,20 +36,17 @@ bool GxsTokenQueue::queueRequest(uint32_t token, uint32_t req_type)
|
||||
void GxsTokenQueue::checkRequests()
|
||||
{
|
||||
{
|
||||
RsStackMutex stack(mQueueMtx); /********** STACK LOCKED MTX ******/
|
||||
if (mQueue.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
RS_STACK_MUTEX(mQueueMtx);
|
||||
if (mQueue.empty()) return;
|
||||
}
|
||||
|
||||
// Must check all, and move to a different list - for reentrant / good mutex behaviour.
|
||||
std::list<GxsTokenQueueItem> toload;
|
||||
std::list<GxsTokenQueueItem>::iterator it;
|
||||
|
||||
bool stuffToLoad = false;
|
||||
|
||||
{
|
||||
RsStackMutex stack(mQueueMtx); /********** STACK LOCKED MTX ******/
|
||||
RS_STACK_MUTEX(mQueueMtx);
|
||||
for(it = mQueue.begin(); it != mQueue.end();)
|
||||
{
|
||||
uint32_t token = it->mToken;
|
||||
@ -62,29 +59,29 @@ void GxsTokenQueue::checkRequests()
|
||||
stuffToLoad = true;
|
||||
|
||||
#ifdef GXS_DEBUG
|
||||
std::cerr << "GxsTokenQueue::checkRequests() token: " << token << " Complete";
|
||||
std::cerr << std::endl;
|
||||
std::cerr << "GxsTokenQueue::checkRequests() token: " << token
|
||||
<< " Complete" << std::endl;
|
||||
#endif
|
||||
++it;
|
||||
}
|
||||
else if (status == RsTokenService::FAILED)
|
||||
{
|
||||
// maybe we should do alternative callback?
|
||||
std::cerr << "GxsTokenQueue::checkRequests() ERROR Request Failed: " << token;
|
||||
std::cerr << std::endl;
|
||||
std::cerr << __PRETTY_FUNCTION__ << " ERROR Request Failed! "
|
||||
<< " token: " << token << std::endl;
|
||||
|
||||
it = mQueue.erase(it);
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef GXS_DEBUG
|
||||
std::cerr << "GxsTokenQueue::checkRequests() token: " << token << " is unfinished, status: " << status;
|
||||
std::cerr << std::endl;
|
||||
std::cerr << "GxsTokenQueue::checkRequests() token: " << token
|
||||
<< " is unfinished, status: " << status << std::endl;
|
||||
#endif
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // RS_STACK_MUTEX(mQueueMtx) END
|
||||
|
||||
if (stuffToLoad)
|
||||
{
|
||||
@ -95,11 +92,3 @@ void GxsTokenQueue::checkRequests()
|
||||
}
|
||||
}
|
||||
|
||||
// This must be overloaded to complete the functionality.
|
||||
void GxsTokenQueue::handleResponse(uint32_t token, uint32_t req_type)
|
||||
{
|
||||
std::cerr << "GxsTokenQueue::handleResponse(" << token << "," << req_type << ") ERROR: NOT HANDLED";
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
|
||||
|
||||
|
@ -54,7 +54,7 @@ public:
|
||||
protected:
|
||||
|
||||
/// This must be overloaded to complete the functionality.
|
||||
virtual void handleResponse(uint32_t token, uint32_t req_type);
|
||||
virtual void handleResponse(uint32_t token, uint32_t req_type) = 0;
|
||||
|
||||
private:
|
||||
RsGenExchange *mGenExchange;
|
||||
|
@ -1198,16 +1198,16 @@ void RsDataService::locked_retrieveGroups(RetroCursor* c, std::vector<RsNxsGrp*>
|
||||
}
|
||||
}
|
||||
|
||||
int RsDataService::retrieveNxsMsgs(const GxsMsgReq &reqIds, GxsMsgResult &msg, bool /* cache */, bool withMeta)
|
||||
int RsDataService::retrieveNxsMsgs(
|
||||
const GxsMsgReq &reqIds, GxsMsgResult &msg, bool /* cache */,
|
||||
bool withMeta )
|
||||
{
|
||||
#ifdef RS_DATA_SERVICE_DEBUG_TIME
|
||||
rstime::RsScopeTimer timer("");
|
||||
int resultCount = 0;
|
||||
#endif
|
||||
|
||||
GxsMsgReq::const_iterator mit = reqIds.begin();
|
||||
|
||||
for(; mit != reqIds.end(); ++mit)
|
||||
for(auto mit = reqIds.begin(); mit != reqIds.end(); ++mit)
|
||||
{
|
||||
|
||||
const RsGxsGroupId& grpId = mit->first;
|
||||
@ -1216,9 +1216,9 @@ int RsDataService::retrieveNxsMsgs(const GxsMsgReq &reqIds, GxsMsgResult &msg, b
|
||||
const std::set<RsGxsMessageId>& msgIdV = mit->second;
|
||||
std::vector<RsNxsMsg*> msgSet;
|
||||
|
||||
if(msgIdV.empty()){
|
||||
|
||||
RsStackMutex stack(mDbMutex);
|
||||
if(msgIdV.empty())
|
||||
{
|
||||
RS_STACK_MUTEX(mDbMutex);
|
||||
|
||||
RetroCursor* c = mDb->sqlQuery(MSG_TABLE_NAME, withMeta ? mMsgColumnsWithMeta : mMsgColumns, KEY_GRP_ID+ "='" + grpId.toStdString() + "'", "");
|
||||
|
||||
@ -1228,16 +1228,17 @@ int RsDataService::retrieveNxsMsgs(const GxsMsgReq &reqIds, GxsMsgResult &msg, b
|
||||
}
|
||||
|
||||
delete c;
|
||||
}else{
|
||||
}
|
||||
else
|
||||
{
|
||||
RS_STACK_MUTEX(mDbMutex);
|
||||
|
||||
// request each grp
|
||||
std::set<RsGxsMessageId>::const_iterator sit = msgIdV.begin();
|
||||
|
||||
for(; sit!=msgIdV.end();++sit){
|
||||
for( std::set<RsGxsMessageId>::const_iterator sit = msgIdV.begin();
|
||||
sit!=msgIdV.end();++sit )
|
||||
{
|
||||
const RsGxsMessageId& msgId = *sit;
|
||||
|
||||
RsStackMutex stack(mDbMutex);
|
||||
|
||||
RetroCursor* c = mDb->sqlQuery(MSG_TABLE_NAME, withMeta ? mMsgColumnsWithMeta : mMsgColumns, KEY_GRP_ID+ "='" + grpId.toStdString()
|
||||
+ "' AND " + KEY_MSG_ID + "='" + msgId.toStdString() + "'", "");
|
||||
|
||||
|
@ -47,10 +47,14 @@ public:
|
||||
* Retrieves all msgs
|
||||
* @param reqIds requested msg ids (grpId,msgId), leave msg list empty to get all msgs for the grp
|
||||
* @param msg result of msg retrieval
|
||||
* @param cache whether to store results of this retrieval in memory for faster later retrieval
|
||||
* @param cache IGNORED whether to store results of this retrieval in memory
|
||||
* for faster later retrieval
|
||||
* @param strictFilter if true do not request any message if reqIds is empty
|
||||
* @return error code
|
||||
*/
|
||||
int retrieveNxsMsgs(const GxsMsgReq& reqIds, GxsMsgResult& msg, bool cache, bool withMeta = false);
|
||||
*/
|
||||
int retrieveNxsMsgs(
|
||||
const GxsMsgReq& reqIds, GxsMsgResult& msg, bool cache,
|
||||
bool withMeta = false );
|
||||
|
||||
/*!
|
||||
* Retrieves groups, if empty, retrieves all grps, if map is not empty
|
||||
|
@ -137,16 +137,19 @@ public:
|
||||
typedef std::map<RsNxsMsg*, RsGxsMsgMetaData*> MsgStoreMap;
|
||||
|
||||
RsGeneralDataService(){}
|
||||
virtual ~RsGeneralDataService(){return;}
|
||||
virtual ~RsGeneralDataService(){}
|
||||
|
||||
/*!
|
||||
* Retrieves all msgs
|
||||
* @param reqIds requested msg ids (grpId,msgId), leave msg list empty to get all msgs for the grp
|
||||
* @param msg result of msg retrieval
|
||||
* @param cache whether to store results of this retrieval in memory for faster later retrieval
|
||||
* @param strictFilter if true do not request any message if reqIds is empty
|
||||
* @return error code
|
||||
*/
|
||||
virtual int retrieveNxsMsgs(const GxsMsgReq& reqIds, GxsMsgResult& msg, bool cache, bool withMeta=false) = 0;
|
||||
*/
|
||||
virtual int retrieveNxsMsgs(
|
||||
const GxsMsgReq& reqIds, GxsMsgResult& msg, bool cache,
|
||||
bool withMeta = false ) = 0;
|
||||
|
||||
/*!
|
||||
* Retrieves all groups stored
|
||||
|
@ -1925,7 +1925,7 @@ void RsGenExchange::setGroupStatusFlags(uint32_t& token, const RsGxsGroupId& grp
|
||||
|
||||
void RsGenExchange::setGroupServiceString(uint32_t& token, const RsGxsGroupId& grpId, const std::string& servString)
|
||||
{
|
||||
RS_STACK_MUTEX(mGenMtx) ;
|
||||
RS_STACK_MUTEX(mGenMtx);
|
||||
token = mDataAccess->generatePublicToken();
|
||||
|
||||
GrpLocMetaData g;
|
||||
|
@ -39,14 +39,16 @@ RsGxsDataAccess::~RsGxsDataAccess()
|
||||
for(std::map<uint32_t, GxsRequest*>::const_iterator it(mRequests.begin());it!=mRequests.end();++it)
|
||||
delete it->second ;
|
||||
}
|
||||
bool RsGxsDataAccess::requestGroupInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts,
|
||||
const std::list<RsGxsGroupId> &groupIds)
|
||||
bool RsGxsDataAccess::requestGroupInfo(
|
||||
uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts,
|
||||
const std::list<RsGxsGroupId> &groupIds )
|
||||
{
|
||||
if(groupIds.empty())
|
||||
{
|
||||
std::cerr << "(WW) Group Id list is empty" << std::endl;
|
||||
return false;
|
||||
}
|
||||
if(groupIds.empty())
|
||||
{
|
||||
std::cerr << __PRETTY_FUNCTION__ << " (WW) Group Id list is empty!"
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
GxsRequest* req = NULL;
|
||||
uint32_t reqType = opts.mReqType;
|
||||
@ -76,19 +78,19 @@ bool RsGxsDataAccess::requestGroupInfo(uint32_t &token, uint32_t ansType, const
|
||||
req = gir;
|
||||
}
|
||||
|
||||
if(req == NULL)
|
||||
{
|
||||
std::cerr << "RsGxsDataAccess::requestGroupInfo() request type not recognised, type "
|
||||
<< reqType << std::endl;
|
||||
return false;
|
||||
}else
|
||||
{
|
||||
generateToken(token);
|
||||
if(!req)
|
||||
{
|
||||
std::cerr << __PRETTY_FUNCTION__ << " request type not recognised, "
|
||||
<< "reqType: " << reqType << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
generateToken(token);
|
||||
|
||||
#ifdef DATA_DEBUG
|
||||
std::cerr << "RsGxsDataAccess::requestGroupInfo() gets Token: " << token << std::endl;
|
||||
std::cerr << "RsGxsDataAccess::requestGroupInfo() gets token: " << token
|
||||
<< std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
setReq(req, token, ansType, opts);
|
||||
storeRequest(req);
|
||||
@ -130,11 +132,8 @@ bool RsGxsDataAccess::requestGroupInfo(uint32_t &token, uint32_t ansType, const
|
||||
|
||||
void RsGxsDataAccess::generateToken(uint32_t &token)
|
||||
{
|
||||
RsStackMutex stack(mDataMutex); /****** LOCKED *****/
|
||||
|
||||
RS_STACK_MUTEX(mDataMutex);
|
||||
token = mNextToken++;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -301,15 +300,12 @@ void RsGxsDataAccess::setReq(GxsRequest* req, uint32_t token, uint32_t ansType,
|
||||
req->Options = opts;
|
||||
return;
|
||||
}
|
||||
void RsGxsDataAccess::storeRequest(GxsRequest* req)
|
||||
void RsGxsDataAccess::storeRequest(GxsRequest* req)
|
||||
{
|
||||
RsStackMutex stack(mDataMutex); /****** LOCKED *****/
|
||||
|
||||
req->status = PENDING;
|
||||
req->reqTime = time(NULL);
|
||||
RS_STACK_MUTEX(mDataMutex);
|
||||
req->status = PENDING;
|
||||
req->reqTime = time(NULL);
|
||||
mRequests[req->token] = req;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
RsTokenService::GxsRequestStatus RsGxsDataAccess::requestStatus(uint32_t token)
|
||||
@ -1040,29 +1036,42 @@ bool RsGxsDataAccess::getMsgData(MsgDataReq* req)
|
||||
{
|
||||
GxsMsgReq msgIdOut;
|
||||
|
||||
const RsTokReqOptions& opts(req->Options);
|
||||
|
||||
// filter based on options
|
||||
getMsgList(req->mMsgIds, req->Options, msgIdOut);
|
||||
getMsgList(req->mMsgIds, opts, msgIdOut);
|
||||
|
||||
// If the list is empty because of filtering do not retrieve from DB
|
||||
if((opts.mMsgFlagMask || opts.mStatusMask) && msgIdOut.empty())
|
||||
return true;
|
||||
|
||||
mDataStore->retrieveNxsMsgs(msgIdOut, req->mMsgData, true, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool RsGxsDataAccess::getMsgSummary(MsgMetaReq* req)
|
||||
{
|
||||
GxsMsgReq msgIdOut;
|
||||
GxsMsgReq msgIdOut;
|
||||
|
||||
// filter based on options
|
||||
getMsgList(req->mMsgIds, req->Options, msgIdOut);
|
||||
const RsTokReqOptions& opts(req->Options);
|
||||
|
||||
mDataStore->retrieveGxsMsgMetaData(msgIdOut, req->mMsgMetaData);
|
||||
// filter based on options
|
||||
getMsgList(req->mMsgIds, opts, msgIdOut);
|
||||
|
||||
// If the list is empty because of filtering do not retrieve from DB
|
||||
if((opts.mMsgFlagMask || opts.mStatusMask) && msgIdOut.empty())
|
||||
return true;
|
||||
|
||||
mDataStore->retrieveGxsMsgMetaData(msgIdOut, req->mMsgMetaData);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool RsGxsDataAccess::getMsgList(const GxsMsgReq& msgIds, const RsTokReqOptions& opts, GxsMsgReq& msgIdsOut)
|
||||
bool RsGxsDataAccess::getMsgList(
|
||||
const GxsMsgReq& msgIds, const RsTokReqOptions& opts,
|
||||
GxsMsgReq& msgIdsOut )
|
||||
{
|
||||
GxsMsgMetaResult result;
|
||||
|
||||
@ -1693,41 +1702,45 @@ void RsGxsDataAccess::cleanseMsgMetaMap(GxsMsgMetaResult& result)
|
||||
return;
|
||||
}
|
||||
|
||||
void RsGxsDataAccess::filterMsgList(GxsMsgIdResult& msgIds, const RsTokReqOptions& opts,
|
||||
const MsgMetaFilter& msgMetas) const
|
||||
void RsGxsDataAccess::filterMsgList(
|
||||
GxsMsgIdResult& resultsMap, const RsTokReqOptions& opts,
|
||||
const MsgMetaFilter& msgMetas ) const
|
||||
{
|
||||
|
||||
GxsMsgIdResult::iterator mit = msgIds.begin();
|
||||
for(;mit != msgIds.end(); ++mit)
|
||||
for( GxsMsgIdResult::iterator grpIt = resultsMap.begin();
|
||||
grpIt != resultsMap.end(); ++grpIt )
|
||||
{
|
||||
const RsGxsGroupId& groupId(grpIt->first);
|
||||
std::set<RsGxsMessageId>& msgsIdSet(grpIt->second);
|
||||
|
||||
MsgMetaFilter::const_iterator cit = msgMetas.find(mit->first);
|
||||
MsgMetaFilter::const_iterator cit = msgMetas.find(groupId);
|
||||
if(cit == msgMetas.end()) continue;
|
||||
|
||||
if(cit == msgMetas.end())
|
||||
continue;
|
||||
std::cerr << __PRETTY_FUNCTION__ << " " << msgsIdSet.size()
|
||||
<< " for group: " << groupId << " before filtering"
|
||||
<< std::endl;
|
||||
|
||||
std::set<RsGxsMessageId>& msgs = mit->second;
|
||||
std::set<RsGxsMessageId>::iterator vit = msgs.begin();
|
||||
const std::map<RsGxsMessageId, RsGxsMsgMetaData*>& meta = cit->second;
|
||||
std::map<RsGxsMessageId, RsGxsMsgMetaData*>::const_iterator cit2;
|
||||
|
||||
for(; vit != msgs.end();)
|
||||
for( std::set<RsGxsMessageId>::iterator msgIdIt = msgsIdSet.begin();
|
||||
msgIdIt != msgsIdSet.end(); )
|
||||
{
|
||||
const RsGxsMessageId& msgId(*msgIdIt);
|
||||
const std::map<RsGxsMessageId, RsGxsMsgMetaData*>& msgsMetaMap =
|
||||
cit->second;
|
||||
|
||||
bool keep = false;
|
||||
if( (cit2 = meta.find(*vit)) != meta.end() )
|
||||
std::map<RsGxsMessageId, RsGxsMsgMetaData*>::const_iterator msgsMetaMapIt;
|
||||
|
||||
if( (msgsMetaMapIt = msgsMetaMap.find(msgId)) != msgsMetaMap.end() )
|
||||
{
|
||||
keep = checkMsgFilter(opts, cit2->second);
|
||||
keep = checkMsgFilter(opts, msgsMetaMapIt->second);
|
||||
}
|
||||
|
||||
if(keep)
|
||||
{
|
||||
++vit;
|
||||
}else
|
||||
{
|
||||
vit = msgs.erase(vit);
|
||||
}
|
||||
if(keep) ++msgIdIt;
|
||||
else msgIdIt = msgsIdSet.erase(msgIdIt);
|
||||
}
|
||||
|
||||
std::cerr << __PRETTY_FUNCTION__ << " " << msgsIdSet.size()
|
||||
<< " for group: " << groupId << " after filtering"
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1905,62 +1918,87 @@ bool RsGxsDataAccess::checkGrpFilter(const RsTokReqOptions &opts, const RsGxsGrp
|
||||
|
||||
return subscribeMatch;
|
||||
}
|
||||
bool RsGxsDataAccess::checkMsgFilter(const RsTokReqOptions& opts, const RsGxsMsgMetaData* meta) const
|
||||
bool RsGxsDataAccess::checkMsgFilter(
|
||||
const RsTokReqOptions& opts, const RsGxsMsgMetaData* meta ) const
|
||||
{
|
||||
bool statusMatch = false;
|
||||
if (opts.mStatusMask)
|
||||
if (opts.mStatusMask)
|
||||
{
|
||||
// Exact Flags match required.
|
||||
if ((opts.mStatusMask & opts.mStatusFilter) == (opts.mStatusMask & meta->mMsgStatus))
|
||||
if ( (opts.mStatusMask & opts.mStatusFilter) ==
|
||||
(opts.mStatusMask & meta->mMsgStatus) )
|
||||
{
|
||||
std::cerr << "checkMsgFilter() Accepting Msg as StatusMatches: ";
|
||||
std::cerr << " Mask: " << opts.mStatusMask << " StatusFilter: " << opts.mStatusFilter;
|
||||
std::cerr << " MsgStatus: " << meta->mMsgStatus << " MsgId: " << meta->mMsgId;
|
||||
std::cerr << std::endl;
|
||||
|
||||
statusMatch = true;
|
||||
#ifdef DATA_DEBUG
|
||||
std::cerr << __PRETTY_FUNCTION__
|
||||
<< " Continue checking Msg as StatusMatches: "
|
||||
<< " Mask: " << opts.mStatusMask
|
||||
<< " StatusFilter: " << opts.mStatusFilter
|
||||
<< " MsgStatus: " << meta->mMsgStatus
|
||||
<< " MsgId: " << meta->mMsgId << std::endl;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "checkMsgFilter() Dropping Msg due to !StatusMatch ";
|
||||
std::cerr << " Mask: " << opts.mStatusMask << " StatusFilter: " << opts.mStatusFilter;
|
||||
std::cerr << " MsgStatus: " << meta->mMsgStatus << " MsgId: " << meta->mMsgId;
|
||||
std::cerr << std::endl;
|
||||
#ifdef DATA_DEBUG
|
||||
std::cerr << __PRETTY_FUNCTION__
|
||||
<< " Dropping Msg due to !StatusMatch "
|
||||
<< " Mask: " << opts.mStatusMask
|
||||
<< " StatusFilter: " << opts.mStatusFilter
|
||||
<< " MsgStatus: " << meta->mMsgStatus
|
||||
<< " MsgId: " << meta->mMsgId << std::endl;
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// no status comparision,
|
||||
statusMatch = true;
|
||||
#ifdef DATA_DEBUG
|
||||
std::cerr << __PRETTY_FUNCTION__
|
||||
<< " Status check not requested"
|
||||
<< " mStatusMask: " << opts.mStatusMask
|
||||
<< " MsgId: " << meta->mMsgId << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool flagMatch = false;
|
||||
if(opts.mMsgFlagMask)
|
||||
{
|
||||
// Exact Flags match required.
|
||||
if ( (opts.mMsgFlagMask & opts.mMsgFlagFilter) ==
|
||||
(opts.mMsgFlagMask & meta->mMsgFlags) )
|
||||
{
|
||||
#ifdef DATA_DEBUG
|
||||
std::cerr << __PRETTY_FUNCTION__
|
||||
<< " Accepting Msg as FlagMatches: "
|
||||
<< " Mask: " << opts.mMsgFlagMask
|
||||
<< " FlagFilter: " << opts.mMsgFlagFilter
|
||||
<< " MsgFlag: " << meta->mMsgFlags
|
||||
<< " MsgId: " << meta->mMsgId << std::endl;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef DATA_DEBUG
|
||||
std::cerr << __PRETTY_FUNCTION__
|
||||
<< " Dropping Msg due to !FlagMatch "
|
||||
<< " Mask: " << opts.mMsgFlagMask
|
||||
<< " FlagFilter: " << opts.mMsgFlagFilter
|
||||
<< " MsgFlag: " << meta->mMsgFlags
|
||||
<< " MsgId: " << meta->mMsgId << std::endl;
|
||||
#endif
|
||||
|
||||
if(opts.mMsgFlagMask)
|
||||
{
|
||||
// Exact Flags match required.
|
||||
if ((opts.mMsgFlagMask & opts.mMsgFlagFilter) == (opts.mMsgFlagMask & meta->mMsgFlags))
|
||||
{
|
||||
std::cerr << "checkMsgFilter() Accepting Msg as FlagMatches: ";
|
||||
std::cerr << " Mask: " << opts.mMsgFlagMask << " FlagFilter: " << opts.mMsgFlagFilter;
|
||||
std::cerr << " MsgFlag: " << meta->mMsgFlags << " MsgId: " << meta->mMsgId;
|
||||
std::cerr << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef DATA_DEBUG
|
||||
std::cerr << __PRETTY_FUNCTION__
|
||||
<< " Flags check not requested"
|
||||
<< " mMsgFlagMask: " << opts.mMsgFlagMask
|
||||
<< " MsgId: " << meta->mMsgId << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
flagMatch = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "checkMsgFilter() Dropping Msg due to !FlagMatch ";
|
||||
std::cerr << " Mask: " << opts.mMsgFlagMask << " FlagFilter: " << opts.mMsgFlagFilter;
|
||||
std::cerr << " MsgFlag: " << meta->mMsgFlags << " MsgId: " << meta->mMsgId;
|
||||
std::cerr << std::endl;
|
||||
|
||||
flagMatch = false;
|
||||
}
|
||||
}else{
|
||||
flagMatch = true;
|
||||
}
|
||||
|
||||
return statusMatch && flagMatch;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -5290,7 +5290,8 @@ void RsGxsNetService::receiveTurtleSearchResults(TurtleRequestId req,const unsig
|
||||
#ifdef NXS_NET_DEBUG_8
|
||||
GXSNETDEBUG___ << " passing the grp data to observer." << std::endl;
|
||||
#endif
|
||||
mObserver->receiveNewGroups(new_grps);
|
||||
mObserver->receiveNewGroups(new_grps);
|
||||
mObserver->receiveDistantSearchResults(req, grpId);
|
||||
}
|
||||
|
||||
bool RsGxsNetService::search( const std::string& substring,
|
||||
|
@ -22,7 +22,7 @@
|
||||
* *
|
||||
*******************************************************************************/
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <functional>
|
||||
@ -32,6 +32,7 @@
|
||||
#include "retroshare/rsgxscommon.h"
|
||||
#include "serialiser/rsserializable.h"
|
||||
#include "retroshare/rsturtle.h"
|
||||
#include "util/rsdeprecate.h"
|
||||
|
||||
class RsGxsChannels;
|
||||
|
||||
@ -100,10 +101,70 @@ std::ostream &operator<<(std::ostream& out, const RsGxsChannelPost& post);
|
||||
class RsGxsChannels: public RsGxsIfaceHelper, public RsGxsCommentService
|
||||
{
|
||||
public:
|
||||
|
||||
explicit RsGxsChannels(RsGxsIface& gxs) : RsGxsIfaceHelper(gxs) {}
|
||||
virtual ~RsGxsChannels() {}
|
||||
|
||||
/**
|
||||
* @brief Create channel. Blocking API.
|
||||
* @jsonapi{development}
|
||||
* @param[inout] channel Channel data (name, description...)
|
||||
* @return false on error, true otherwise
|
||||
*/
|
||||
virtual bool createChannel(RsGxsChannelGroup& channel) = 0;
|
||||
|
||||
/**
|
||||
* @brief Create channel post. Blocking API.
|
||||
* @jsonapi{development}
|
||||
* @param[inout] post
|
||||
* @return false on error, true otherwise
|
||||
*/
|
||||
virtual bool createPost(RsGxsChannelPost& post) = 0;
|
||||
|
||||
/**
|
||||
* @brief Edit channel details.
|
||||
* @jsonapi{development}
|
||||
* @param[in] channel Channel data (name, description...) with modifications
|
||||
* @return false on error, true otherwise
|
||||
*/
|
||||
virtual bool editChannel(RsGxsChannelGroup& channel) = 0;
|
||||
|
||||
/**
|
||||
* @brief Share extra file
|
||||
* Can be used to share extra file attached to a channel post
|
||||
* @jsonapi{development}
|
||||
* @param[in] path file path
|
||||
* @return false on error, true otherwise
|
||||
*/
|
||||
virtual bool ExtraFileHash(const std::string& path) = 0;
|
||||
|
||||
/**
|
||||
* @brief Remove extra file from shared files
|
||||
* @jsonapi{development}
|
||||
* @param[in] hash hash of the file to remove
|
||||
* @return false on error, true otherwise
|
||||
*/
|
||||
virtual bool ExtraFileRemove(const RsFileHash& hash) = 0;
|
||||
|
||||
/**
|
||||
* @brief Get auto-download option value for given channel
|
||||
* @jsonapi{development}
|
||||
* @param[in] channelId channel id
|
||||
* @param[out] enabled storage for the auto-download option value
|
||||
* @return false if something failed, true otherwhise
|
||||
*/
|
||||
virtual bool getChannelAutoDownload(
|
||||
const RsGxsGroupId& channelId, bool& enabled ) = 0;
|
||||
|
||||
/**
|
||||
* @brief Get download directory for the given channel
|
||||
* @jsonapi{development}
|
||||
* @param[in] channelId id of the channel
|
||||
* @param[out] directory reference to string where to store the path
|
||||
* @return false on error, true otherwise
|
||||
*/
|
||||
virtual bool getChannelDownloadDirectory( const RsGxsGroupId& channelId,
|
||||
std::string& directory ) = 0;
|
||||
|
||||
/**
|
||||
* @brief Get channels summaries list. Blocking API.
|
||||
* @jsonapi{development}
|
||||
@ -138,63 +199,37 @@ public:
|
||||
std::vector<RsGxsComment>& comments ) = 0;
|
||||
|
||||
/**
|
||||
* @brief Create channel. Blocking API.
|
||||
* @brief Toggle post read status. Blocking API.
|
||||
* @jsonapi{development}
|
||||
* @param[inout] channel Channel data (name, description...)
|
||||
* @param[in] postId post identifier
|
||||
* @param[in] read true to mark as read, false to mark as unread
|
||||
* @return false on error, true otherwise
|
||||
*/
|
||||
virtual bool createChannel(RsGxsChannelGroup& channel) = 0;
|
||||
virtual bool markRead(const RsGxsGrpMsgIdPair& postId, bool read) = 0;
|
||||
|
||||
/**
|
||||
* @brief Create channel post. Blocking API.
|
||||
* @brief Enable or disable auto-download for given channel. Blocking API
|
||||
* @jsonapi{development}
|
||||
* @param[inout] post
|
||||
* @return false on error, true otherwise
|
||||
*/
|
||||
virtual bool createPost(RsGxsChannelPost& post) = 0;
|
||||
|
||||
|
||||
/* Specific Service Data
|
||||
* TODO: change the orrible const uint32_t &token to uint32_t token
|
||||
* TODO: create a new typedef for token so code is easier to read
|
||||
*/
|
||||
|
||||
virtual bool getGroupData(const uint32_t &token, std::vector<RsGxsChannelGroup> &groups) = 0;
|
||||
virtual bool getPostData(const uint32_t &token, std::vector<RsGxsChannelPost> &posts, std::vector<RsGxsComment> &cmts) = 0;
|
||||
virtual bool getPostData(const uint32_t &token, std::vector<RsGxsChannelPost> &posts) = 0;
|
||||
|
||||
/**
|
||||
* @brief toggle message read status
|
||||
* @jsonapi{development}
|
||||
* @param[out] token GXS token queue token
|
||||
* @param[in] msgId
|
||||
* @param[in] read
|
||||
*/
|
||||
virtual void setMessageReadStatus(
|
||||
uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool read) = 0;
|
||||
|
||||
/**
|
||||
* @brief Enable or disable auto-download for given channel
|
||||
* @jsonapi{development}
|
||||
* @param[in] groupId channel id
|
||||
* @param[in] channelId channel id
|
||||
* @param[in] enable true to enable, false to disable
|
||||
* @return false if something failed, true otherwhise
|
||||
*/
|
||||
virtual bool setChannelAutoDownload(
|
||||
const RsGxsGroupId &groupId, bool enable) = 0;
|
||||
const RsGxsGroupId& channelId, bool enable ) = 0;
|
||||
|
||||
/**
|
||||
* @brief Get auto-download option value for given channel
|
||||
* @brief Share channel publishing key
|
||||
* This can be used to authorize other peers to post on the channel
|
||||
* @jsonapi{development}
|
||||
* @param[in] groupId channel id
|
||||
* @param[in] enabled storage for the auto-download option value
|
||||
* @return false if something failed, true otherwhise
|
||||
* @param[in] channelId id of the channel
|
||||
* @param[in] peers peers to share the key with
|
||||
* @return false on error, true otherwise
|
||||
*/
|
||||
virtual bool getChannelAutoDownload(
|
||||
const RsGxsGroupId &groupId, bool& enabled) = 0;
|
||||
virtual bool shareChannelKeys(
|
||||
const RsGxsGroupId& channelId, const std::set<RsPeerId>& peers ) = 0;
|
||||
|
||||
/**
|
||||
* @brief Set download directory for the given channel
|
||||
* @brief Set download directory for the given channel. Blocking API.
|
||||
* @jsonapi{development}
|
||||
* @param[in] channelId id of the channel
|
||||
* @param[in] directory path
|
||||
@ -204,90 +239,14 @@ public:
|
||||
const RsGxsGroupId& channelId, const std::string& directory) = 0;
|
||||
|
||||
/**
|
||||
* @brief Get download directory for the given channel
|
||||
* @brief Subscrbe to a channel. Blocking API
|
||||
* @jsonapi{development}
|
||||
* @param[in] channelId id of the channel
|
||||
* @param[out] directory reference to string where to store the path
|
||||
* @param[in] channelId Channel id
|
||||
* @param[in] subscribe true to subscribe, false to unsubscribe
|
||||
* @return false on error, true otherwise
|
||||
*/
|
||||
virtual bool getChannelDownloadDirectory( const RsGxsGroupId& channelId,
|
||||
std::string& directory ) = 0;
|
||||
|
||||
/**
|
||||
* @brief Share channel publishing key
|
||||
* This can be used to authorize other peers to post on the channel
|
||||
* @jsonapi{development}
|
||||
* @param[in] groupId Channel id
|
||||
* @param[in] peers peers to which share the key
|
||||
* @return false on error, true otherwise
|
||||
*/
|
||||
virtual bool groupShareKeys(
|
||||
const RsGxsGroupId& groupId, const std::set<RsPeerId>& peers ) = 0;
|
||||
|
||||
/**
|
||||
* @brief Request subscription to a group.
|
||||
* The action is performed asyncronously, so it could fail in a subsequent
|
||||
* phase even after returning true.
|
||||
* @jsonapi{development}
|
||||
* @param[out] token Storage for RsTokenService token to track request
|
||||
* status.
|
||||
* @param[in] groupId Channel id
|
||||
* @param[in] subscribe
|
||||
* @return false on error, true otherwise
|
||||
*/
|
||||
virtual bool subscribeToGroup( uint32_t& token, const RsGxsGroupId &groupId,
|
||||
bool subscribe ) = 0;
|
||||
|
||||
/**
|
||||
* @brief Request channel creation.
|
||||
* The action is performed asyncronously, so it could fail in a subsequent
|
||||
* phase even after returning true.
|
||||
* @param[out] token Storage for RsTokenService token to track request
|
||||
* status.
|
||||
* @param[in] group Channel data (name, description...)
|
||||
* @return false on error, true otherwise
|
||||
*/
|
||||
virtual bool createGroup(uint32_t& token, RsGxsChannelGroup& group) = 0;
|
||||
|
||||
/**
|
||||
* @brief Request post creation.
|
||||
* The action is performed asyncronously, so it could fail in a subsequent
|
||||
* phase even after returning true.
|
||||
* @param[out] token Storage for RsTokenService token to track request
|
||||
* status.
|
||||
* @param[in] post
|
||||
* @return false on error, true otherwise
|
||||
*/
|
||||
virtual bool createPost(uint32_t& token, RsGxsChannelPost& post) = 0;
|
||||
|
||||
/**
|
||||
* @brief Request channel change.
|
||||
* The action is performed asyncronously, so it could fail in a subsequent
|
||||
* phase even after returning true.
|
||||
* @jsonapi{development}
|
||||
* @param[out] token Storage for RsTokenService token to track request
|
||||
* status.
|
||||
* @param[in] group Channel data (name, description...) with modifications
|
||||
* @return false on error, true otherwise
|
||||
*/
|
||||
virtual bool updateGroup(uint32_t& token, RsGxsChannelGroup& group) = 0;
|
||||
|
||||
/**
|
||||
* @brief Share extra file
|
||||
* Can be used to share extra file attached to a channel post
|
||||
* @jsonapi{development}
|
||||
* @param[in] path file path
|
||||
* @return false on error, true otherwise
|
||||
*/
|
||||
virtual bool ExtraFileHash(const std::string& path) = 0;
|
||||
|
||||
/**
|
||||
* @brief Remove extra file from shared files
|
||||
* @jsonapi{development}
|
||||
* @param[in] hash hash of the file to remove
|
||||
* @return false on error, true otherwise
|
||||
*/
|
||||
virtual bool ExtraFileRemove(const RsFileHash& hash) = 0;
|
||||
virtual bool subscribeToChannel( const RsGxsGroupId &channelId,
|
||||
bool subscribe ) = 0;
|
||||
|
||||
/**
|
||||
* @brief Request remote channels search
|
||||
@ -303,15 +262,123 @@ public:
|
||||
const std::function<void (const RsGxsGroupSummary& result)>& multiCallback,
|
||||
rstime_t maxWait = 300 ) = 0;
|
||||
|
||||
/**
|
||||
* @brief Request remote channel
|
||||
* @jsonapi{development}
|
||||
* @param[in] channelId id of the channel to request to distants peers
|
||||
* @param multiCallback function that will be called each time a result is
|
||||
* received
|
||||
* @param[in] maxWait maximum wait time in seconds for search results
|
||||
* @return false on error, true otherwise
|
||||
*/
|
||||
virtual bool turtleChannelRequest(
|
||||
const RsGxsGroupId& channelId,
|
||||
const std::function<void (const RsGxsChannelGroup& result)>& multiCallback,
|
||||
rstime_t maxWait = 300 ) = 0;
|
||||
|
||||
|
||||
/* Following functions are deprecated as they expose internal functioning
|
||||
* semantic, instead of a safe to use API */
|
||||
|
||||
RS_DEPRECATED_FOR(getChannelsInfo)
|
||||
virtual bool getGroupData(const uint32_t &token, std::vector<RsGxsChannelGroup> &groups) = 0;
|
||||
|
||||
RS_DEPRECATED_FOR(getChannelsContent)
|
||||
virtual bool getPostData(const uint32_t &token, std::vector<RsGxsChannelPost> &posts, std::vector<RsGxsComment> &cmts) = 0;
|
||||
|
||||
RS_DEPRECATED_FOR(getChannelsContent)
|
||||
virtual bool getPostData(const uint32_t &token, std::vector<RsGxsChannelPost> &posts) = 0;
|
||||
|
||||
/**
|
||||
* @brief toggle message read status
|
||||
* @deprecated
|
||||
* @param[out] token GXS token queue token
|
||||
* @param[in] msgId
|
||||
* @param[in] read
|
||||
*/
|
||||
RS_DEPRECATED_FOR(markRead)
|
||||
virtual void setMessageReadStatus(
|
||||
uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool read) = 0;
|
||||
|
||||
/**
|
||||
* @brief Share channel publishing key
|
||||
* This can be used to authorize other peers to post on the channel
|
||||
* @deprecated
|
||||
* @param[in] groupId Channel id
|
||||
* @param[in] peers peers to which share the key
|
||||
* @return false on error, true otherwise
|
||||
*/
|
||||
RS_DEPRECATED_FOR(shareChannelKeys)
|
||||
virtual bool groupShareKeys(
|
||||
const RsGxsGroupId& groupId, const std::set<RsPeerId>& peers ) = 0;
|
||||
|
||||
/**
|
||||
* @brief Request subscription to a group.
|
||||
* The action is performed asyncronously, so it could fail in a subsequent
|
||||
* phase even after returning true.
|
||||
* @deprecated
|
||||
* @param[out] token Storage for RsTokenService token to track request
|
||||
* status.
|
||||
* @param[in] groupId Channel id
|
||||
* @param[in] subscribe
|
||||
* @return false on error, true otherwise
|
||||
*/
|
||||
RS_DEPRECATED_FOR(subscribeToChannel)
|
||||
virtual bool subscribeToGroup( uint32_t& token, const RsGxsGroupId &groupId,
|
||||
bool subscribe ) = 0;
|
||||
|
||||
/**
|
||||
* @brief Request channel creation.
|
||||
* The action is performed asyncronously, so it could fail in a subsequent
|
||||
* phase even after returning true.
|
||||
* @deprecated
|
||||
* @param[out] token Storage for RsTokenService token to track request
|
||||
* status.
|
||||
* @param[in] group Channel data (name, description...)
|
||||
* @return false on error, true otherwise
|
||||
*/
|
||||
RS_DEPRECATED_FOR(createChannel)
|
||||
virtual bool createGroup(uint32_t& token, RsGxsChannelGroup& group) = 0;
|
||||
|
||||
/**
|
||||
* @brief Request post creation.
|
||||
* The action is performed asyncronously, so it could fail in a subsequent
|
||||
* phase even after returning true.
|
||||
* @deprecated
|
||||
* @param[out] token Storage for RsTokenService token to track request
|
||||
* status.
|
||||
* @param[in] post
|
||||
* @return false on error, true otherwise
|
||||
*/
|
||||
RS_DEPRECATED
|
||||
virtual bool createPost(uint32_t& token, RsGxsChannelPost& post) = 0;
|
||||
|
||||
/**
|
||||
* @brief Request channel change.
|
||||
* The action is performed asyncronously, so it could fail in a subsequent
|
||||
* phase even after returning true.
|
||||
* @deprecated
|
||||
* @param[out] token Storage for RsTokenService token to track request
|
||||
* status.
|
||||
* @param[in] group Channel data (name, description...) with modifications
|
||||
* @return false on error, true otherwise
|
||||
*/
|
||||
RS_DEPRECATED_FOR(editChannel)
|
||||
virtual bool updateGroup(uint32_t& token, RsGxsChannelGroup& group) = 0;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// Distant synchronisation methods ///
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
RS_DEPRECATED_FOR(turtleChannelRequest)
|
||||
virtual TurtleRequestId turtleGroupRequest(const RsGxsGroupId& group_id)=0;
|
||||
RS_DEPRECATED
|
||||
virtual TurtleRequestId turtleSearchRequest(const std::string& match_string)=0;
|
||||
RS_DEPRECATED_FOR(turtleSearchRequest)
|
||||
virtual bool retrieveDistantSearchResults(TurtleRequestId req, std::map<RsGxsGroupId, RsGxsGroupSummary> &results) =0;
|
||||
RS_DEPRECATED
|
||||
virtual bool clearDistantSearchResults(TurtleRequestId req)=0;
|
||||
RS_DEPRECATED_FOR(turtleChannelRequest)
|
||||
virtual bool retrieveDistantGroup(const RsGxsGroupId& group_id,RsGxsChannelGroup& distant_group)=0;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
};
|
||||
|
@ -76,7 +76,10 @@ p3GxsChannels::p3GxsChannels(
|
||||
RsGenExchange( gds, nes, new RsGxsChannelSerialiser(),
|
||||
RS_SERVICE_GXS_TYPE_CHANNELS, gixs, channelsAuthenPolicy() ),
|
||||
RsGxsChannels(static_cast<RsGxsIface&>(*this)), GxsTokenQueue(this),
|
||||
mSearchCallbacksMapMutex("GXS channels search")
|
||||
mSubscribedGroupsMutex("GXS channels subscribed groups cache"),
|
||||
mKnownChannelsMutex("GXS channels known channels timestamp cache"),
|
||||
mSearchCallbacksMapMutex("GXS channels search callbacks map"),
|
||||
mDistantChannelsCallbacksMapMutex("GXS channels distant channels callbacks map")
|
||||
{
|
||||
// For Dummy Msgs.
|
||||
mGenActive = false;
|
||||
@ -174,7 +177,10 @@ bool p3GxsChannels::saveList(bool &cleanup, std::list<RsItem *>&saveList)
|
||||
|
||||
RsGxsForumNotifyRecordsItem *item = new RsGxsForumNotifyRecordsItem ;
|
||||
|
||||
item->records = mKnownChannels ;
|
||||
{
|
||||
RS_STACK_MUTEX(mKnownChannelsMutex);
|
||||
item->records = mKnownChannels;
|
||||
}
|
||||
|
||||
saveList.push_back(item) ;
|
||||
return true;
|
||||
@ -191,8 +197,9 @@ bool p3GxsChannels::loadList(std::list<RsItem *>& loadList)
|
||||
|
||||
RsGxsForumNotifyRecordsItem *fnr = dynamic_cast<RsGxsForumNotifyRecordsItem*>(item) ;
|
||||
|
||||
if(fnr != NULL)
|
||||
if(fnr)
|
||||
{
|
||||
RS_STACK_MUTEX(mKnownChannelsMutex);
|
||||
mKnownChannels.clear();
|
||||
|
||||
for(auto it(fnr->records.begin());it!=fnr->records.end();++it)
|
||||
@ -228,7 +235,7 @@ void p3GxsChannels::notifyChanges(std::vector<RsGxsNotify *> &changes)
|
||||
std::cerr << "p3GxsChannels::notifyChanges() : " << changes.size() << "changes to notify" << std::endl;
|
||||
#endif
|
||||
|
||||
p3Notify *notify = NULL;
|
||||
p3Notify* notify = nullptr;
|
||||
if (!changes.empty())
|
||||
{
|
||||
notify = RsServer::notify();
|
||||
@ -271,9 +278,8 @@ void p3GxsChannels::notifyChanges(std::vector<RsGxsNotify *> &changes)
|
||||
std::cerr << "p3GxsChannels::notifyChanges() Msgs for Group: " << mit->first;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
bool enabled = false ;
|
||||
|
||||
if (autoDownloadEnabled(mit->first, enabled) && enabled)
|
||||
bool enabled = false;
|
||||
if (autoDownloadEnabled(mit->first, enabled) && enabled)
|
||||
{
|
||||
#ifdef GXSCHANNELS_DEBUG
|
||||
std::cerr << "p3GxsChannels::notifyChanges() AutoDownload for Group: " << mit->first;
|
||||
@ -306,6 +312,7 @@ void p3GxsChannels::notifyChanges(std::vector<RsGxsNotify *> &changes)
|
||||
/* group received */
|
||||
std::list<RsGxsGroupId> &grpList = grpChange->mGrpIdList;
|
||||
std::list<RsGxsGroupId>::iterator git;
|
||||
RS_STACK_MUTEX(mKnownChannelsMutex);
|
||||
for (git = grpList.begin(); git != grpList.end(); ++git)
|
||||
{
|
||||
if(mKnownChannels.find(*git) == mKnownChannels.end())
|
||||
@ -338,15 +345,15 @@ void p3GxsChannels::notifyChanges(std::vector<RsGxsNotify *> &changes)
|
||||
/* shouldn't need to worry about groups - as they need to be subscribed to */
|
||||
}
|
||||
|
||||
request_SpecificSubscribedGroups(unprocessedGroups);
|
||||
if(!unprocessedGroups.empty())
|
||||
request_SpecificSubscribedGroups(unprocessedGroups);
|
||||
|
||||
RsGxsIfaceHelper::receiveChanges(changes);
|
||||
}
|
||||
|
||||
void p3GxsChannels::service_tick()
|
||||
{
|
||||
|
||||
static rstime_t last_dummy_tick = 0;
|
||||
static rstime_t last_dummy_tick = 0;
|
||||
|
||||
if (time(NULL) > last_dummy_tick + 5)
|
||||
{
|
||||
@ -414,75 +421,84 @@ bool p3GxsChannels::groupShareKeys(
|
||||
* at the moment - fix it up later
|
||||
*/
|
||||
|
||||
bool p3GxsChannels::getPostData(const uint32_t &token, std::vector<RsGxsChannelPost> &msgs, std::vector<RsGxsComment> &cmts)
|
||||
bool p3GxsChannels::getPostData(
|
||||
const uint32_t &token, std::vector<RsGxsChannelPost> &msgs,
|
||||
std::vector<RsGxsComment> &cmts )
|
||||
{
|
||||
#ifdef GXSCHANNELS_DEBUG
|
||||
std::cerr << "p3GxsChannels::getPostData()";
|
||||
std::cerr << std::endl;
|
||||
std::cerr << __PRETTY_FUNCTION__ << std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
GxsMsgDataMap msgData;
|
||||
bool ok = RsGenExchange::getMsgData(token, msgData);
|
||||
|
||||
if(ok)
|
||||
if(!RsGenExchange::getMsgData(token, msgData))
|
||||
{
|
||||
GxsMsgDataMap::iterator mit = msgData.begin();
|
||||
|
||||
for(; mit != msgData.end(); ++mit)
|
||||
std::cerr << __PRETTY_FUNCTION__ <<" ERROR in request" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
GxsMsgDataMap::iterator mit = msgData.begin();
|
||||
|
||||
for(; mit != msgData.end(); ++mit)
|
||||
{
|
||||
std::vector<RsGxsMsgItem*>& msgItems = mit->second;
|
||||
std::vector<RsGxsMsgItem*>::iterator vit = msgItems.begin();
|
||||
|
||||
for(; vit != msgItems.end(); ++vit)
|
||||
{
|
||||
std::vector<RsGxsMsgItem*>& msgItems = mit->second;
|
||||
std::vector<RsGxsMsgItem*>::iterator vit = msgItems.begin();
|
||||
RsGxsChannelPostItem* postItem =
|
||||
dynamic_cast<RsGxsChannelPostItem*>(*vit);
|
||||
|
||||
for(; vit != msgItems.end(); ++vit)
|
||||
if(postItem)
|
||||
{
|
||||
RsGxsChannelPostItem* postItem = dynamic_cast<RsGxsChannelPostItem*>(*vit);
|
||||
|
||||
if(postItem)
|
||||
RsGxsChannelPost msg;
|
||||
postItem->toChannelPost(msg, true);
|
||||
msgs.push_back(msg);
|
||||
delete postItem;
|
||||
}
|
||||
else
|
||||
{
|
||||
RsGxsCommentItem* cmtItem =
|
||||
dynamic_cast<RsGxsCommentItem*>(*vit);
|
||||
if(cmtItem)
|
||||
{
|
||||
RsGxsChannelPost msg;
|
||||
postItem->toChannelPost(msg, true);
|
||||
msgs.push_back(msg);
|
||||
delete postItem;
|
||||
RsGxsComment cmt;
|
||||
RsGxsMsgItem *mi = (*vit);
|
||||
cmt = cmtItem->mMsg;
|
||||
cmt.mMeta = mi->meta;
|
||||
#ifdef GXSCOMMENT_DEBUG
|
||||
std::cerr << "p3GxsChannels::getPostData Found Comment:" << std::endl;
|
||||
cmt.print(std::cerr," ", "cmt");
|
||||
#endif
|
||||
cmts.push_back(cmt);
|
||||
delete cmtItem;
|
||||
}
|
||||
else
|
||||
{
|
||||
RsGxsCommentItem* cmtItem = dynamic_cast<RsGxsCommentItem*>(*vit);
|
||||
if(cmtItem)
|
||||
{
|
||||
RsGxsComment cmt;
|
||||
RsGxsMsgItem *mi = (*vit);
|
||||
cmt = cmtItem->mMsg;
|
||||
cmt.mMeta = mi->meta;
|
||||
#ifdef GXSCOMMENT_DEBUG
|
||||
std::cerr << "p3GxsChannels::getPostData Found Comment:" << std::endl;
|
||||
cmt.print(std::cerr," ", "cmt");
|
||||
#endif
|
||||
cmts.push_back(cmt);
|
||||
delete cmtItem;
|
||||
}
|
||||
else
|
||||
{
|
||||
RsGxsMsgItem* msg = (*vit);
|
||||
//const uint16_t RS_SERVICE_GXS_TYPE_CHANNELS = 0x0217;
|
||||
//const uint8_t RS_PKT_SUBTYPE_GXSCHANNEL_POST_ITEM = 0x03;
|
||||
//const uint8_t RS_PKT_SUBTYPE_GXSCOMMENT_COMMENT_ITEM = 0xf1;
|
||||
std::cerr << "Not a GxsChannelPostItem neither a RsGxsCommentItem"
|
||||
<< " PacketService=" << std::hex << (int)msg->PacketService() << std::dec
|
||||
<< " PacketSubType=" << std::hex << (int)msg->PacketSubType() << std::dec
|
||||
<< " , deleting!" << std::endl;
|
||||
delete *vit;
|
||||
}
|
||||
RsGxsMsgItem* msg = (*vit);
|
||||
//const uint16_t RS_SERVICE_GXS_TYPE_CHANNELS = 0x0217;
|
||||
//const uint8_t RS_PKT_SUBTYPE_GXSCHANNEL_POST_ITEM = 0x03;
|
||||
//const uint8_t RS_PKT_SUBTYPE_GXSCOMMENT_COMMENT_ITEM = 0xf1;
|
||||
std::cerr << __PRETTY_FUNCTION__
|
||||
<< " Not a GxsChannelPostItem neither a "
|
||||
<< "RsGxsCommentItem PacketService=" << std::hex
|
||||
<< (int)msg->PacketService() << std::dec
|
||||
<< " PacketSubType=" << std::hex
|
||||
<< (int)msg->PacketSubType() << std::dec
|
||||
<< " , deleting!" << std::endl;
|
||||
delete *vit;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "p3GxsChannels::getPostData() ERROR in request";
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
|
||||
return ok;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool p3GxsChannels::getPostData(
|
||||
const uint32_t& token, std::vector<RsGxsChannelPost>& posts )
|
||||
{
|
||||
std::vector<RsGxsComment> cmts;
|
||||
return getPostData(token, posts, cmts);
|
||||
}
|
||||
|
||||
//Not currently used
|
||||
@ -548,21 +564,6 @@ bool p3GxsChannels::getPostData(const uint32_t &token, std::vector<RsGxsChannelP
|
||||
/********************************************************************************************/
|
||||
/********************************************************************************************/
|
||||
|
||||
#if 0
|
||||
bool p3GxsChannels::setChannelAutoDownload(uint32_t &token, const RsGxsGroupId &groupId, bool autoDownload)
|
||||
{
|
||||
std::cerr << "p3GxsChannels::setChannelAutoDownload()";
|
||||
std::cerr << std::endl;
|
||||
|
||||
// we don't actually use the token at this point....
|
||||
//bool p3GxsChannels::setAutoDownload(const RsGxsGroupId &groupId, bool enabled)
|
||||
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool p3GxsChannels::setChannelAutoDownload(const RsGxsGroupId &groupId, bool enabled)
|
||||
{
|
||||
return setAutoDownload(groupId, enabled);
|
||||
@ -574,36 +575,37 @@ bool p3GxsChannels::getChannelAutoDownload(const RsGxsGroupId &groupId, bool& en
|
||||
return autoDownloadEnabled(groupId,enabled);
|
||||
}
|
||||
|
||||
bool p3GxsChannels::setChannelDownloadDirectory(const RsGxsGroupId &groupId, const std::string& directory)
|
||||
bool p3GxsChannels::setChannelDownloadDirectory(
|
||||
const RsGxsGroupId &groupId, const std::string& directory )
|
||||
{
|
||||
#ifdef GXSCHANNELS_DEBUG
|
||||
std::cerr << "p3GxsChannels::setDownloadDirectory() id: " << groupId << " to: " << directory << std::endl;
|
||||
std::cerr << __PRETTY_FUNCTION__ << " id: " << groupId << " to: "
|
||||
<< directory << std::endl;
|
||||
#endif
|
||||
|
||||
RS_STACK_MUTEX(mSubscribedGroupsMutex);
|
||||
|
||||
std::map<RsGxsGroupId, RsGroupMetaData>::iterator it;
|
||||
|
||||
it = mSubscribedGroups.find(groupId);
|
||||
if (it == mSubscribedGroups.end())
|
||||
{
|
||||
#ifdef GXSCHANNELS_DEBUG
|
||||
std::cerr << "p3GxsChannels::setAutoDownload() Missing Group" << std::endl;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
it = mSubscribedGroups.find(groupId);
|
||||
if (it == mSubscribedGroups.end())
|
||||
{
|
||||
std::cerr << __PRETTY_FUNCTION__ << " Error! Unknown groupId: "
|
||||
<< groupId.toStdString() << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* extract from ServiceString */
|
||||
SSGxsChannelGroup ss;
|
||||
ss.load(it->second.mServiceString);
|
||||
|
||||
if (directory == ss.mDownloadDirectory)
|
||||
{
|
||||
#ifdef GXSCHANNELS_DEBUG
|
||||
std::cerr << "p3GxsChannels::setDownloadDirectory() WARNING setting looks okay already" << std::endl;
|
||||
#endif
|
||||
if (directory == ss.mDownloadDirectory)
|
||||
{
|
||||
std::cerr << __PRETTY_FUNCTION__ << " Warning! groupId: " << groupId
|
||||
<< " Was already configured to download into: " << directory
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* we are just going to set it anyway. */
|
||||
ss.mDownloadDirectory = directory;
|
||||
std::string serviceString = ss.save();
|
||||
uint32_t token;
|
||||
@ -611,6 +613,13 @@ bool p3GxsChannels::setChannelDownloadDirectory(const RsGxsGroupId &groupId, con
|
||||
it->second.mServiceString = serviceString; // update Local Cache.
|
||||
RsGenExchange::setGroupServiceString(token, groupId, serviceString); // update dbase.
|
||||
|
||||
if(waitToken(token) != RsTokenService::COMPLETE)
|
||||
{
|
||||
std::cerr << __PRETTY_FUNCTION__ << " Error! Feiled setting group "
|
||||
<< " service string" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* now reload it */
|
||||
std::list<RsGxsGroupId> groups;
|
||||
groups.push_back(groupId);
|
||||
@ -626,25 +635,24 @@ bool p3GxsChannels::getChannelDownloadDirectory(const RsGxsGroupId & groupId,std
|
||||
std::cerr << "p3GxsChannels::getChannelDownloadDirectory(" << id << ")" << std::endl;
|
||||
#endif
|
||||
|
||||
RS_STACK_MUTEX(mSubscribedGroupsMutex);
|
||||
|
||||
std::map<RsGxsGroupId, RsGroupMetaData>::iterator it;
|
||||
|
||||
it = mSubscribedGroups.find(groupId);
|
||||
|
||||
if (it == mSubscribedGroups.end())
|
||||
{
|
||||
#ifdef GXSCHANNELS_DEBUG
|
||||
std::cerr << "p3GxsChannels::getChannelDownloadDirectory() No Entry" << std::endl;
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
it = mSubscribedGroups.find(groupId);
|
||||
if (it == mSubscribedGroups.end())
|
||||
{
|
||||
std::cerr << __PRETTY_FUNCTION__ << " Error! Unknown groupId: "
|
||||
<< groupId.toStdString() << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* extract from ServiceString */
|
||||
SSGxsChannelGroup ss;
|
||||
ss.load(it->second.mServiceString);
|
||||
directory = ss.mDownloadDirectory;
|
||||
|
||||
return true ;
|
||||
return true;
|
||||
}
|
||||
|
||||
void p3GxsChannels::request_AllSubscribedGroups()
|
||||
@ -668,7 +676,8 @@ void p3GxsChannels::request_AllSubscribedGroups()
|
||||
}
|
||||
|
||||
|
||||
void p3GxsChannels::request_SpecificSubscribedGroups(const std::list<RsGxsGroupId> &groups)
|
||||
void p3GxsChannels::request_SpecificSubscribedGroups(
|
||||
const std::list<RsGxsGroupId> &groups )
|
||||
{
|
||||
#ifdef GXSCHANNELS_DEBUG
|
||||
std::cerr << "p3GxsChannels::request_SpecificSubscribedGroups()";
|
||||
@ -681,8 +690,19 @@ void p3GxsChannels::request_SpecificSubscribedGroups(const std::list<RsGxsGroupI
|
||||
|
||||
uint32_t token = 0;
|
||||
|
||||
RsGenExchange::getTokenService()->requestGroupInfo(token, ansType, opts, groups);
|
||||
GxsTokenQueue::queueRequest(token, GXSCHANNELS_SUBSCRIBED_META);
|
||||
if(!RsGenExchange::getTokenService()->
|
||||
requestGroupInfo(token, ansType, opts, groups))
|
||||
{
|
||||
std::cerr << __PRETTY_FUNCTION__ << " Failed requesting groups info!"
|
||||
<< std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if(!GxsTokenQueue::queueRequest(token, GXSCHANNELS_SUBSCRIBED_META))
|
||||
{
|
||||
std::cerr << __PRETTY_FUNCTION__ << " Failed queuing request!"
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -746,6 +766,7 @@ void p3GxsChannels::updateSubscribedGroup(const RsGroupMetaData &group)
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
RS_STACK_MUTEX(mSubscribedGroupsMutex);
|
||||
mSubscribedGroups[group.mGroupId] = group;
|
||||
}
|
||||
|
||||
@ -757,9 +778,8 @@ void p3GxsChannels::clearUnsubscribedGroup(const RsGxsGroupId &id)
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
//std::map<RsGxsGroupId, RsGrpMetaData> mSubscribedGroups;
|
||||
RS_STACK_MUTEX(mSubscribedGroupsMutex);
|
||||
std::map<RsGxsGroupId, RsGroupMetaData>::iterator it;
|
||||
|
||||
it = mSubscribedGroups.find(id);
|
||||
if (it != mSubscribedGroups.end())
|
||||
{
|
||||
@ -838,24 +858,20 @@ void p3GxsChannels::request_GroupUnprocessedPosts(const std::list<RsGxsGroupId>
|
||||
}
|
||||
|
||||
|
||||
void p3GxsChannels::load_SpecificUnprocessedPosts(const uint32_t &token)
|
||||
void p3GxsChannels::load_unprocessedPosts(uint32_t token)
|
||||
{
|
||||
#ifdef GXSCHANNELS_DEBUG
|
||||
std::cerr << "p3GxsChannels::load_SpecificUnprocessedPosts";
|
||||
std::cerr << std::endl;
|
||||
std::cerr << "p3GxsChannels::load_SpecificUnprocessedPosts" << std::endl;
|
||||
#endif
|
||||
|
||||
std::vector<RsGxsChannelPost> posts;
|
||||
if (!getPostData(token, posts))
|
||||
{
|
||||
#ifdef GXSCHANNELS_DEBUG
|
||||
std::cerr << "p3GxsChannels::load_SpecificUnprocessedPosts ERROR";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
std::cerr << __PRETTY_FUNCTION__ << " ERROR getting post data!"
|
||||
<< std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
std::vector<RsGxsChannelPost>::iterator it;
|
||||
for(it = posts.begin(); it != posts.end(); ++it)
|
||||
{
|
||||
@ -864,58 +880,27 @@ void p3GxsChannels::load_SpecificUnprocessedPosts(const uint32_t &token)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void p3GxsChannels::load_GroupUnprocessedPosts(const uint32_t &token)
|
||||
{
|
||||
#ifdef GXSCHANNELS_DEBUG
|
||||
std::cerr << "p3GxsChannels::load_GroupUnprocessedPosts";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
std::vector<RsGxsChannelPost> posts;
|
||||
if (!getPostData(token, posts))
|
||||
{
|
||||
#ifdef GXSCHANNELS_DEBUG
|
||||
std::cerr << "p3GxsChannels::load_GroupUnprocessedPosts ERROR";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
std::vector<RsGxsChannelPost>::iterator it;
|
||||
for(it = posts.begin(); it != posts.end(); ++it)
|
||||
{
|
||||
handleUnprocessedPost(*it);
|
||||
}
|
||||
}
|
||||
|
||||
void p3GxsChannels::handleUnprocessedPost(const RsGxsChannelPost &msg)
|
||||
{
|
||||
#ifdef GXSCHANNELS_DEBUG
|
||||
std::cerr << "p3GxsChannels::handleUnprocessedPost() GroupId: " << msg.mMeta.mGroupId << " MsgId: " << msg.mMeta.mMsgId;
|
||||
std::cerr << std::endl;
|
||||
std::cerr << __PRETTY_FUNCTION__ << " GroupId: " << msg.mMeta.mGroupId
|
||||
<< " MsgId: " << msg.mMeta.mMsgId << std::endl;
|
||||
#endif
|
||||
|
||||
if (!IS_MSG_UNPROCESSED(msg.mMeta.mMsgStatus))
|
||||
{
|
||||
std::cerr << "p3GxsChannels::handleUnprocessedPost() Msg already Processed";
|
||||
std::cerr << std::endl;
|
||||
std::cerr << "p3GxsChannels::handleUnprocessedPost() ERROR - this should not happen";
|
||||
std::cerr << std::endl;
|
||||
std::cerr << __PRETTY_FUNCTION__ << " ERROR Msg already Processed! "
|
||||
<< "mMsgId: " << msg.mMeta.mMsgId << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
bool enabled = false ;
|
||||
|
||||
/* check that autodownload is set */
|
||||
if (autoDownloadEnabled(msg.mMeta.mGroupId,enabled) && enabled )
|
||||
bool enabled = false;
|
||||
if (autoDownloadEnabled(msg.mMeta.mGroupId, enabled) && enabled)
|
||||
{
|
||||
|
||||
|
||||
#ifdef GXSCHANNELS_DEBUG
|
||||
std::cerr << "p3GxsChannels::handleUnprocessedPost() AutoDownload Enabled ... handling";
|
||||
std::cerr << std::endl;
|
||||
std::cerr << __PRETTY_FUNCTION__ << " AutoDownload Enabled... handling"
|
||||
<< std::endl;
|
||||
#endif
|
||||
|
||||
/* check the date is not too old */
|
||||
@ -928,8 +913,7 @@ void p3GxsChannels::handleUnprocessedPost(const RsGxsChannelPost &msg)
|
||||
// MORE THOUGHT HAS TO GO INTO THAT STUFF.
|
||||
|
||||
#ifdef GXSCHANNELS_DEBUG
|
||||
std::cerr << "p3GxsChannels::handleUnprocessedPost() START DOWNLOAD";
|
||||
std::cerr << std::endl;
|
||||
std::cerr << __PRETTY_FUNCTION__ << " START DOWNLOAD" << std::endl;
|
||||
#endif
|
||||
|
||||
std::list<RsGxsFile>::const_iterator fit;
|
||||
@ -951,8 +935,11 @@ void p3GxsChannels::handleUnprocessedPost(const RsGxsChannelPost &msg)
|
||||
|
||||
rsFiles->FileRequest(fname, hash, size, localpath, flags, srcIds);
|
||||
}
|
||||
else
|
||||
std::cerr << "WARNING: Channel file is not auto-downloaded because its size exceeds the threshold of " << CHANNEL_MAX_AUTO_DL << " bytes." << std::endl;
|
||||
else
|
||||
std::cerr << __PRETTY_FUNCTION__ << "Channel file is not auto-"
|
||||
<< "downloaded because its size exceeds the threshold"
|
||||
<< " of " << CHANNEL_MAX_AUTO_DL << " bytes."
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
@ -986,19 +973,18 @@ void p3GxsChannels::handleResponse(uint32_t token, uint32_t req_type)
|
||||
load_SubscribedGroups(token);
|
||||
break;
|
||||
|
||||
case GXSCHANNELS_UNPROCESSED_SPECIFIC:
|
||||
load_SpecificUnprocessedPosts(token);
|
||||
break;
|
||||
case GXSCHANNELS_UNPROCESSED_SPECIFIC:
|
||||
load_unprocessedPosts(token);
|
||||
break;
|
||||
|
||||
case GXSCHANNELS_UNPROCESSED_GENERIC:
|
||||
load_SpecificUnprocessedPosts(token);
|
||||
break;
|
||||
case GXSCHANNELS_UNPROCESSED_GENERIC:
|
||||
load_unprocessedPosts(token);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* error */
|
||||
std::cerr << "p3GxsService::handleResponse() Unknown Request Type: " << req_type;
|
||||
std::cerr << std::endl;
|
||||
break;
|
||||
default:
|
||||
std::cerr << __PRETTY_FUNCTION__ << "ERROR Unknown Request Type: "
|
||||
<< req_type << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1045,20 +1031,63 @@ bool p3GxsChannels::getChannelsContent(
|
||||
bool p3GxsChannels::createChannel(RsGxsChannelGroup& channel)
|
||||
{
|
||||
uint32_t token;
|
||||
if( !createGroup(token, channel)
|
||||
|| waitToken(token) != RsTokenService::COMPLETE )
|
||||
return false;
|
||||
|
||||
if(RsGenExchange::getPublishedGroupMeta(token, channel.mMeta))
|
||||
if(!createGroup(token, channel))
|
||||
{
|
||||
#ifdef RS_DEEP_SEARCH
|
||||
DeepSearch::indexChannelGroup(channel);
|
||||
#endif // RS_DEEP_SEARCH
|
||||
|
||||
return true;
|
||||
std::cerr << __PRETTY_FUNCTION__ << "Error! Failed updating group."
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
if(waitToken(token) != RsTokenService::COMPLETE)
|
||||
{
|
||||
std::cerr << __PRETTY_FUNCTION__ << "Error! GXS operation failed."
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!RsGenExchange::getPublishedGroupMeta(token, channel.mMeta))
|
||||
{
|
||||
std::cerr << __PRETTY_FUNCTION__ << "Error! Failure getting updated "
|
||||
<< " group data." << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef RS_DEEP_SEARCH
|
||||
DeepSearch::indexChannelGroup(channel);
|
||||
#endif // RS_DEEP_SEARCH
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool p3GxsChannels::editChannel(RsGxsChannelGroup& channel)
|
||||
{
|
||||
uint32_t token;
|
||||
if(!updateGroup(token, channel))
|
||||
{
|
||||
std::cerr << __PRETTY_FUNCTION__ << "Error! Failed updating group."
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(waitToken(token) != RsTokenService::COMPLETE)
|
||||
{
|
||||
std::cerr << __PRETTY_FUNCTION__ << "Error! GXS operation failed."
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!RsGenExchange::getPublishedGroupMeta(token, channel.mMeta))
|
||||
{
|
||||
std::cerr << __PRETTY_FUNCTION__ << "Error! Failure getting updated "
|
||||
<< " group data." << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef RS_DEEP_SEARCH
|
||||
DeepSearch::indexChannelGroup(channel);
|
||||
#endif // RS_DEEP_SEARCH
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool p3GxsChannels::createPost(RsGxsChannelPost& post)
|
||||
@ -1079,6 +1108,29 @@ bool p3GxsChannels::createPost(RsGxsChannelPost& post)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool p3GxsChannels::subscribeToChannel(
|
||||
const RsGxsGroupId& groupId, bool subscribe )
|
||||
{
|
||||
uint32_t token;
|
||||
if( !subscribeToGroup(token, groupId, subscribe)
|
||||
|| waitToken(token) != RsTokenService::COMPLETE ) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool p3GxsChannels::markRead(const RsGxsGrpMsgIdPair& msgId, bool read)
|
||||
{
|
||||
uint32_t token;
|
||||
setMessageReadStatus(token, msgId, read);
|
||||
if(waitToken(token) != RsTokenService::COMPLETE ) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool p3GxsChannels::shareChannelKeys(
|
||||
const RsGxsGroupId& channelId, const std::set<RsPeerId>& peers)
|
||||
{
|
||||
return groupShareKeys(channelId, peers);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Blocking API implementation end
|
||||
@ -1092,20 +1144,17 @@ bool p3GxsChannels::createPost(RsGxsChannelPost& post)
|
||||
bool p3GxsChannels::autoDownloadEnabled(const RsGxsGroupId &groupId,bool& enabled)
|
||||
{
|
||||
#ifdef GXSCHANNELS_DEBUG
|
||||
std::cerr << "p3GxsChannels::autoDownloadEnabled(" << id << ")";
|
||||
std::cerr << "p3GxsChannels::autoDownloadEnabled(" << groupId << ")";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
RS_STACK_MUTEX(mSubscribedGroupsMutex);
|
||||
std::map<RsGxsGroupId, RsGroupMetaData>::iterator it;
|
||||
|
||||
it = mSubscribedGroups.find(groupId);
|
||||
if (it == mSubscribedGroups.end())
|
||||
{
|
||||
#ifdef GXSCHANNELS_DEBUG
|
||||
std::cerr << "p3GxsChannels::autoDownloadEnabled() No Entry";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
std::cerr << __PRETTY_FUNCTION__ << " WARNING requested channel: "
|
||||
<< groupId << " is not subscribed" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1190,23 +1239,20 @@ std::string SSGxsChannelGroup::save() const
|
||||
return output;
|
||||
}
|
||||
|
||||
bool p3GxsChannels::setAutoDownload(const RsGxsGroupId &groupId, bool enabled)
|
||||
bool p3GxsChannels::setAutoDownload(const RsGxsGroupId& groupId, bool enabled)
|
||||
{
|
||||
#ifdef GXSCHANNELS_DEBUG
|
||||
std::cerr << "p3GxsChannels::setAutoDownload() id: " << groupId << " enabled: " << enabled;
|
||||
std::cerr << std::endl;
|
||||
std::cerr << __PRETTY_FUNCTION__ << " id: " << groupId
|
||||
<< " enabled: " << enabled << std::endl;
|
||||
#endif
|
||||
|
||||
RS_STACK_MUTEX(mSubscribedGroupsMutex);
|
||||
std::map<RsGxsGroupId, RsGroupMetaData>::iterator it;
|
||||
|
||||
it = mSubscribedGroups.find(groupId);
|
||||
if (it == mSubscribedGroups.end())
|
||||
{
|
||||
#ifdef GXSCHANNELS_DEBUG
|
||||
std::cerr << "p3GxsChannels::setAutoDownload() Missing Group";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
std::cerr << __PRETTY_FUNCTION__ << " ERROR requested channel: "
|
||||
<< groupId.toStdString() << " is not subscribed!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1215,27 +1261,21 @@ bool p3GxsChannels::setAutoDownload(const RsGxsGroupId &groupId, bool enabled)
|
||||
ss.load(it->second.mServiceString);
|
||||
if (enabled == ss.mAutoDownload)
|
||||
{
|
||||
/* it should be okay! */
|
||||
#ifdef GXSCHANNELS_DEBUG
|
||||
std::cerr << "p3GxsChannels::setAutoDownload() WARNING setting looks okay already";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
std::cerr << __PRETTY_FUNCTION__ << " WARNING mAutoDownload was already"
|
||||
<< " properly set to: " << enabled << " for channel:"
|
||||
<< groupId.toStdString() << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* we are just going to set it anyway. */
|
||||
ss.mAutoDownload = enabled;
|
||||
std::string serviceString = ss.save();
|
||||
|
||||
uint32_t token;
|
||||
RsGenExchange::setGroupServiceString(token, groupId, serviceString);
|
||||
|
||||
if(waitToken(token) != RsTokenService::COMPLETE) return false;
|
||||
|
||||
it->second.mServiceString = serviceString; // update Local Cache.
|
||||
RsGenExchange::setGroupServiceString(token, groupId, serviceString); // update dbase.
|
||||
|
||||
/* now reload it */
|
||||
std::list<RsGxsGroupId> groups;
|
||||
groups.push_back(groupId);
|
||||
|
||||
request_SpecificSubscribedGroups(groups);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -1604,7 +1644,7 @@ void p3GxsChannels::dummy_tick()
|
||||
|
||||
}
|
||||
|
||||
cleanTimedOutSearches();
|
||||
cleanTimedOutCallbacks();
|
||||
}
|
||||
|
||||
|
||||
@ -1776,7 +1816,7 @@ TurtleRequestId p3GxsChannels::turtleGroupRequest(const RsGxsGroupId& group_id)
|
||||
}
|
||||
TurtleRequestId p3GxsChannels::turtleSearchRequest(const std::string& match_string)
|
||||
{
|
||||
return netService()->turtleSearchRequest(match_string) ;
|
||||
return netService()->turtleSearchRequest(match_string);
|
||||
}
|
||||
|
||||
bool p3GxsChannels::clearDistantSearchResults(TurtleRequestId req)
|
||||
@ -1834,13 +1874,43 @@ bool p3GxsChannels::turtleSearchRequest(
|
||||
|
||||
TurtleRequestId sId = turtleSearchRequest(matchString);
|
||||
|
||||
{
|
||||
RS_STACK_MUTEX(mSearchCallbacksMapMutex);
|
||||
mSearchCallbacksMap.emplace(
|
||||
sId,
|
||||
std::make_pair(
|
||||
multiCallback,
|
||||
std::chrono::system_clock::now() +
|
||||
std::chrono::seconds(maxWait) ) );
|
||||
std::chrono::seconds(maxWait) ) );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// @see RsGxsChannels::turtleChannelRequest
|
||||
bool p3GxsChannels::turtleChannelRequest(
|
||||
const RsGxsGroupId& channelId,
|
||||
const std::function<void (const RsGxsChannelGroup& result)>& multiCallback,
|
||||
rstime_t maxWait)
|
||||
{
|
||||
if(channelId.isNull())
|
||||
{
|
||||
std::cerr << __PRETTY_FUNCTION__ << "Error! channelId can't be null!"
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
TurtleRequestId sId = turtleGroupRequest(channelId);
|
||||
|
||||
{
|
||||
RS_STACK_MUTEX(mDistantChannelsCallbacksMapMutex);
|
||||
mDistantChannelsCallbacksMap.emplace(
|
||||
sId,
|
||||
std::make_pair(
|
||||
multiCallback,
|
||||
std::chrono::system_clock::now() +
|
||||
std::chrono::seconds(maxWait) ) );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -1851,29 +1921,77 @@ void p3GxsChannels::receiveDistantSearchResults(
|
||||
std::cerr << __PRETTY_FUNCTION__ << "(" << id << ", " << grpId << ")"
|
||||
<< std::endl;
|
||||
|
||||
RsGenExchange::receiveDistantSearchResults(id, grpId);
|
||||
RsGxsGroupSummary gs;
|
||||
gs.mGroupId = grpId;
|
||||
netService()->retrieveDistantGroupSummary(grpId, gs);
|
||||
{
|
||||
RsGenExchange::receiveDistantSearchResults(id, grpId);
|
||||
RsGxsGroupSummary gs;
|
||||
gs.mGroupId = grpId;
|
||||
netService()->retrieveDistantGroupSummary(grpId, gs);
|
||||
|
||||
{
|
||||
RS_STACK_MUTEX(mSearchCallbacksMapMutex);
|
||||
auto cbpt = mSearchCallbacksMap.find(id);
|
||||
if(cbpt != mSearchCallbacksMap.end())
|
||||
{
|
||||
cbpt->second.first(gs);
|
||||
return;
|
||||
}
|
||||
} // end RS_STACK_MUTEX(mSearchCallbacksMapMutex);
|
||||
}
|
||||
|
||||
{
|
||||
RS_STACK_MUTEX(mDistantChannelsCallbacksMapMutex);
|
||||
auto cbpt = mDistantChannelsCallbacksMap.find(id);
|
||||
if(cbpt != mDistantChannelsCallbacksMap.end())
|
||||
{
|
||||
std::function<void (const RsGxsChannelGroup&)> callback =
|
||||
cbpt->second.first;
|
||||
RsThread::async([this, callback, grpId]()
|
||||
{
|
||||
std::list<RsGxsGroupId> chanIds({grpId});
|
||||
std::vector<RsGxsChannelGroup> channelsInfo;
|
||||
if(!getChannelsInfo(chanIds, channelsInfo))
|
||||
{
|
||||
std::cerr << __PRETTY_FUNCTION__ << " Error! Received "
|
||||
<< "distant channel result grpId: " << grpId
|
||||
<< " but failed getting channel info"
|
||||
<< std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
for(const RsGxsChannelGroup& chan : channelsInfo)
|
||||
callback(chan);
|
||||
} );
|
||||
|
||||
return;
|
||||
}
|
||||
} // RS_STACK_MUTEX(mDistantChannelsCallbacksMapMutex);
|
||||
}
|
||||
|
||||
void p3GxsChannels::cleanTimedOutCallbacks()
|
||||
{
|
||||
auto now = std::chrono::system_clock::now();
|
||||
|
||||
{
|
||||
RS_STACK_MUTEX(mSearchCallbacksMapMutex);
|
||||
auto cbpt = mSearchCallbacksMap.find(id);
|
||||
if(cbpt != mSearchCallbacksMap.end())
|
||||
cbpt->second.first(gs);
|
||||
} // end RS_STACK_MUTEX(mSearchCallbacksMapMutex);
|
||||
}
|
||||
for( auto cbpt = mSearchCallbacksMap.begin();
|
||||
cbpt != mSearchCallbacksMap.end(); )
|
||||
if(cbpt->second.second <= now)
|
||||
{
|
||||
clearDistantSearchResults(cbpt->first);
|
||||
cbpt = mSearchCallbacksMap.erase(cbpt);
|
||||
}
|
||||
else ++cbpt;
|
||||
} // RS_STACK_MUTEX(mSearchCallbacksMapMutex);
|
||||
|
||||
void p3GxsChannels::cleanTimedOutSearches()
|
||||
{
|
||||
RS_STACK_MUTEX(mSearchCallbacksMapMutex);
|
||||
auto now = std::chrono::system_clock::now();
|
||||
for( auto cbpt = mSearchCallbacksMap.begin();
|
||||
cbpt != mSearchCallbacksMap.end(); )
|
||||
if(cbpt->second.second <= now)
|
||||
{
|
||||
clearDistantSearchResults(cbpt->first);
|
||||
cbpt = mSearchCallbacksMap.erase(cbpt);
|
||||
}
|
||||
else ++cbpt;
|
||||
{
|
||||
RS_STACK_MUTEX(mDistantChannelsCallbacksMapMutex);
|
||||
for( auto cbpt = mDistantChannelsCallbacksMap.begin();
|
||||
cbpt != mDistantChannelsCallbacksMap.end(); )
|
||||
if(cbpt->second.second <= now)
|
||||
{
|
||||
clearDistantSearchResults(cbpt->first);
|
||||
cbpt = mDistantChannelsCallbacksMap.erase(cbpt);
|
||||
}
|
||||
else ++cbpt;
|
||||
} // RS_STACK_MUTEX(mDistantChannelsCallbacksMapMutex)
|
||||
}
|
||||
|
@ -83,7 +83,7 @@ public:
|
||||
|
||||
virtual bool getGroupData(const uint32_t &token, std::vector<RsGxsChannelGroup> &groups);
|
||||
virtual bool getPostData(const uint32_t &token, std::vector<RsGxsChannelPost> &posts, std::vector<RsGxsComment> &cmts);
|
||||
virtual bool getPostData(const uint32_t &token, std::vector<RsGxsChannelPost> &posts) { std::vector<RsGxsComment> cmts; return getPostData( token, posts, cmts);}
|
||||
virtual bool getPostData(const uint32_t &token, std::vector<RsGxsChannelPost> &posts);
|
||||
//Not currently used
|
||||
//virtual bool getRelatedPosts(const uint32_t &token, std::vector<RsGxsChannelPost> &posts);
|
||||
|
||||
@ -112,6 +112,12 @@ virtual bool getChannelDownloadDirectory(const RsGxsGroupId &groupId, std::strin
|
||||
const std::function<void (const RsGxsGroupSummary&)>& multiCallback,
|
||||
rstime_t maxWait = 300 );
|
||||
|
||||
/// @see RsGxsChannels::turtleChannelRequest
|
||||
virtual bool turtleChannelRequest(
|
||||
const RsGxsGroupId& channelId,
|
||||
const std::function<void (const RsGxsChannelGroup& result)>& multiCallback,
|
||||
rstime_t maxWait = 300 );
|
||||
|
||||
/**
|
||||
* Receive results from turtle search @see RsGenExchange @see RsNxsObserver
|
||||
* @see RsGxsNetService::receiveTurtleSearchResults
|
||||
@ -183,9 +189,22 @@ virtual bool ExtraFileRemove(const RsFileHash &hash);
|
||||
/// Implementation of @see RsGxsChannels::createChannel
|
||||
virtual bool createChannel(RsGxsChannelGroup& channel);
|
||||
|
||||
/// Implementation of @see RsGxsChannels::editChannel
|
||||
virtual bool editChannel(RsGxsChannelGroup& channel);
|
||||
|
||||
/// Implementation of @see RsGxsChannels::createPost
|
||||
virtual bool createPost(RsGxsChannelPost& post);
|
||||
|
||||
/// Implementation of @see RsGxsChannels::subscribeToChannel
|
||||
virtual bool subscribeToChannel( const RsGxsGroupId &groupId,
|
||||
bool subscribe );
|
||||
|
||||
/// Implementation of @see RsGxsChannels::setPostRead
|
||||
virtual bool markRead(const RsGxsGrpMsgIdPair& msgId, bool read);
|
||||
|
||||
virtual bool shareChannelKeys(
|
||||
const RsGxsGroupId& channelId, const std::set<RsPeerId>& peers );
|
||||
|
||||
protected:
|
||||
// Overloaded from GxsTokenQueue for Request callbacks.
|
||||
virtual void handleResponse(uint32_t token, uint32_t req_type);
|
||||
@ -201,10 +220,8 @@ static uint32_t channelsAuthenPolicy();
|
||||
void load_SubscribedGroups(const uint32_t &token);
|
||||
|
||||
void request_SpecificUnprocessedPosts(std::list<std::pair<RsGxsGroupId, RsGxsMessageId> > &ids);
|
||||
void load_SpecificUnprocessedPosts(const uint32_t &token);
|
||||
|
||||
void request_GroupUnprocessedPosts(const std::list<RsGxsGroupId> &grouplist);
|
||||
void load_GroupUnprocessedPosts(const uint32_t &token);
|
||||
void load_unprocessedPosts(uint32_t token);
|
||||
|
||||
void handleUnprocessedPost(const RsGxsChannelPost &msg);
|
||||
|
||||
@ -214,11 +231,6 @@ static uint32_t channelsAuthenPolicy();
|
||||
bool setAutoDownload(const RsGxsGroupId &groupId, bool enabled);
|
||||
bool autoDownloadEnabled(const RsGxsGroupId &groupId, bool &enabled);
|
||||
|
||||
|
||||
|
||||
std::map<RsGxsGroupId, RsGroupMetaData> mSubscribedGroups;
|
||||
|
||||
|
||||
// DUMMY DATA,
|
||||
virtual bool generateDummyData();
|
||||
|
||||
@ -246,14 +258,21 @@ bool generateGroup(uint32_t &token, std::string groupName);
|
||||
RsGxsMessageId mMsgId;
|
||||
};
|
||||
|
||||
std::map<RsGxsGroupId, RsGroupMetaData> mSubscribedGroups;
|
||||
RsMutex mSubscribedGroupsMutex;
|
||||
|
||||
/** G10h4ck: Is this stuff really used? And for what? BEGIN */
|
||||
uint32_t mGenToken;
|
||||
bool mGenActive;
|
||||
int mGenCount;
|
||||
std::vector<ChannelDummyRef> mGenRefs;
|
||||
RsGxsMessageId mGenThreadId;
|
||||
/** G10h4ck: Is this stuff really used? And for what? END */
|
||||
|
||||
p3GxsCommentService *mCommentService;
|
||||
std::map<RsGxsGroupId,rstime_t> mKnownChannels;
|
||||
p3GxsCommentService* mCommentService;
|
||||
|
||||
std::map<RsGxsGroupId,rstime_t> mKnownChannels;
|
||||
RsMutex mKnownChannelsMutex;
|
||||
|
||||
/** Store search callbacks with timeout*/
|
||||
std::map<
|
||||
@ -264,8 +283,17 @@ bool generateGroup(uint32_t &token, std::string groupName);
|
||||
> mSearchCallbacksMap;
|
||||
RsMutex mSearchCallbacksMapMutex;
|
||||
|
||||
/// Cleanup mSearchCallbacksMap
|
||||
void cleanTimedOutSearches();
|
||||
/** Store distant channels requests callbacks with timeout*/
|
||||
std::map<
|
||||
TurtleRequestId,
|
||||
std::pair<
|
||||
std::function<void (const RsGxsChannelGroup&)>,
|
||||
std::chrono::system_clock::time_point >
|
||||
> mDistantChannelsCallbacksMap;
|
||||
RsMutex mDistantChannelsCallbacksMapMutex;
|
||||
|
||||
/// Cleanup mSearchCallbacksMap and mDistantChannelsCallbacksMap
|
||||
void cleanTimedOutCallbacks();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -27,6 +27,8 @@
|
||||
#include <iostream>
|
||||
#include <unistd.h>
|
||||
#include <semaphore.h>
|
||||
#include <thread>
|
||||
#include <functional>
|
||||
|
||||
#include <util/rsmemory.h>
|
||||
#include "util/rstime.h"
|
||||
@ -239,7 +241,7 @@ pthread_t createThread(RsThread &thread);
|
||||
|
||||
class RsThread
|
||||
{
|
||||
public:
|
||||
public:
|
||||
RsThread();
|
||||
virtual ~RsThread() {}
|
||||
|
||||
@ -259,6 +261,17 @@ class RsThread
|
||||
|
||||
void ask_for_stop();
|
||||
|
||||
/**
|
||||
* Execute given function on another thread without blocking the caller
|
||||
* execution.
|
||||
* This can be generalized with variadic template, ATM it is enough to wrap
|
||||
* any kind of function call or job into a lambda which get no paramethers
|
||||
* and return nothing but can capture
|
||||
* This can be easly optimized later by using a thread pool
|
||||
*/
|
||||
static void async(const std::function<void()>& fn)
|
||||
{ std::thread(fn).detach(); }
|
||||
|
||||
protected:
|
||||
virtual void runloop() =0; /* called once the thread is started. Should be overloaded by subclasses. */
|
||||
void go() ; // this one calls runloop and also sets the flags correctly when the thread is finished running.
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
#include <QMenu>
|
||||
#include <QFileDialog>
|
||||
#include <QMetaObject>
|
||||
|
||||
#include <retroshare/rsfiles.h>
|
||||
|
||||
@ -33,6 +34,7 @@
|
||||
#include "gui/settings/rsharesettings.h"
|
||||
#include "gui/notifyqt.h"
|
||||
#include "gui/common/GroupTreeWidget.h"
|
||||
#include "util/qtthreadsutils.h"
|
||||
|
||||
class GxsChannelGroupInfoData : public RsUserdata
|
||||
{
|
||||
@ -275,17 +277,37 @@ QWidget *GxsChannelDialog::createCommentHeaderWidget(const RsGxsGroupId &grpId,
|
||||
void GxsChannelDialog::toggleAutoDownload()
|
||||
{
|
||||
RsGxsGroupId grpId = groupId();
|
||||
if (grpId.isNull()) {
|
||||
if (grpId.isNull()) return;
|
||||
|
||||
bool autoDownload;
|
||||
if(!rsGxsChannels->getChannelAutoDownload(grpId, autoDownload))
|
||||
{
|
||||
std::cerr << __PRETTY_FUNCTION__ << " failed to get autodownload value "
|
||||
<< "for channel: " << grpId.toStdString() << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
bool autoDownload ;
|
||||
|
||||
if(!rsGxsChannels->getChannelAutoDownload(grpId,autoDownload) || !rsGxsChannels->setChannelAutoDownload(grpId, !autoDownload))
|
||||
RsThread::async([this, grpId, autoDownload]()
|
||||
{
|
||||
std::cerr << "GxsChannelDialog::toggleAutoDownload() Auto Download failed to set";
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
if(!rsGxsChannels->setChannelAutoDownload(grpId, !autoDownload))
|
||||
{
|
||||
std::cerr << __PRETTY_FUNCTION__ << " failed to set autodownload "
|
||||
<< "for channel: " << grpId << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
RsQThreadUtils::postToObject( [=]()
|
||||
{
|
||||
/* Here it goes any code you want to be executed on the Qt Gui
|
||||
* thread, for example to update the data model with new information
|
||||
* after a blocking call to RetroShare API complete, note that
|
||||
* Qt::QueuedConnection is important!
|
||||
*/
|
||||
|
||||
std::cerr << __PRETTY_FUNCTION__ << " Has been executed on GUI "
|
||||
<< "thread but was scheduled by async thread" << std::endl;
|
||||
}, this );
|
||||
});
|
||||
}
|
||||
|
||||
void GxsChannelDialog::loadGroupSummaryToken(const uint32_t &token, std::list<RsGroupMetaData> &groupInfo, RsUserdata *&userdata)
|
||||
|
@ -31,8 +31,10 @@
|
||||
#include "gui/settings/rsharesettings.h"
|
||||
#include "gui/feeds/SubFileItem.h"
|
||||
#include "gui/notifyqt.h"
|
||||
#include <algorithm>
|
||||
#include "util/DateTime.h"
|
||||
#include "util/qtthreadsutils.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#define CHAN_DEFAULT_IMAGE ":/images/channels.png"
|
||||
|
||||
@ -621,13 +623,13 @@ bool GxsChannelPostsWidget::navigatePostItem(const RsGxsMessageId &msgId)
|
||||
|
||||
void GxsChannelPostsWidget::subscribeGroup(bool subscribe)
|
||||
{
|
||||
if (groupId().isNull()) {
|
||||
return;
|
||||
}
|
||||
RsGxsGroupId grpId(groupId());
|
||||
if (grpId.isNull()) return;
|
||||
|
||||
uint32_t token;
|
||||
rsGxsChannels->subscribeToGroup(token, groupId(), subscribe);
|
||||
// mChannelQueue->queueRequest(token, 0, RS_TOKREQ_ANSTYPE_ACK, TOKEN_TYPE_SUBSCRIBE_CHANGE);
|
||||
RsThread::async([=]()
|
||||
{
|
||||
rsGxsChannels->subscribeToChannel(grpId, subscribe);
|
||||
} );
|
||||
}
|
||||
|
||||
void GxsChannelPostsWidget::setAutoDownload(bool autoDl)
|
||||
@ -643,12 +645,35 @@ void GxsChannelPostsWidget::toggleAutoDownload()
|
||||
return;
|
||||
}
|
||||
|
||||
bool autoDownload ;
|
||||
if(!rsGxsChannels->getChannelAutoDownload(grpId,autoDownload) || !rsGxsChannels->setChannelAutoDownload(grpId, !autoDownload))
|
||||
bool autoDownload;
|
||||
if(!rsGxsChannels->getChannelAutoDownload(grpId, autoDownload))
|
||||
{
|
||||
std::cerr << "GxsChannelDialog::toggleAutoDownload() Auto Download failed to set";
|
||||
std::cerr << std::endl;
|
||||
std::cerr << __PRETTY_FUNCTION__ << " failed to get autodownload value "
|
||||
<< "for channel: " << grpId.toStdString() << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
RsThread::async([this, grpId, autoDownload]()
|
||||
{
|
||||
if(!rsGxsChannels->setChannelAutoDownload(grpId, !autoDownload))
|
||||
{
|
||||
std::cerr << __PRETTY_FUNCTION__ << " failed to set autodownload "
|
||||
<< "for channel: " << grpId.toStdString() << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
RsQThreadUtils::postToObject( [=]()
|
||||
{
|
||||
/* Here it goes any code you want to be executed on the Qt Gui
|
||||
* thread, for example to update the data model with new information
|
||||
* after a blocking call to RetroShare API complete, note that
|
||||
* Qt::QueuedConnection is important!
|
||||
*/
|
||||
|
||||
std::cerr << __PRETTY_FUNCTION__ << " Has been executed on GUI "
|
||||
<< "thread but was scheduled by async thread" << std::endl;
|
||||
}, this );
|
||||
});
|
||||
}
|
||||
|
||||
bool GxsChannelPostsWidget::insertGroupData(const uint32_t &token, RsGroupMetaData &metaData)
|
||||
|
@ -424,6 +424,7 @@ HEADERS += rshare.h \
|
||||
util/ObjectPainter.h \
|
||||
util/QtVersion.h \
|
||||
util/RsFile.h \
|
||||
util/qtthreadsutils.h \
|
||||
gui/profile/ProfileWidget.h \
|
||||
gui/profile/ProfileManager.h \
|
||||
gui/profile/StatusMessage.h \
|
||||
|
117
retroshare-gui/src/util/qtthreadsutils.h
Normal file
117
retroshare-gui/src/util/qtthreadsutils.h
Normal file
@ -0,0 +1,117 @@
|
||||
/*
|
||||
* RetroShare
|
||||
* Copyright (C) 2018 Gioacchino Mazzurco <gio@eigenlab.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
/* Thanks to KubaO which realeased original C++14 versions of this functions
|
||||
* under public domain license
|
||||
* https://github.com/KubaO/stackoverflown/blob/master/questions/metacall-21646467/main.cpp
|
||||
* https://github.com/KubaO/stackoverflown/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
#include <QtGlobal>
|
||||
#include <QtCore>
|
||||
#include <type_traits>
|
||||
|
||||
namespace RsQThreadUtils {
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
|
||||
|
||||
/**
|
||||
* @brief execute given function in the QThread where given QObject belongs
|
||||
*/
|
||||
template <typename F>
|
||||
void postToObject(F &&fun, QObject *obj = qApp)
|
||||
{
|
||||
if (qobject_cast<QThread*>(obj))
|
||||
qWarning() << "posting a call to a thread object - consider using postToThread";
|
||||
QObject src;
|
||||
auto type = obj->metaObject();
|
||||
QObject::connect( &src, &QObject::destroyed, obj,
|
||||
[fun, type, obj]
|
||||
{
|
||||
// ensure that the object is not being destructed
|
||||
if (obj->metaObject()->inherits(type)) fun();
|
||||
}, Qt::QueuedConnection );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief execute given function in the given QThread
|
||||
*/
|
||||
template <typename F>
|
||||
void postToThread(F &&fun, QThread *thread = qApp->thread())
|
||||
{
|
||||
QObject * obj = QAbstractEventDispatcher::instance(thread);
|
||||
Q_ASSERT(obj);
|
||||
QObject src;
|
||||
auto type = obj->metaObject();
|
||||
QObject::connect( &src, &QObject::destroyed, obj,
|
||||
[fun, type, obj]
|
||||
{
|
||||
// ensure that the object is not being destructed
|
||||
if (obj->metaObject()->inherits(type)) fun();
|
||||
}, Qt::QueuedConnection );
|
||||
}
|
||||
|
||||
#else // QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
|
||||
|
||||
template <typename F>
|
||||
struct FEvent : QEvent
|
||||
{
|
||||
using Fun = typename std::decay<F>::type;
|
||||
const QObject *const obj;
|
||||
const QMetaObject *const type = obj->metaObject();
|
||||
Fun fun;
|
||||
template <typename Fun>
|
||||
FEvent(const QObject *obj, Fun &&fun) :
|
||||
QEvent(QEvent::None), obj(obj), fun(std::forward<Fun>(fun)) {}
|
||||
~FEvent()
|
||||
{
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
|
||||
// ensure that the object is not being destructed
|
||||
if (obj->metaObject()->inherits(type)) fun();
|
||||
#else // QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
|
||||
fun();
|
||||
#endif // QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief execute given function in the QThread where given QObject belongs
|
||||
*/
|
||||
template <typename F>
|
||||
static void postToObject(F &&fun, QObject *obj = qApp)
|
||||
{
|
||||
if (qobject_cast<QThread*>(obj))
|
||||
qWarning() << "posting a call to a thread object - consider using postToThread";
|
||||
QCoreApplication::postEvent(obj, new FEvent<F>(obj, std::forward<F>(fun)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief execute given function in the given QThread
|
||||
*/
|
||||
template <typename F>
|
||||
static void postToThread(F &&fun, QThread *thread = qApp->thread())
|
||||
{
|
||||
QObject * obj = QAbstractEventDispatcher::instance(thread);
|
||||
Q_ASSERT(obj);
|
||||
QCoreApplication::postEvent(obj, new FEvent<F>(obj, std::forward<F>(fun)));
|
||||
}
|
||||
#endif // QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user