mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-02-25 17:21:27 -05:00
Merge pull request #1264 from G10h4ck/channel_json_api_v2
Channel json api v2
This commit is contained in:
commit
9f37b63e4d
@ -240,7 +240,7 @@ public:
|
|||||||
mTransfersHandler(sts, ifaces.mFiles, ifaces.mPeers, *ifaces.mNotify),
|
mTransfersHandler(sts, ifaces.mFiles, ifaces.mPeers, *ifaces.mNotify),
|
||||||
mChatHandler(sts, ifaces.mNotify, ifaces.mMsgs, ifaces.mPeers, ifaces.mIdentity, &mPeersHandler),
|
mChatHandler(sts, ifaces.mNotify, ifaces.mMsgs, ifaces.mPeers, ifaces.mIdentity, &mPeersHandler),
|
||||||
mApiPluginHandler(sts, ifaces),
|
mApiPluginHandler(sts, ifaces),
|
||||||
mChannelsHandler(ifaces.mGxsChannels),
|
mChannelsHandler(*ifaces.mGxsChannels),
|
||||||
mStatsHandler()
|
mStatsHandler()
|
||||||
#ifdef LIBRESAPI_SETTINGS
|
#ifdef LIBRESAPI_SETTINGS
|
||||||
,mSettingsHandler(sts)
|
,mSettingsHandler(sts)
|
||||||
|
@ -1,7 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* RetroShare JSON API
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
#include "ChannelsHandler.h"
|
#include "ChannelsHandler.h"
|
||||||
|
|
||||||
#include <retroshare/rsgxschannels.h>
|
#include <retroshare/rsgxschannels.h>
|
||||||
#include <util/radix64.h>
|
#include <util/radix64.h>
|
||||||
|
#include <util/rstime.h>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include "Operators.h"
|
#include "Operators.h"
|
||||||
|
|
||||||
@ -21,22 +40,347 @@ StreamBase& operator << (StreamBase& left, RsGxsFile& file)
|
|||||||
{
|
{
|
||||||
double size = 0;
|
double size = 0;
|
||||||
left << makeKeyValueReference("size", size);
|
left << makeKeyValueReference("size", size);
|
||||||
file.mSize = size;
|
file.mSize = size;
|
||||||
}
|
}
|
||||||
return left;
|
return left;
|
||||||
}
|
}
|
||||||
|
|
||||||
ChannelsHandler::ChannelsHandler(RsGxsChannels *channels):
|
ChannelsHandler::ChannelsHandler(RsGxsChannels& channels): mChannels(channels)
|
||||||
mChannels(channels)
|
|
||||||
{
|
{
|
||||||
addResourceHandler("create_post", this, &ChannelsHandler::handleCreatePost);
|
addResourceHandler("list_channels", this,
|
||||||
|
&ChannelsHandler::handleListChannels);
|
||||||
|
addResourceHandler("get_channel", this, &ChannelsHandler::handleGetChannel);
|
||||||
|
addResourceHandler("toggle_subscribe", this, &ChannelsHandler::handleToggleSubscription);
|
||||||
|
addResourceHandler("toggle_auto_download", this, &ChannelsHandler::handleToggleAutoDownload);
|
||||||
|
addResourceHandler("toggle_read", this, &ChannelsHandler::handleTogglePostRead);
|
||||||
|
addResourceHandler("create_channel", this, &ChannelsHandler::handleCreateChannel);
|
||||||
|
addResourceHandler("create_post", this, &ChannelsHandler::handleCreatePost);
|
||||||
}
|
}
|
||||||
|
|
||||||
ResponseTask* ChannelsHandler::handleCreatePost(Request &req, Response &resp)
|
void ChannelsHandler::handleListChannels(Request& /*req*/, Response& resp)
|
||||||
|
{
|
||||||
|
RsTokReqOptions opts;
|
||||||
|
opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA;
|
||||||
|
uint32_t token;
|
||||||
|
|
||||||
|
RsTokenService& tChannels = *mChannels.getTokenService();
|
||||||
|
|
||||||
|
tChannels.requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts);
|
||||||
|
|
||||||
|
time_t start = time(NULL);
|
||||||
|
while((tChannels.requestStatus(token) != RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE)
|
||||||
|
&&(tChannels.requestStatus(token) != RsTokenService::GXS_REQUEST_V2_STATUS_FAILED)
|
||||||
|
&&((time(NULL) < (start+10)))) rstime::rs_usleep(500*1000);
|
||||||
|
|
||||||
|
std::vector<RsGxsChannelGroup> grps;
|
||||||
|
if( tChannels.requestStatus(token) == RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE
|
||||||
|
&& mChannels.getGroupData(token, grps) )
|
||||||
|
{
|
||||||
|
for( std::vector<RsGxsChannelGroup>::iterator vit = grps.begin();
|
||||||
|
vit != grps.end(); ++vit )
|
||||||
|
{
|
||||||
|
RsGxsChannelGroup& grp = *vit;
|
||||||
|
KeyValueReference<RsGxsGroupId> id("channel_id", grp.mMeta.mGroupId);
|
||||||
|
KeyValueReference<uint32_t> vis_msg("visible_msg_count", grp.mMeta.mVisibleMsgCount);
|
||||||
|
bool own = (grp.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN);
|
||||||
|
bool subscribed = IS_GROUP_SUBSCRIBED(grp.mMeta.mSubscribeFlags);
|
||||||
|
std::string lastPostTsStr = std::to_string(grp.mMeta.mLastPost);
|
||||||
|
std::string publishTsStr = std::to_string(grp.mMeta.mPublishTs);
|
||||||
|
std::string thumbnail_base64;
|
||||||
|
Radix64::encode(grp.mImage.mData, grp.mImage.mSize, thumbnail_base64);
|
||||||
|
resp.mDataStream.getStreamToMember()
|
||||||
|
<< id
|
||||||
|
<< makeKeyValueReference("name", grp.mMeta.mGroupName)
|
||||||
|
<< makeKeyValueReference("last_post_ts", lastPostTsStr)
|
||||||
|
<< makeKeyValueReference("popularity", grp.mMeta.mPop)
|
||||||
|
<< makeKeyValueReference("publish_ts", publishTsStr)
|
||||||
|
<< vis_msg
|
||||||
|
<< makeKeyValueReference("group_status", grp.mMeta.mGroupStatus)
|
||||||
|
<< makeKeyValueReference("author_id", grp.mMeta.mAuthorId)
|
||||||
|
<< makeKeyValueReference("parent_grp_id", grp.mMeta.mParentGrpId)
|
||||||
|
<< makeKeyValueReference("description", grp.mDescription)
|
||||||
|
<< makeKeyValueReference("own", own)
|
||||||
|
<< makeKeyValueReference("subscribed", subscribed)
|
||||||
|
<< makeKeyValueReference("thumbnail_base64_png", thumbnail_base64)
|
||||||
|
<< makeKeyValueReference("auto_download", grp.mAutoDownload);
|
||||||
|
}
|
||||||
|
|
||||||
|
resp.setOk();
|
||||||
|
}
|
||||||
|
else resp.setFail("Cant get data from GXS!");
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChannelsHandler::handleGetChannel(Request& req, Response& resp)
|
||||||
|
{
|
||||||
|
std::string chanIdStr;
|
||||||
|
req.mStream << makeKeyValueReference("channel_id", chanIdStr);
|
||||||
|
if(chanIdStr.empty())
|
||||||
|
{
|
||||||
|
resp.setFail("channel_id required!");
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
RsGxsGroupId chanId(chanIdStr);
|
||||||
|
if(chanId.isNull())
|
||||||
|
{
|
||||||
|
resp.setFail("Invalid channel_id:" + chanIdStr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::list<RsGxsGroupId> groupIds; groupIds.push_back(chanId);
|
||||||
|
uint32_t token;
|
||||||
|
RsTokReqOptions opts;
|
||||||
|
opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA;
|
||||||
|
|
||||||
|
if(! mChannels.getTokenService()->
|
||||||
|
requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, groupIds) )
|
||||||
|
{
|
||||||
|
resp.setFail("Unknown GXS error!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
time_t start = time(NULL);
|
||||||
|
while((mChannels.getTokenService()->requestStatus(token) != RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE)
|
||||||
|
&&(mChannels.getTokenService()->requestStatus(token) != RsTokenService::GXS_REQUEST_V2_STATUS_FAILED)
|
||||||
|
&&((time(NULL) < (start+10)))) rstime::rs_usleep(500*1000);
|
||||||
|
|
||||||
|
std::vector<RsGxsChannelPost> posts;
|
||||||
|
std::vector<RsGxsComment> comments;
|
||||||
|
if( mChannels.getTokenService()->requestStatus(token) ==
|
||||||
|
RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE &&
|
||||||
|
mChannels.getPostData(token, posts, comments) )
|
||||||
|
{
|
||||||
|
for( std::vector<RsGxsChannelPost>::iterator vit = posts.begin();
|
||||||
|
vit != posts.end(); ++vit )
|
||||||
|
{
|
||||||
|
RsGxsChannelPost& post = *vit;
|
||||||
|
RsMsgMetaData& pMeta = post.mMeta;
|
||||||
|
resp.mDataStream.getStreamToMember()
|
||||||
|
<< makeKeyValueReference("channel_id", pMeta.mGroupId)
|
||||||
|
<< makeKeyValueReference("name", pMeta.mMsgName)
|
||||||
|
<< makeKeyValueReference("post_id", pMeta.mMsgId)
|
||||||
|
<< makeKeyValueReference("parent_id", pMeta.mParentId)
|
||||||
|
<< makeKeyValueReference("author_id", pMeta.mAuthorId)
|
||||||
|
<< makeKeyValueReference("orig_msg_id", pMeta.mOrigMsgId)
|
||||||
|
<< makeKeyValueReference("thread_id", pMeta.mThreadId)
|
||||||
|
<< makeKeyValueReference("message", post.mMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
for( std::vector<RsGxsComment>::iterator vit = comments.begin();
|
||||||
|
vit != comments.end(); ++vit )
|
||||||
|
{
|
||||||
|
RsGxsComment& comment = *vit;
|
||||||
|
RsMsgMetaData& cMeta = comment.mMeta;
|
||||||
|
std::string scoreStr = std::to_string(comment.mScore);
|
||||||
|
resp.mDataStream.getStreamToMember()
|
||||||
|
<< makeKeyValueReference("channel_id", cMeta.mGroupId)
|
||||||
|
<< makeKeyValueReference("name", cMeta.mMsgName)
|
||||||
|
<< makeKeyValueReference("comment_id", cMeta.mMsgId)
|
||||||
|
<< makeKeyValueReference("parent_id", cMeta.mParentId)
|
||||||
|
<< makeKeyValueReference("author_id", cMeta.mAuthorId)
|
||||||
|
<< makeKeyValueReference("orig_msg_id", cMeta.mOrigMsgId)
|
||||||
|
<< makeKeyValueReference("thread_id", cMeta.mThreadId)
|
||||||
|
<< makeKeyValueReference("score", scoreStr)
|
||||||
|
<< makeKeyValueReference("message", comment.mComment);
|
||||||
|
}
|
||||||
|
|
||||||
|
resp.setOk();
|
||||||
|
}
|
||||||
|
else resp.setFail("Cant get data from GXS!");
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChannelsHandler::handleToggleSubscription(Request& req, Response& resp)
|
||||||
|
{
|
||||||
|
std::string chanIdStr;
|
||||||
|
bool subscribe = true;
|
||||||
|
|
||||||
|
req.mStream << makeKeyValueReference("channel_id", chanIdStr)
|
||||||
|
<< makeKeyValueReference("subscribe", subscribe);
|
||||||
|
|
||||||
|
if(chanIdStr.empty())
|
||||||
|
{
|
||||||
|
resp.setFail("channel_id required!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RsGxsGroupId chanId(chanIdStr);
|
||||||
|
if(chanId.isNull())
|
||||||
|
{
|
||||||
|
resp.setFail("Invalid channel_id:" + chanIdStr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t token;
|
||||||
|
if(mChannels.subscribeToGroup(token, chanId, subscribe))
|
||||||
|
{
|
||||||
|
RsTokenService& tChannels = *mChannels.getTokenService();
|
||||||
|
|
||||||
|
time_t start = time(NULL);
|
||||||
|
while((tChannels.requestStatus(token) != RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE)
|
||||||
|
&&(tChannels.requestStatus(token) != RsTokenService::GXS_REQUEST_V2_STATUS_FAILED)
|
||||||
|
&&((time(NULL) < (start+10)))) rstime::rs_usleep(500*1000);
|
||||||
|
|
||||||
|
if(tChannels.requestStatus(token) == RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE)
|
||||||
|
resp.setOk();
|
||||||
|
else resp.setFail("Unknown GXS error!");
|
||||||
|
}
|
||||||
|
else resp.setFail("Unknown GXS error!");
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChannelsHandler::handleCreateChannel(Request& req, Response& resp)
|
||||||
|
{
|
||||||
|
RsGxsChannelGroup chan;
|
||||||
|
RsGroupMetaData& cMeta = chan.mMeta;
|
||||||
|
std::string authorIdStr;
|
||||||
|
std::string thumbnail_base64;
|
||||||
|
|
||||||
|
req.mStream << makeKeyValueReference("author_id", authorIdStr)
|
||||||
|
<< makeKeyValueReference("name", cMeta.mGroupName)
|
||||||
|
<< makeKeyValueReference("description", chan.mDescription)
|
||||||
|
<< makeKeyValueReference("thumbnail_base64_png", thumbnail_base64);
|
||||||
|
|
||||||
|
if(cMeta.mGroupName.empty())
|
||||||
|
{
|
||||||
|
resp.setFail("Channel name required!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(thumbnail_base64.empty()) chan.mImage.clear();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::vector<uint8_t> png_data = Radix64::decode(thumbnail_base64);
|
||||||
|
if(!png_data.empty())
|
||||||
|
{
|
||||||
|
if(png_data.size() < 8)
|
||||||
|
{
|
||||||
|
resp.setFail("Decoded thumbnail_base64_png is smaller than 8 byte. This can't be a valid png file!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uint8_t png_magic_number[] = {0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a};
|
||||||
|
if(!std::equal(&png_magic_number[0],&png_magic_number[8],png_data.begin()))
|
||||||
|
{
|
||||||
|
resp.setFail("Decoded thumbnail_base64_png does not seem to be a png file. (Header is missing magic number)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
chan.mImage.copy(png_data.data(), png_data.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!authorIdStr.empty()) cMeta.mAuthorId = RsGxsId(authorIdStr);
|
||||||
|
|
||||||
|
// ATM supports creating only public channels
|
||||||
|
cMeta.mGroupFlags = GXS_SERV::FLAG_PRIVACY_PUBLIC;
|
||||||
|
|
||||||
|
// I am not sure about those flags I have reversed them with the debugger
|
||||||
|
// that gives 520 as value of this member when a channel with default
|
||||||
|
// options is created from Qt Gui
|
||||||
|
cMeta.mSignFlags = GXS_SERV::MSG_AUTHEN_CHILD_AUTHOR_SIGN |
|
||||||
|
GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_REQUIRED;
|
||||||
|
|
||||||
|
uint32_t token;
|
||||||
|
if(mChannels.createGroup(token, chan))
|
||||||
|
{
|
||||||
|
RsTokenService& tChannels = *mChannels.getTokenService();
|
||||||
|
|
||||||
|
time_t start = time(NULL);
|
||||||
|
while((tChannels.requestStatus(token) != RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE)
|
||||||
|
&&(tChannels.requestStatus(token) != RsTokenService::GXS_REQUEST_V2_STATUS_FAILED)
|
||||||
|
&&((time(NULL) < (start+10)))) rstime::rs_usleep(500*1000);
|
||||||
|
|
||||||
|
if(tChannels.requestStatus(token) == RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE)
|
||||||
|
resp.setOk();
|
||||||
|
else resp.setFail("Unknown GXS error!");
|
||||||
|
}
|
||||||
|
else resp.setFail("Unkown GXS error!");
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChannelsHandler::handleToggleAutoDownload(Request& req, Response& resp)
|
||||||
|
{
|
||||||
|
|
||||||
|
std::string chanIdStr;
|
||||||
|
bool autoDownload = true;
|
||||||
|
|
||||||
|
req.mStream << makeKeyValueReference("channel_id", chanIdStr)
|
||||||
|
<< makeKeyValueReference("auto_download", autoDownload);
|
||||||
|
|
||||||
|
if(chanIdStr.empty())
|
||||||
|
{
|
||||||
|
resp.setFail("channel_id required!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RsGxsGroupId chanId(chanIdStr);
|
||||||
|
if(chanId.isNull())
|
||||||
|
{
|
||||||
|
resp.setFail("Invalid channel_id:" + chanIdStr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(mChannels.setChannelAutoDownload(chanId, autoDownload))
|
||||||
|
resp.setOk();
|
||||||
|
else resp.setFail();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChannelsHandler::handleTogglePostRead(Request& req, Response& resp)
|
||||||
|
{
|
||||||
|
std::string chanIdStr;
|
||||||
|
std::string postIdStr;
|
||||||
|
bool read = true;
|
||||||
|
|
||||||
|
req.mStream << makeKeyValueReference("channel_id", chanIdStr)
|
||||||
|
<< makeKeyValueReference("post_id", postIdStr)
|
||||||
|
<< makeKeyValueReference("read", read);
|
||||||
|
|
||||||
|
if(chanIdStr.empty())
|
||||||
|
{
|
||||||
|
resp.setFail("channel_id required!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RsGxsGroupId chanId(chanIdStr);
|
||||||
|
if(chanId.isNull())
|
||||||
|
{
|
||||||
|
resp.setFail("Invalid channel_id:" + chanIdStr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(postIdStr.empty())
|
||||||
|
{
|
||||||
|
resp.setFail("post_id required!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RsGxsMessageId postId(postIdStr);
|
||||||
|
if(postId.isNull())
|
||||||
|
{
|
||||||
|
resp.setFail("Invalid post_id:" + postIdStr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cerr << __PRETTY_FUNCTION__ << " " << chanIdStr << " " << postIdStr
|
||||||
|
<< " " << read << std::endl;
|
||||||
|
|
||||||
|
uint32_t token;
|
||||||
|
mChannels.setMessageReadStatus(token, std::make_pair(chanId,postId), read);
|
||||||
|
|
||||||
|
RsTokenService& tChannels = *mChannels.getTokenService();
|
||||||
|
|
||||||
|
time_t start = time(NULL);
|
||||||
|
while((tChannels.requestStatus(token) != RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE)
|
||||||
|
&&(tChannels.requestStatus(token) != RsTokenService::GXS_REQUEST_V2_STATUS_FAILED)
|
||||||
|
&&((time(NULL) < (start+10)))) rstime::rs_usleep(500*1000);
|
||||||
|
|
||||||
|
if(tChannels.requestStatus(token) == RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE)
|
||||||
|
resp.setOk();
|
||||||
|
else resp.setFail("Unknown GXS error!");
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChannelsHandler::handleCreatePost(Request &req, Response &resp)
|
||||||
{
|
{
|
||||||
RsGxsChannelPost post;
|
RsGxsChannelPost post;
|
||||||
|
|
||||||
req.mStream << makeKeyValueReference("group_id", post.mMeta.mGroupId);
|
req.mStream << makeKeyValueReference("channel_id", post.mMeta.mGroupId);
|
||||||
req.mStream << makeKeyValueReference("subject", post.mMeta.mMsgName);
|
req.mStream << makeKeyValueReference("subject", post.mMeta.mMsgName);
|
||||||
req.mStream << makeKeyValueReference("message", post.mMsg);
|
req.mStream << makeKeyValueReference("message", post.mMsg);
|
||||||
|
|
||||||
@ -53,36 +397,36 @@ ResponseTask* ChannelsHandler::handleCreatePost(Request &req, Response &resp)
|
|||||||
|
|
||||||
if(post.mMeta.mGroupId.isNull())
|
if(post.mMeta.mGroupId.isNull())
|
||||||
{
|
{
|
||||||
resp.setFail("groupd_id is null");
|
resp.setFail("groupd_id is null");
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
if(post.mMeta.mMsgName.empty())
|
if(post.mMeta.mMsgName.empty())
|
||||||
{
|
{
|
||||||
resp.setFail("subject is empty");
|
resp.setFail("subject is empty");
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
if(post.mMsg.empty())
|
if(post.mMsg.empty())
|
||||||
{
|
{
|
||||||
resp.setFail("msg text is empty");
|
resp.setFail("msg text is empty");
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
// empty file list is ok, but files have to be valid
|
// empty file list is ok, but files have to be valid
|
||||||
for(std::list<RsGxsFile>::iterator lit = post.mFiles.begin(); lit != post.mFiles.end(); ++lit)
|
for(std::list<RsGxsFile>::iterator lit = post.mFiles.begin(); lit != post.mFiles.end(); ++lit)
|
||||||
{
|
{
|
||||||
if(lit->mHash.isNull())
|
if(lit->mHash.isNull())
|
||||||
{
|
{
|
||||||
resp.setFail("at least one file hash is empty");
|
resp.setFail("at least one file hash is empty");
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
if(lit->mName.empty())
|
if(lit->mName.empty())
|
||||||
{
|
{
|
||||||
resp.setFail("at leats one file name is empty");
|
resp.setFail("at leats one file name is empty");
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
if(lit->mSize == 0)
|
if(lit->mSize == 0)
|
||||||
{
|
{
|
||||||
resp.setFail("at least one file size is empty");
|
resp.setFail("at least one file size is empty");
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,22 +435,33 @@ ResponseTask* ChannelsHandler::handleCreatePost(Request &req, Response &resp)
|
|||||||
{
|
{
|
||||||
if(png_data.size() < 8)
|
if(png_data.size() < 8)
|
||||||
{
|
{
|
||||||
resp.setFail("Decoded thumbnail_base64_png is smaller than 8 byte. This can't be a valid png file!");
|
resp.setFail("Decoded thumbnail_base64_png is smaller than 8 byte. This can't be a valid png file!");
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
uint8_t png_magic_number[] = {0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a};
|
uint8_t png_magic_number[] = {0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a};
|
||||||
if(!std::equal(&png_magic_number[0],&png_magic_number[8],png_data.begin()))
|
if(!std::equal(&png_magic_number[0],&png_magic_number[8],png_data.begin()))
|
||||||
{
|
{
|
||||||
resp.setFail("Decoded thumbnail_base64_png does not seem to be a png file. (Header is missing magic number)");
|
resp.setFail("Decoded thumbnail_base64_png does not seem to be a png file. (Header is missing magic number)");
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
post.mThumbnail.copy(png_data.data(), png_data.size());
|
post.mThumbnail.copy(png_data.data(), png_data.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t token;
|
uint32_t token;
|
||||||
mChannels->createPost(token, post);
|
if(mChannels.createPost(token, post))
|
||||||
// TODO: grp creation acknowledge
|
{
|
||||||
return 0;
|
RsTokenService& tChannels = *mChannels.getTokenService();
|
||||||
|
|
||||||
|
time_t start = time(NULL);
|
||||||
|
while((tChannels.requestStatus(token) != RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE)
|
||||||
|
&&(tChannels.requestStatus(token) != RsTokenService::GXS_REQUEST_V2_STATUS_FAILED)
|
||||||
|
&&((time(NULL) < (start+10)))) rstime::rs_usleep(500*1000);
|
||||||
|
|
||||||
|
if(tChannels.requestStatus(token) == RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE)
|
||||||
|
resp.setOk();
|
||||||
|
else resp.setFail("Unknown GXS error!");
|
||||||
|
}
|
||||||
|
else resp.setFail("Unknown GXS error!");
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace resource_api
|
} // namespace resource_api
|
||||||
|
@ -1,4 +1,21 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
/*
|
||||||
|
* RetroShare JSON API
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
#include "ResourceRouter.h"
|
#include "ResourceRouter.h"
|
||||||
|
|
||||||
@ -7,15 +24,20 @@ class RsGxsChannels;
|
|||||||
namespace resource_api
|
namespace resource_api
|
||||||
{
|
{
|
||||||
|
|
||||||
class ChannelsHandler : public ResourceRouter
|
struct ChannelsHandler : ResourceRouter
|
||||||
{
|
{
|
||||||
public:
|
ChannelsHandler(RsGxsChannels& channels);
|
||||||
ChannelsHandler(RsGxsChannels* channels);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ResponseTask* handleCreatePost(Request& req, Response& resp);
|
void handleListChannels(Request& req, Response& resp);
|
||||||
|
void handleGetChannel(Request& req, Response& resp);
|
||||||
|
void handleToggleSubscription(Request& req, Response& resp);
|
||||||
|
void handleCreateChannel(Request& req, Response& resp);
|
||||||
|
void handleToggleAutoDownload(Request& req, Response& resp);
|
||||||
|
void handleTogglePostRead(Request& req, Response& resp);
|
||||||
|
void handleCreatePost(Request& req, Response& resp);
|
||||||
|
|
||||||
RsGxsChannels* mChannels;
|
RsGxsChannels& mChannels;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace resource_api
|
} // namespace resource_api
|
||||||
|
@ -124,24 +124,27 @@ class RsGxsComment
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class RsGxsCommentService
|
struct RsGxsCommentService
|
||||||
{
|
{
|
||||||
public:
|
RsGxsCommentService() {}
|
||||||
|
virtual ~RsGxsCommentService() {}
|
||||||
|
|
||||||
RsGxsCommentService() { return; }
|
/** Get previously requested comment data with token */
|
||||||
virtual ~RsGxsCommentService() { return; }
|
virtual bool getCommentData( uint32_t token,
|
||||||
|
std::vector<RsGxsComment> &comments ) = 0;
|
||||||
|
virtual bool getRelatedComments( uint32_t token,
|
||||||
|
std::vector<RsGxsComment> &comments ) = 0;
|
||||||
|
|
||||||
virtual bool getCommentData(const uint32_t &token, std::vector<RsGxsComment> &comments) = 0;
|
virtual bool createComment(uint32_t &token, RsGxsComment &comment) = 0;
|
||||||
virtual bool getRelatedComments(const uint32_t &token, std::vector<RsGxsComment> &comments) = 0;
|
virtual bool createVote(uint32_t &token, RsGxsVote &vote) = 0;
|
||||||
|
|
||||||
//virtual bool getDetailedCommentData(const uint32_t &token, std::vector<RsGxsComment> &comments);
|
virtual bool acknowledgeComment(
|
||||||
|
uint32_t token,
|
||||||
virtual bool createComment(uint32_t &token, RsGxsComment &comment) = 0;
|
std::pair<RsGxsGroupId, RsGxsMessageId>& msgId ) = 0;
|
||||||
virtual bool createVote(uint32_t &token, RsGxsVote &vote) = 0;
|
|
||||||
|
|
||||||
virtual bool acknowledgeComment(const uint32_t& token, std::pair<RsGxsGroupId, RsGxsMessageId>& msgId) = 0;
|
|
||||||
virtual bool acknowledgeVote(const uint32_t& token, std::pair<RsGxsGroupId, RsGxsMessageId>& msgId) = 0;
|
|
||||||
|
|
||||||
|
virtual bool acknowledgeVote(
|
||||||
|
uint32_t token,
|
||||||
|
std::pair<RsGxsGroupId, RsGxsMessageId>& msgId ) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1179,7 +1179,9 @@ void p3GxsChannels::setMessageProcessedStatus(uint32_t& token, const RsGxsGrpMsg
|
|||||||
setMsgStatusFlags(token, msgId, status, mask);
|
setMsgStatusFlags(token, msgId, status, mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
void p3GxsChannels::setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool read)
|
void p3GxsChannels::setMessageReadStatus( uint32_t& token,
|
||||||
|
const RsGxsGrpMsgIdPair& msgId,
|
||||||
|
bool read )
|
||||||
{
|
{
|
||||||
#ifdef GXSCHANNELS_DEBUG
|
#ifdef GXSCHANNELS_DEBUG
|
||||||
std::cerr << "p3GxsChannels::setMessageReadStatus()";
|
std::cerr << "p3GxsChannels::setMessageReadStatus()";
|
||||||
@ -1189,10 +1191,8 @@ void p3GxsChannels::setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPai
|
|||||||
/* Always remove status unprocessed */
|
/* Always remove status unprocessed */
|
||||||
uint32_t mask = GXS_SERV::GXS_MSG_STATUS_GUI_NEW | GXS_SERV::GXS_MSG_STATUS_GUI_UNREAD;
|
uint32_t mask = GXS_SERV::GXS_MSG_STATUS_GUI_NEW | GXS_SERV::GXS_MSG_STATUS_GUI_UNREAD;
|
||||||
uint32_t status = GXS_SERV::GXS_MSG_STATUS_GUI_UNREAD;
|
uint32_t status = GXS_SERV::GXS_MSG_STATUS_GUI_UNREAD;
|
||||||
if (read)
|
if (read) status = 0;
|
||||||
{
|
|
||||||
status = 0;
|
|
||||||
}
|
|
||||||
setMsgStatusFlags(token, msgId, status, mask);
|
setMsgStatusFlags(token, msgId, status, mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,15 +108,12 @@ virtual bool setChannelDownloadDirectory(const RsGxsGroupId &groupId, const std:
|
|||||||
virtual bool getChannelDownloadDirectory(const RsGxsGroupId &groupId, std::string& directory);
|
virtual bool getChannelDownloadDirectory(const RsGxsGroupId &groupId, std::string& directory);
|
||||||
|
|
||||||
/* Comment service - Provide RsGxsCommentService - redirect to p3GxsCommentService */
|
/* Comment service - Provide RsGxsCommentService - redirect to p3GxsCommentService */
|
||||||
virtual bool getCommentData(const uint32_t &token, std::vector<RsGxsComment> &msgs)
|
virtual bool getCommentData(uint32_t token, std::vector<RsGxsComment> &msgs)
|
||||||
{
|
{ return mCommentService->getGxsCommentData(token, msgs); }
|
||||||
return mCommentService->getGxsCommentData(token, msgs);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool getRelatedComments(const uint32_t &token, std::vector<RsGxsComment> &msgs)
|
virtual bool getRelatedComments( uint32_t token,
|
||||||
{
|
std::vector<RsGxsComment> &msgs )
|
||||||
return mCommentService->getGxsRelatedComments(token, msgs);
|
{ return mCommentService->getGxsRelatedComments(token, msgs); }
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool createComment(uint32_t &token, RsGxsComment &msg)
|
virtual bool createComment(uint32_t &token, RsGxsComment &msg)
|
||||||
{
|
{
|
||||||
@ -128,13 +125,13 @@ virtual bool createVote(uint32_t &token, RsGxsVote &msg)
|
|||||||
return mCommentService->createGxsVote(token, msg);
|
return mCommentService->createGxsVote(token, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool acknowledgeComment(const uint32_t& token, std::pair<RsGxsGroupId, RsGxsMessageId>& msgId)
|
virtual bool acknowledgeComment(uint32_t token, std::pair<RsGxsGroupId, RsGxsMessageId>& msgId)
|
||||||
{
|
{
|
||||||
return acknowledgeMsg(token, msgId);
|
return acknowledgeMsg(token, msgId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
virtual bool acknowledgeVote(const uint32_t& token, std::pair<RsGxsGroupId, RsGxsMessageId>& msgId)
|
virtual bool acknowledgeVote(uint32_t token, std::pair<RsGxsGroupId, RsGxsMessageId>& msgId)
|
||||||
{
|
{
|
||||||
if (mCommentService->acknowledgeVote(token, msgId))
|
if (mCommentService->acknowledgeVote(token, msgId))
|
||||||
{
|
{
|
||||||
|
@ -83,16 +83,14 @@ virtual void setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgI
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Comment service - Provide RsGxsCommentService - redirect to p3GxsCommentService */
|
/** Comment service - Provide RsGxsCommentService -
|
||||||
virtual bool getCommentData(const uint32_t &token, std::vector<RsGxsComment> &msgs)
|
* redirect to p3GxsCommentService */
|
||||||
{
|
virtual bool getCommentData(uint32_t token, std::vector<RsGxsComment> &msgs)
|
||||||
return mCommentService->getGxsCommentData(token, msgs);
|
{ return mCommentService->getGxsCommentData(token, msgs); }
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool getRelatedComments(const uint32_t &token, std::vector<RsGxsComment> &msgs)
|
virtual bool getRelatedComments( uint32_t token,
|
||||||
{
|
std::vector<RsGxsComment> &msgs )
|
||||||
return mCommentService->getGxsRelatedComments(token, msgs);
|
{ return mCommentService->getGxsRelatedComments(token, msgs); }
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool createComment(uint32_t &token, RsGxsComment &msg)
|
virtual bool createComment(uint32_t &token, RsGxsComment &msg)
|
||||||
{
|
{
|
||||||
@ -104,17 +102,14 @@ virtual bool createVote(uint32_t &token, RsGxsVote &msg)
|
|||||||
return mCommentService->createGxsVote(token, msg);
|
return mCommentService->createGxsVote(token, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool acknowledgeComment(const uint32_t& token, std::pair<RsGxsGroupId, RsGxsMessageId>& msgId)
|
virtual bool acknowledgeComment(
|
||||||
{
|
uint32_t token, std::pair<RsGxsGroupId, RsGxsMessageId>& msgId )
|
||||||
return acknowledgeMsg(token, msgId);
|
{ return acknowledgeMsg(token, msgId); }
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool acknowledgeVote(const uint32_t& token, std::pair<RsGxsGroupId, RsGxsMessageId>& msgId)
|
virtual bool acknowledgeVote(
|
||||||
|
uint32_t token, std::pair<RsGxsGroupId, RsGxsMessageId>& msgId )
|
||||||
{
|
{
|
||||||
if (mCommentService->acknowledgeVote(token, msgId))
|
if (mCommentService->acknowledgeVote(token, msgId)) return true;
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return acknowledgeMsg(token, msgId);
|
return acknowledgeMsg(token, msgId);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user