mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-10-01 02:35:48 -04:00
merged upstream/master
This commit is contained in:
commit
395cf57ece
@ -39,7 +39,7 @@ libresapi_settings {
|
||||
}
|
||||
|
||||
libresapihttpserver {
|
||||
unix {
|
||||
linux-* {
|
||||
|
||||
webui_files.path = "$${DATA_DIR}/webui"
|
||||
webui_files.files = webui/app.js webui/app.css webui/index.html
|
||||
|
@ -264,7 +264,8 @@ private:
|
||||
static std::string timetToXapianDate(const rstime_t& time)
|
||||
{
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
@ -1373,7 +1373,7 @@ int RsDataService::retrieveGxsGrpMetaData(RsGxsGrpMetaTemporaryMap& grp)
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
RsStackMutex stack(mDbMutex);
|
||||
RS_STACK_MUTEX(mDbMutex);
|
||||
|
||||
#ifdef RS_DATA_SERVICE_DEBUG_TIME
|
||||
rstime::RsScopeTimer timer("");
|
||||
|
@ -1189,6 +1189,26 @@ bool RsGenExchange::getMsgRelatedList(const uint32_t &token, MsgRelatedIdResult
|
||||
{
|
||||
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)
|
||||
{
|
||||
@ -1639,12 +1659,13 @@ void RsGenExchange::receiveNewMessages(std::vector<RsNxsMsg *>& messages)
|
||||
|
||||
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);
|
||||
|
||||
RsGxsDistantSearchResultChange* gc = new RsGxsDistantSearchResultChange(id,grpId);
|
||||
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)
|
||||
@ -2164,7 +2185,7 @@ void RsGenExchange::publishMsgs()
|
||||
#endif
|
||||
|
||||
RsGxsMsgItem* msgItem = mit->second;
|
||||
const uint32_t& token = mit->first;
|
||||
uint32_t token = mit->first;
|
||||
|
||||
uint32_t size = mSerialiser->size(msgItem);
|
||||
char* mData = new char[size];
|
||||
@ -2279,6 +2300,9 @@ void RsGenExchange::publishMsgs()
|
||||
|
||||
computeHash(msg->msg, msg->metaData->mHash);
|
||||
mDataAccess->addMsgData(msg);
|
||||
|
||||
mPublishedMsgs[token] = *msg->metaData;
|
||||
|
||||
delete msg ;
|
||||
|
||||
msgChangeMap[grpId].insert(msgId);
|
||||
@ -2669,6 +2693,7 @@ void RsGenExchange::publishGrps()
|
||||
#warning csoler: TODO: grp->meta should be renamed grp->public_meta !
|
||||
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
|
||||
grp->metaData->keys.private_keys = fullKeySet.private_keys;
|
||||
|
@ -242,6 +242,21 @@ public:
|
||||
*/
|
||||
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
|
||||
@ -883,6 +898,9 @@ private:
|
||||
std::vector<GxsGrpPendingSign> mGrpsToPublish;
|
||||
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, RsGxsGrpMsgIdPair > mMsgNotify;
|
||||
|
@ -5140,11 +5140,13 @@ TurtleRequestId RsGxsNetService::turtleSearchRequest(const std::string& match_st
|
||||
return mGxsNetTunnel->turtleSearchRequest(match_string,this) ;
|
||||
}
|
||||
|
||||
#ifndef RS_DEEP_SEARCH
|
||||
static bool termSearch(const std::string& src, const std::string& substring)
|
||||
{
|
||||
/* always ignore case */
|
||||
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)
|
||||
{
|
||||
@ -5179,7 +5181,9 @@ bool RsGxsNetService::clearDistantSearchResults(const TurtleRequestId& id)
|
||||
mDistantSearchResults.erase(id);
|
||||
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;
|
||||
|
||||
@ -5190,36 +5194,40 @@ void RsGxsNetService::receiveTurtleSearchResults(TurtleRequestId req, const std:
|
||||
std::map<RsGxsGroupId,RsGxsGroupSummary>&
|
||||
search_results_map(mDistantSearchResults[req]);
|
||||
|
||||
for(auto it(group_infos.begin());it!=group_infos.end();++it)
|
||||
if(search_results_map.find((*it).mGroupId) == search_results_map.end())
|
||||
grpMeta[(*it).mGroupId] = NULL;
|
||||
|
||||
for(const RsGxsGroupSummary& gps : group_infos)
|
||||
if(search_results_map.find(gps.mGroupId) == search_results_map.end())
|
||||
grpMeta[gps.mGroupId] = nullptr;
|
||||
mDataStore->retrieveGxsGrpMetaData(grpMeta);
|
||||
|
||||
// only keep groups that are not locally known, and groups that are not already in the mDistantSearchResults structure
|
||||
|
||||
for(auto it(group_infos.begin());it!=group_infos.end();++it)
|
||||
if(grpMeta[(*it).mGroupId] == NULL)
|
||||
for (const RsGxsGroupSummary& gps : group_infos)
|
||||
{
|
||||
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);
|
||||
|
||||
auto it2 = search_results_map.find(grpId);
|
||||
|
||||
if(it2 != search_results_map.end())
|
||||
{
|
||||
// update existing data
|
||||
|
||||
it2->second.mPopularity++;
|
||||
it2->second.mNumberOfMessages = std::max(
|
||||
it2->second.mNumberOfMessages,
|
||||
(*it).mNumberOfMessages );
|
||||
RsGxsGroupSummary& eGpS(it2->second);
|
||||
eGpS.mPopularity++;
|
||||
eGpS.mNumberOfMessages = std::max(
|
||||
eGpS.mNumberOfMessages,
|
||||
gps.mNumberOfMessages );
|
||||
}
|
||||
else
|
||||
{
|
||||
search_results_map[grpId] = *it;
|
||||
search_results_map[grpId].mPopularity = 1; // number of results so far
|
||||
search_results_map[grpId] = gps;
|
||||
// number of results so far
|
||||
search_results_map[grpId].mPopularity = 1;
|
||||
}
|
||||
}
|
||||
} // end RS_STACK_MUTEX(mNxsMutex);
|
||||
|
@ -118,6 +118,54 @@ JsonApiServer::JsonApiServer(uint16_t port, const std::string& bindAddress,
|
||||
mNewAccessRequestCallback(newAccessRequestCallback),
|
||||
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",
|
||||
[this](const std::shared_ptr<rb::Session> session)
|
||||
{
|
||||
|
@ -292,20 +292,20 @@ struct RsLoginHelper
|
||||
|
||||
/**
|
||||
* @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
|
||||
* and storage to output the data of the generated location
|
||||
* @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] makeAutoTor pass true to create an automatically configured
|
||||
* Tor hidden location. UNTESTED!
|
||||
* @param[out] errorMessage if some error occurred human readable error
|
||||
* message
|
||||
* @return true if success, false otherwise
|
||||
*/
|
||||
bool createLocation( RsLoginHelper::Location& location,
|
||||
const std::string& password, bool makeHidden,
|
||||
bool makeAutoTor, std::string& errorMessage );
|
||||
const std::string& password, std::string& errorMessage,
|
||||
bool makeHidden = false, bool makeAutoTor = false );
|
||||
|
||||
/**
|
||||
* @brief Check if RetroShare is already logged in, this usually return true
|
||||
|
@ -1952,7 +1952,7 @@ void RsLoginHelper::getLocations(std::vector<RsLoginHelper::Location>& store)
|
||||
|
||||
bool RsLoginHelper::createLocation(
|
||||
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);
|
||||
|
||||
|
@ -1045,102 +1045,38 @@ bool p3GxsChannels::getChannelsContent(
|
||||
bool p3GxsChannels::createChannel(RsGxsChannelGroup& channel)
|
||||
{
|
||||
uint32_t token;
|
||||
time_t beginCreation = time(nullptr);
|
||||
if( !createGroup(token, channel)
|
||||
|| waitToken(token) != RsTokenService::COMPLETE )
|
||||
return false;
|
||||
time_t endCreation = time(nullptr);
|
||||
|
||||
std::list<RsGroupMetaData> channels;
|
||||
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(RsGenExchange::getPublishedGroupMeta(token, channel.mMeta))
|
||||
{
|
||||
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
|
||||
if(found) DeepSearch::indexChannelGroup(channel);
|
||||
DeepSearch::indexChannelGroup(channel);
|
||||
#endif // RS_DEEP_SEARCH
|
||||
|
||||
return found;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool p3GxsChannels::createPost(RsGxsChannelPost& post)
|
||||
{
|
||||
uint32_t token;
|
||||
time_t beginCreation = time(nullptr);
|
||||
if( !createPost(token, post)
|
||||
|| waitToken(token) != RsTokenService::COMPLETE ) return false;
|
||||
time_t endCreation = time(nullptr);
|
||||
|
||||
std::list<RsGxsGroupId> chanIds; chanIds.push_back(post.mMeta.mGroupId);
|
||||
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)
|
||||
if(RsGenExchange::getPublishedMsgMeta(token,post.mMeta))
|
||||
{
|
||||
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
|
||||
if(found) DeepSearch::indexChannelPost(post);
|
||||
DeepSearch::indexChannelPost(post);
|
||||
#endif // RS_DEEP_SEARCH
|
||||
|
||||
return found;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
@ -114,10 +114,11 @@ virtual bool getChannelDownloadDirectory(const RsGxsGroupId &groupId, std::strin
|
||||
|
||||
/**
|
||||
* Receive results from turtle search @see RsGenExchange @see RsNxsObserver
|
||||
* @see RsGxsNetService::receiveTurtleSearchResults
|
||||
* @see p3turtle::handleSearchResult
|
||||
*/
|
||||
void receiveDistantSearchResults( TurtleRequestId id,
|
||||
const RsGxsGroupId& grpId );
|
||||
const RsGxsGroupId& grpId ) override;
|
||||
|
||||
/* Comment service - Provide RsGxsCommentService - redirect to p3GxsCommentService */
|
||||
virtual bool getCommentData(uint32_t token, std::vector<RsGxsComment> &msgs)
|
||||
|
Loading…
Reference in New Issue
Block a user