merged upstream/master

This commit is contained in:
csoler 2018-10-20 14:48:11 +02:00
commit 395cf57ece
No known key found for this signature in database
GPG Key ID: 7BCA522266C0804C
11 changed files with 154 additions and 117 deletions

View File

@ -39,7 +39,7 @@ libresapi_settings {
} }
libresapihttpserver { libresapihttpserver {
unix { linux-* {
webui_files.path = "$${DATA_DIR}/webui" webui_files.path = "$${DATA_DIR}/webui"
webui_files.files = webui/app.js webui/app.css webui/index.html webui_files.files = webui/app.js webui/app.css webui/index.html

View File

@ -264,7 +264,8 @@ private:
static std::string timetToXapianDate(const rstime_t& time) static std::string timetToXapianDate(const rstime_t& time)
{ {
char date[] = "YYYYMMDD\0"; char date[] = "YYYYMMDD\0";
std::strftime(date, 9, "%Y%m%d", std::gmtime(&time)); time_t tTime = static_cast<time_t>(time);
std::strftime(date, 9, "%Y%m%d", std::gmtime(&tTime));
return date; return date;
} }
}; };

View File

@ -1373,7 +1373,7 @@ int RsDataService::retrieveGxsGrpMetaData(RsGxsGrpMetaTemporaryMap& grp)
std::cerr << std::endl; std::cerr << std::endl;
#endif #endif
RsStackMutex stack(mDbMutex); RS_STACK_MUTEX(mDbMutex);
#ifdef RS_DATA_SERVICE_DEBUG_TIME #ifdef RS_DATA_SERVICE_DEBUG_TIME
rstime::RsScopeTimer timer(""); rstime::RsScopeTimer timer("");

View File

@ -1189,6 +1189,26 @@ bool RsGenExchange::getMsgRelatedList(const uint32_t &token, MsgRelatedIdResult
{ {
return mDataAccess->getMsgRelatedList(token, msgIds); return mDataAccess->getMsgRelatedList(token, msgIds);
} }
bool RsGenExchange::getPublishedMsgMeta(const uint32_t& token,RsMsgMetaData& meta)
{
auto it = mPublishedMsgs.find(token);
if(it == mPublishedMsgs.end())
return false ;
meta = it->second;
return true;
}
bool RsGenExchange::getPublishedGroupMeta(const uint32_t& token,RsGroupMetaData& meta)
{
auto it = mPublishedGrps.find(token);
if(it == mPublishedGrps.end())
return false ;
meta = it->second;
return true;
}
bool RsGenExchange::getGroupMeta(const uint32_t &token, std::list<RsGroupMetaData> &groupInfo) bool RsGenExchange::getGroupMeta(const uint32_t &token, std::list<RsGroupMetaData> &groupInfo)
{ {
@ -1639,12 +1659,13 @@ void RsGenExchange::receiveNewMessages(std::vector<RsNxsMsg *>& messages)
void RsGenExchange::receiveDistantSearchResults(TurtleRequestId id,const RsGxsGroupId &grpId) void RsGenExchange::receiveDistantSearchResults(TurtleRequestId id,const RsGxsGroupId &grpId)
{ {
std::cerr << __PRETTY_FUNCTION__ << " received result for request "
<< std::hex << id << std::dec << std::endl;
RS_STACK_MUTEX(mGenMtx); RS_STACK_MUTEX(mGenMtx);
RsGxsDistantSearchResultChange* gc = new RsGxsDistantSearchResultChange(id,grpId); RsGxsDistantSearchResultChange* gc = new RsGxsDistantSearchResultChange(id,grpId);
mNotifications.push_back(gc); mNotifications.push_back(gc);
std::cerr << "RsGenExchange::receiveDistantSearchResults(): received result for request " << std::hex << id << std::dec << std::endl;
} }
void RsGenExchange::notifyReceivePublishKey(const RsGxsGroupId &grpId) void RsGenExchange::notifyReceivePublishKey(const RsGxsGroupId &grpId)
@ -2164,7 +2185,7 @@ void RsGenExchange::publishMsgs()
#endif #endif
RsGxsMsgItem* msgItem = mit->second; RsGxsMsgItem* msgItem = mit->second;
const uint32_t& token = mit->first; uint32_t token = mit->first;
uint32_t size = mSerialiser->size(msgItem); uint32_t size = mSerialiser->size(msgItem);
char* mData = new char[size]; char* mData = new char[size];
@ -2279,6 +2300,9 @@ void RsGenExchange::publishMsgs()
computeHash(msg->msg, msg->metaData->mHash); computeHash(msg->msg, msg->metaData->mHash);
mDataAccess->addMsgData(msg); mDataAccess->addMsgData(msg);
mPublishedMsgs[token] = *msg->metaData;
delete msg ; delete msg ;
msgChangeMap[grpId].insert(msgId); msgChangeMap[grpId].insert(msgId);
@ -2669,6 +2693,7 @@ void RsGenExchange::publishGrps()
#warning csoler: TODO: grp->meta should be renamed grp->public_meta ! #warning csoler: TODO: grp->meta should be renamed grp->public_meta !
grp->meta.setBinData(metaData, mdSize); grp->meta.setBinData(metaData, mdSize);
} }
mPublishedGrps[ggps.mToken] = *grp->metaData ; // save the connexion between the token and the created metadata, without private keys
// Place back private keys for publisher and database storage // Place back private keys for publisher and database storage
grp->metaData->keys.private_keys = fullKeySet.private_keys; grp->metaData->keys.private_keys = fullKeySet.private_keys;

View File

@ -242,6 +242,21 @@ public:
*/ */
bool getMsgRelatedMeta(const uint32_t &token, GxsMsgRelatedMetaMap& msgMeta); bool getMsgRelatedMeta(const uint32_t &token, GxsMsgRelatedMetaMap& msgMeta);
/*!
* Retrieves the meta data of a newly created group. The meta is kept in cache for the current session.
* \param token token that was used to create the group
* \param meta meta data for this group
* \return false if the group is not yet created.
*/
bool getPublishedGroupMeta(const uint32_t& token,RsGroupMetaData& meta);
/*!
* Retrieves the meta data of a newly created post. The meta is kept in cache for the current session.
* \param token token that was used to create the post
* \param meta meta data for this post
* \return false if the group is not yet created.
*/
bool getPublishedMsgMeta(const uint32_t& token,RsMsgMetaData& meta);
/*! /*!
* Gxs services should call this for automatic handling of * Gxs services should call this for automatic handling of
@ -883,6 +898,9 @@ private:
std::vector<GxsGrpPendingSign> mGrpsToPublish; std::vector<GxsGrpPendingSign> mGrpsToPublish;
typedef std::vector<GxsGrpPendingSign> NxsGrpSignPendVect; typedef std::vector<GxsGrpPendingSign> NxsGrpSignPendVect;
std::map<uint32_t,RsGxsGrpMetaData> mPublishedGrps ; // keeps track of which group was created using which token
std::map<uint32_t,RsGxsMsgMetaData> mPublishedMsgs ; // keeps track of which message was created using which token
std::map<uint32_t, RsGxsMsgItem*> mMsgsToPublish; std::map<uint32_t, RsGxsMsgItem*> mMsgsToPublish;
std::map<uint32_t, RsGxsGrpMsgIdPair > mMsgNotify; std::map<uint32_t, RsGxsGrpMsgIdPair > mMsgNotify;

View File

@ -5140,11 +5140,13 @@ TurtleRequestId RsGxsNetService::turtleSearchRequest(const std::string& match_st
return mGxsNetTunnel->turtleSearchRequest(match_string,this) ; return mGxsNetTunnel->turtleSearchRequest(match_string,this) ;
} }
#ifndef RS_DEEP_SEARCH
static bool termSearch(const std::string& src, const std::string& substring) static bool termSearch(const std::string& src, const std::string& substring)
{ {
/* always ignore case */ /* always ignore case */
return src.end() != std::search( src.begin(), src.end(), substring.begin(), substring.end(), RsRegularExpression::CompareCharIC() ); return src.end() != std::search( src.begin(), src.end(), substring.begin(), substring.end(), RsRegularExpression::CompareCharIC() );
} }
#endif // ndef RS_DEEP_SEARCH
bool RsGxsNetService::retrieveDistantSearchResults(TurtleRequestId req,std::map<RsGxsGroupId,RsGxsGroupSummary>& group_infos) bool RsGxsNetService::retrieveDistantSearchResults(TurtleRequestId req,std::map<RsGxsGroupId,RsGxsGroupSummary>& group_infos)
{ {
@ -5179,7 +5181,9 @@ bool RsGxsNetService::clearDistantSearchResults(const TurtleRequestId& id)
mDistantSearchResults.erase(id); mDistantSearchResults.erase(id);
return true ; return true ;
} }
void RsGxsNetService::receiveTurtleSearchResults(TurtleRequestId req, const std::list<RsGxsGroupSummary>& group_infos)
void RsGxsNetService::receiveTurtleSearchResults(
TurtleRequestId req, const std::list<RsGxsGroupSummary>& group_infos )
{ {
std::set<RsGxsGroupId> groupsToNotifyResults; std::set<RsGxsGroupId> groupsToNotifyResults;
@ -5190,36 +5194,40 @@ void RsGxsNetService::receiveTurtleSearchResults(TurtleRequestId req, const std:
std::map<RsGxsGroupId,RsGxsGroupSummary>& std::map<RsGxsGroupId,RsGxsGroupSummary>&
search_results_map(mDistantSearchResults[req]); search_results_map(mDistantSearchResults[req]);
for(auto it(group_infos.begin());it!=group_infos.end();++it) for(const RsGxsGroupSummary& gps : group_infos)
if(search_results_map.find((*it).mGroupId) == search_results_map.end()) if(search_results_map.find(gps.mGroupId) == search_results_map.end())
grpMeta[(*it).mGroupId] = NULL; grpMeta[gps.mGroupId] = nullptr;
mDataStore->retrieveGxsGrpMetaData(grpMeta); mDataStore->retrieveGxsGrpMetaData(grpMeta);
// only keep groups that are not locally known, and groups that are not already in the mDistantSearchResults structure for (const RsGxsGroupSummary& gps : group_infos)
for(auto it(group_infos.begin());it!=group_infos.end();++it)
if(grpMeta[(*it).mGroupId] == NULL)
{ {
const RsGxsGroupId& grpId((*it).mGroupId); #ifndef RS_DEEP_SEARCH
/* Only keep groups that are not locally known, and groups that are
* not already in the mDistantSearchResults structure. */
if(grpMeta[gps.mGroupId]) continue;
#else // ndef RS_DEEP_SEARCH
/* When deep search is enabled search results may bring more info
* then we already have also about post that are indexed by xapian,
* so we don't apply this filter in this case. */
#endif
const RsGxsGroupId& grpId(gps.mGroupId);
groupsToNotifyResults.insert(grpId); groupsToNotifyResults.insert(grpId);
auto it2 = search_results_map.find(grpId); auto it2 = search_results_map.find(grpId);
if(it2 != search_results_map.end()) if(it2 != search_results_map.end())
{ {
// update existing data // update existing data
RsGxsGroupSummary& eGpS(it2->second);
it2->second.mPopularity++; eGpS.mPopularity++;
it2->second.mNumberOfMessages = std::max( eGpS.mNumberOfMessages = std::max(
it2->second.mNumberOfMessages, eGpS.mNumberOfMessages,
(*it).mNumberOfMessages ); gps.mNumberOfMessages );
} }
else else
{ {
search_results_map[grpId] = *it; search_results_map[grpId] = gps;
search_results_map[grpId].mPopularity = 1; // number of results so far // number of results so far
search_results_map[grpId].mPopularity = 1;
} }
} }
} // end RS_STACK_MUTEX(mNxsMutex); } // end RS_STACK_MUTEX(mNxsMutex);

View File

@ -118,6 +118,54 @@ JsonApiServer::JsonApiServer(uint16_t port, const std::string& bindAddress,
mNewAccessRequestCallback(newAccessRequestCallback), mNewAccessRequestCallback(newAccessRequestCallback),
configMutex("JsonApiServer config") configMutex("JsonApiServer config")
{ {
registerHandler("/rsLoginHelper/createLocation",
[this](const std::shared_ptr<rb::Session> session)
{
size_t reqSize = session->get_request()->get_header("Content-Length", 0);
session->fetch( reqSize, [this](
const std::shared_ptr<rb::Session> session,
const rb::Bytes& body )
{
INITIALIZE_API_CALL_JSON_CONTEXT;
RsLoginHelper::Location location;
std::string password;
std::string errorMessage;
bool makeHidden = false;
bool makeAutoTor = false;
// deserialize input parameters from JSON
{
RsGenericSerializer::SerializeContext& ctx(cReq);
RsGenericSerializer::SerializeJob j(RsGenericSerializer::FROM_JSON);
RS_SERIAL_PROCESS(location);
RS_SERIAL_PROCESS(password);
RS_SERIAL_PROCESS(makeHidden);
RS_SERIAL_PROCESS(makeAutoTor);
}
// call retroshare C++ API
bool retval = rsLoginHelper->createLocation(
location, password, errorMessage, makeHidden,
makeAutoTor );
if(retval)
authorizeToken(location.mLocationId.toStdString()+":"+password);
// serialize out parameters and return value to JSON
{
RsGenericSerializer::SerializeContext& ctx(cAns);
RsGenericSerializer::SerializeJob j(RsGenericSerializer::TO_JSON);
RS_SERIAL_PROCESS(location);
RS_SERIAL_PROCESS(errorMessage);
RS_SERIAL_PROCESS(retval);
}
// return them to the API caller
DEFAULT_API_CALL_JSON_RETURN(rb::OK);
} );
}, false);
registerHandler("/rsLoginHelper/attemptLogin", registerHandler("/rsLoginHelper/attemptLogin",
[this](const std::shared_ptr<rb::Session> session) [this](const std::shared_ptr<rb::Session> session)
{ {

View File

@ -292,20 +292,20 @@ struct RsLoginHelper
/** /**
* @brief Creates a new RetroShare location, and log in once is created * @brief Creates a new RetroShare location, and log in once is created
* @jsonapi{development,unauthenticated} * @jsonapi{development,manualwrapper}
* @param[inout] location provide input information to generate the location * @param[inout] location provide input information to generate the location
* and storage to output the data of the generated location * and storage to output the data of the generated location
* @param[in] password to protect and unlock the associated PGP key * @param[in] password to protect and unlock the associated PGP key
* @param[out] errorMessage if some error occurred human readable error
* message
* @param[in] makeHidden pass true to create an hidden location. UNTESTED! * @param[in] makeHidden pass true to create an hidden location. UNTESTED!
* @param[in] makeAutoTor pass true to create an automatically configured * @param[in] makeAutoTor pass true to create an automatically configured
* Tor hidden location. UNTESTED! * Tor hidden location. UNTESTED!
* @param[out] errorMessage if some error occurred human readable error
* message
* @return true if success, false otherwise * @return true if success, false otherwise
*/ */
bool createLocation( RsLoginHelper::Location& location, bool createLocation( RsLoginHelper::Location& location,
const std::string& password, bool makeHidden, const std::string& password, std::string& errorMessage,
bool makeAutoTor, std::string& errorMessage ); bool makeHidden = false, bool makeAutoTor = false );
/** /**
* @brief Check if RetroShare is already logged in, this usually return true * @brief Check if RetroShare is already logged in, this usually return true

View File

@ -1952,7 +1952,7 @@ void RsLoginHelper::getLocations(std::vector<RsLoginHelper::Location>& store)
bool RsLoginHelper::createLocation( bool RsLoginHelper::createLocation(
RsLoginHelper::Location& l, const std::string& password, RsLoginHelper::Location& l, const std::string& password,
bool makeHidden, bool makeAutoTor, std::string& errorMessage ) std::string& errorMessage, bool makeHidden, bool makeAutoTor )
{ {
if(isLoggedIn()) return (errorMessage="Already Running", false); if(isLoggedIn()) return (errorMessage="Already Running", false);

View File

@ -1045,102 +1045,38 @@ bool p3GxsChannels::getChannelsContent(
bool p3GxsChannels::createChannel(RsGxsChannelGroup& channel) bool p3GxsChannels::createChannel(RsGxsChannelGroup& channel)
{ {
uint32_t token; uint32_t token;
time_t beginCreation = time(nullptr);
if( !createGroup(token, channel) if( !createGroup(token, channel)
|| waitToken(token) != RsTokenService::COMPLETE ) || waitToken(token) != RsTokenService::COMPLETE )
return false; return false;
time_t endCreation = time(nullptr);
std::list<RsGroupMetaData> channels; if(RsGenExchange::getPublishedGroupMeta(token, channel.mMeta))
if(!getChannelsSummaries(channels)) return false;
/* This is ugly but after digging and doing many tries of doing it the right
* way ending always into too big refactor chain reaction, I think this is
* not that bad, moreover seems the last created group tend to end up near
* the beginning of the list so it is fast founding it.
* The shortcoming of this is that if groups with same data are created in
* a burst (more then once in a second) is that the id of another similar
* group can be returned, but this is a pointy case.
* Order of conditions in the `if` matter for performances */
bool found = false;
for(const RsGroupMetaData& chan : channels)
{ {
if( IS_GROUP_ADMIN(chan.mSubscribeFlags)
&& IS_GROUP_SUBSCRIBED(chan.mSubscribeFlags)
&& chan.mPublishTs >= beginCreation
&& chan.mPublishTs <= endCreation
&& chan.mGroupFlags == channel.mMeta.mGroupFlags
&& chan.mSignFlags == channel.mMeta.mSignFlags
&& chan.mCircleType == channel.mMeta.mCircleType
&& chan.mAuthorId == channel.mMeta.mAuthorId
&& chan.mCircleId == channel.mMeta.mCircleId
&& chan.mServiceString == channel.mMeta.mServiceString
&& chan.mGroupName == channel.mMeta.mGroupName )
{
channel.mMeta = chan;
found = true;
break;
}
}
#ifdef RS_DEEP_SEARCH #ifdef RS_DEEP_SEARCH
if(found) DeepSearch::indexChannelGroup(channel); DeepSearch::indexChannelGroup(channel);
#endif // RS_DEEP_SEARCH #endif // RS_DEEP_SEARCH
return found; return true;
}
return false;
} }
bool p3GxsChannels::createPost(RsGxsChannelPost& post) bool p3GxsChannels::createPost(RsGxsChannelPost& post)
{ {
uint32_t token; uint32_t token;
time_t beginCreation = time(nullptr);
if( !createPost(token, post) if( !createPost(token, post)
|| waitToken(token) != RsTokenService::COMPLETE ) return false; || waitToken(token) != RsTokenService::COMPLETE ) return false;
time_t endCreation = time(nullptr);
std::list<RsGxsGroupId> chanIds; chanIds.push_back(post.mMeta.mGroupId); if(RsGenExchange::getPublishedMsgMeta(token,post.mMeta))
std::vector<RsGxsChannelPost> posts;
std::vector<RsGxsComment> comments;
if(!getChannelsContent(chanIds, posts, comments)) return false;
/* This is ugly but after digging and doing many tries of doing it the right
* way ending always into too big refactor chain reaction, I think this is
* not that bad.
* The shortcoming of this is that if posts with same data are created in
* a burst (more then once in a second) is that the id of another similar
* post could be returned, but this is a pointy case.
* Order of conditions in the `if` matter for performances */
bool found = false;
for(const RsGxsChannelPost& itPost : posts)
{ {
std::cout << __PRETTY_FUNCTION__ << " " << beginCreation << " "
<< itPost.mMeta.mPublishTs << " " << endCreation << " "
<< itPost.mMeta.mMsgId << std::endl;
if( itPost.mMeta.mPublishTs >= beginCreation
&& itPost.mMeta.mPublishTs <= endCreation
&& itPost.mMeta.mMsgFlags == post.mMeta.mMsgFlags
&& itPost.mMeta.mGroupId == post.mMeta.mGroupId
&& itPost.mMeta.mThreadId == post.mMeta.mThreadId
&& itPost.mMeta.mParentId == post.mMeta.mParentId
&& itPost.mMeta.mAuthorId == post.mMeta.mAuthorId
&& itPost.mMeta.mMsgName == post.mMeta.mMsgName
&& itPost.mFiles.size() == post.mFiles.size()
&& itPost.mMeta.mServiceString == post.mMeta.mServiceString
&& itPost.mOlderVersions == post.mOlderVersions
&& itPost.mMsg == post.mMsg )
{
post = itPost;
found = true;
break;
}
}
#ifdef RS_DEEP_SEARCH #ifdef RS_DEEP_SEARCH
if(found) DeepSearch::indexChannelPost(post); DeepSearch::indexChannelPost(post);
#endif // RS_DEEP_SEARCH #endif // RS_DEEP_SEARCH
return found; return true;
}
return false;
} }

View File

@ -114,10 +114,11 @@ virtual bool getChannelDownloadDirectory(const RsGxsGroupId &groupId, std::strin
/** /**
* Receive results from turtle search @see RsGenExchange @see RsNxsObserver * Receive results from turtle search @see RsGenExchange @see RsNxsObserver
* @see RsGxsNetService::receiveTurtleSearchResults
* @see p3turtle::handleSearchResult * @see p3turtle::handleSearchResult
*/ */
void receiveDistantSearchResults( TurtleRequestId id, void receiveDistantSearchResults( TurtleRequestId id,
const RsGxsGroupId& grpId ); const RsGxsGroupId& grpId ) override;
/* Comment service - Provide RsGxsCommentService - redirect to p3GxsCommentService */ /* Comment service - Provide RsGxsCommentService - redirect to p3GxsCommentService */
virtual bool getCommentData(uint32_t token, std::vector<RsGxsComment> &msgs) virtual bool getCommentData(uint32_t token, std::vector<RsGxsComment> &msgs)