From 8d1f1da242675a03a05ccecfd7ef8596d60e0afe Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Wed, 28 Mar 2018 16:30:35 +0200 Subject: [PATCH 1/2] Extend libresapi with minimal support for channels The code is not elegant as this version of the API will be soon obsolete but it offer a bunch of channels functionalities, comments and votes are not implemented yet /channels/list_channels get all visibile channels /channels/get_channel get content of a subscribed channel /channels/toggle_subscribe subscribe/unsubscribe to a channel /channels/toggle_auto_download set/unset auto-download for files attached to posts in a channel /channels/toggle_read mark a post as read /channels/create_channel create a new channel /channels/create_post create a new post in given channel, group_id paramenter renamed to channel_id for consistence mChannels use reference instead of pointer as it must be valid for the whole lifetime of the object RsGxsCommentService and derivatives use proper types for parameter, avoid reference when unneeded --- libresapi/src/api/ApiServer.cpp | 2 +- libresapi/src/api/ChannelsHandler.cpp | 405 ++++++++++++++++++-- libresapi/src/api/ChannelsHandler.h | 32 +- libretroshare/src/retroshare/rsgxscommon.h | 29 +- libretroshare/src/services/p3gxschannels.cc | 10 +- libretroshare/src/services/p3gxschannels.h | 17 +- libretroshare/src/services/p3posted.h | 31 +- 7 files changed, 449 insertions(+), 77 deletions(-) diff --git a/libresapi/src/api/ApiServer.cpp b/libresapi/src/api/ApiServer.cpp index db8b75d16..b1f6629fd 100644 --- a/libresapi/src/api/ApiServer.cpp +++ b/libresapi/src/api/ApiServer.cpp @@ -240,7 +240,7 @@ public: mTransfersHandler(sts, ifaces.mFiles, ifaces.mPeers, *ifaces.mNotify), mChatHandler(sts, ifaces.mNotify, ifaces.mMsgs, ifaces.mPeers, ifaces.mIdentity, &mPeersHandler), mApiPluginHandler(sts, ifaces), - mChannelsHandler(ifaces.mGxsChannels), + mChannelsHandler(*ifaces.mGxsChannels), mStatsHandler() #ifdef LIBRESAPI_QT ,mSettingsHandler(sts) diff --git a/libresapi/src/api/ChannelsHandler.cpp b/libresapi/src/api/ChannelsHandler.cpp index 27cc02e56..d1812dc3d 100644 --- a/libresapi/src/api/ChannelsHandler.cpp +++ b/libresapi/src/api/ChannelsHandler.cpp @@ -1,7 +1,26 @@ +/* + * RetroShare JSON API + * Copyright (C) 2018 Gioacchino Mazzurco + * + * 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 . + */ + #include "ChannelsHandler.h" #include #include +#include #include #include "Operators.h" @@ -21,22 +40,347 @@ StreamBase& operator << (StreamBase& left, RsGxsFile& file) { double size = 0; left << makeKeyValueReference("size", size); - file.mSize = size; + file.mSize = size; } return left; } -ChannelsHandler::ChannelsHandler(RsGxsChannels *channels): - mChannels(channels) +ChannelsHandler::ChannelsHandler(RsGxsChannels& 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 grps; + if( tChannels.requestStatus(token) == RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE + && mChannels.getGroupData(token, grps) ) + { + for( std::vector::iterator vit = grps.begin(); + vit != grps.end(); ++vit ) + { + RsGxsChannelGroup& grp = *vit; + KeyValueReference id("id", grp.mMeta.mGroupId); + KeyValueReference 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 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 posts; + std::vector comments; + if( mChannels.getTokenService()->requestStatus(token) == + RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE && + mChannels.getPostData(token, posts, comments) ) + { + for( std::vector::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("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::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("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 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; - 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("message", post.mMsg); @@ -53,36 +397,36 @@ ResponseTask* ChannelsHandler::handleCreatePost(Request &req, Response &resp) if(post.mMeta.mGroupId.isNull()) { - resp.setFail("groupd_id is null"); - return 0; + resp.setFail("groupd_id is null"); + return; } if(post.mMeta.mMsgName.empty()) { - resp.setFail("subject is empty"); - return 0; + resp.setFail("subject is empty"); + return; } if(post.mMsg.empty()) { - resp.setFail("msg text is empty"); - return 0; + resp.setFail("msg text is empty"); + return; } // empty file list is ok, but files have to be valid for(std::list::iterator lit = post.mFiles.begin(); lit != post.mFiles.end(); ++lit) { if(lit->mHash.isNull()) { - resp.setFail("at least one file hash is empty"); - return 0; + resp.setFail("at least one file hash is empty"); + return; } if(lit->mName.empty()) { - resp.setFail("at leats one file name is empty"); - return 0; + resp.setFail("at leats one file name is empty"); + return; } if(lit->mSize == 0) { - resp.setFail("at least one file size is empty"); - return 0; + resp.setFail("at least one file size is empty"); + return; } } @@ -91,22 +435,33 @@ ResponseTask* ChannelsHandler::handleCreatePost(Request &req, Response &resp) { 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 0; + 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 0; + resp.setFail("Decoded thumbnail_base64_png does not seem to be a png file. (Header is missing magic number)"); + return; } post.mThumbnail.copy(png_data.data(), png_data.size()); } uint32_t token; - mChannels->createPost(token, post); - // TODO: grp creation acknowledge - return 0; + if(mChannels.createPost(token, post)) + { + 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 diff --git a/libresapi/src/api/ChannelsHandler.h b/libresapi/src/api/ChannelsHandler.h index 1d8559f52..b40f23b73 100644 --- a/libresapi/src/api/ChannelsHandler.h +++ b/libresapi/src/api/ChannelsHandler.h @@ -1,4 +1,21 @@ #pragma once +/* + * RetroShare JSON API + * Copyright (C) 2018 Gioacchino Mazzurco + * + * 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 . + */ #include "ResourceRouter.h" @@ -7,15 +24,20 @@ class RsGxsChannels; namespace resource_api { -class ChannelsHandler : public ResourceRouter +struct ChannelsHandler : ResourceRouter { -public: - ChannelsHandler(RsGxsChannels* channels); + ChannelsHandler(RsGxsChannels& channels); 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 diff --git a/libretroshare/src/retroshare/rsgxscommon.h b/libretroshare/src/retroshare/rsgxscommon.h index 6d4b1655e..b1579e406 100644 --- a/libretroshare/src/retroshare/rsgxscommon.h +++ b/libretroshare/src/retroshare/rsgxscommon.h @@ -124,24 +124,27 @@ class RsGxsComment }; -class RsGxsCommentService +struct RsGxsCommentService { - public: + RsGxsCommentService() {} + virtual ~RsGxsCommentService() {} - RsGxsCommentService() { return; } -virtual ~RsGxsCommentService() { return; } + /** Get previously requested comment data with token */ + virtual bool getCommentData( uint32_t token, + std::vector &comments ) = 0; + virtual bool getRelatedComments( uint32_t token, + std::vector &comments ) = 0; -virtual bool getCommentData(const uint32_t &token, std::vector &comments) = 0; -virtual bool getRelatedComments(const uint32_t &token, std::vector &comments) = 0; + virtual bool createComment(uint32_t &token, RsGxsComment &comment) = 0; + virtual bool createVote(uint32_t &token, RsGxsVote &vote) = 0; -//virtual bool getDetailedCommentData(const uint32_t &token, std::vector &comments); - -virtual bool createComment(uint32_t &token, RsGxsComment &comment) = 0; -virtual bool createVote(uint32_t &token, RsGxsVote &vote) = 0; - -virtual bool acknowledgeComment(const uint32_t& token, std::pair& msgId) = 0; -virtual bool acknowledgeVote(const uint32_t& token, std::pair& msgId) = 0; + virtual bool acknowledgeComment( + uint32_t token, + std::pair& msgId ) = 0; + virtual bool acknowledgeVote( + uint32_t token, + std::pair& msgId ) = 0; }; diff --git a/libretroshare/src/services/p3gxschannels.cc b/libretroshare/src/services/p3gxschannels.cc index d2578d470..2e412034f 100644 --- a/libretroshare/src/services/p3gxschannels.cc +++ b/libretroshare/src/services/p3gxschannels.cc @@ -1179,7 +1179,9 @@ void p3GxsChannels::setMessageProcessedStatus(uint32_t& token, const RsGxsGrpMsg 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 std::cerr << "p3GxsChannels::setMessageReadStatus()"; @@ -1189,10 +1191,8 @@ void p3GxsChannels::setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPai /* Always remove status unprocessed */ 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; - if (read) - { - status = 0; - } + if (read) status = 0; + setMsgStatusFlags(token, msgId, status, mask); } diff --git a/libretroshare/src/services/p3gxschannels.h b/libretroshare/src/services/p3gxschannels.h index 4eb5f5fba..0e6156f48 100644 --- a/libretroshare/src/services/p3gxschannels.h +++ b/libretroshare/src/services/p3gxschannels.h @@ -108,15 +108,12 @@ virtual bool setChannelDownloadDirectory(const RsGxsGroupId &groupId, const std: virtual bool getChannelDownloadDirectory(const RsGxsGroupId &groupId, std::string& directory); /* Comment service - Provide RsGxsCommentService - redirect to p3GxsCommentService */ -virtual bool getCommentData(const uint32_t &token, std::vector &msgs) - { - return mCommentService->getGxsCommentData(token, msgs); - } + virtual bool getCommentData(uint32_t token, std::vector &msgs) + { return mCommentService->getGxsCommentData(token, msgs); } -virtual bool getRelatedComments(const uint32_t &token, std::vector &msgs) - { - return mCommentService->getGxsRelatedComments(token, msgs); - } + virtual bool getRelatedComments( uint32_t token, + std::vector &msgs ) + { return mCommentService->getGxsRelatedComments(token, msgs); } 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); } -virtual bool acknowledgeComment(const uint32_t& token, std::pair& msgId) +virtual bool acknowledgeComment(uint32_t token, std::pair& msgId) { return acknowledgeMsg(token, msgId); } -virtual bool acknowledgeVote(const uint32_t& token, std::pair& msgId) +virtual bool acknowledgeVote(uint32_t token, std::pair& msgId) { if (mCommentService->acknowledgeVote(token, msgId)) { diff --git a/libretroshare/src/services/p3posted.h b/libretroshare/src/services/p3posted.h index 0cb2bcd74..aa4bbc8ee 100644 --- a/libretroshare/src/services/p3posted.h +++ b/libretroshare/src/services/p3posted.h @@ -83,16 +83,14 @@ virtual void setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgI } - /* Comment service - Provide RsGxsCommentService - redirect to p3GxsCommentService */ -virtual bool getCommentData(const uint32_t &token, std::vector &msgs) - { - return mCommentService->getGxsCommentData(token, msgs); - } + /** Comment service - Provide RsGxsCommentService - + * redirect to p3GxsCommentService */ + virtual bool getCommentData(uint32_t token, std::vector &msgs) + { return mCommentService->getGxsCommentData(token, msgs); } -virtual bool getRelatedComments(const uint32_t &token, std::vector &msgs) - { - return mCommentService->getGxsRelatedComments(token, msgs); - } + virtual bool getRelatedComments( uint32_t token, + std::vector &msgs ) + { return mCommentService->getGxsRelatedComments(token, msgs); } 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); } -virtual bool acknowledgeComment(const uint32_t& token, std::pair& msgId) - { - return acknowledgeMsg(token, msgId); - } + virtual bool acknowledgeComment( + uint32_t token, std::pair& msgId ) + { return acknowledgeMsg(token, msgId); } -virtual bool acknowledgeVote(const uint32_t& token, std::pair& msgId) + virtual bool acknowledgeVote( + uint32_t token, std::pair& msgId ) { - if (mCommentService->acknowledgeVote(token, msgId)) - { - return true; - } + if (mCommentService->acknowledgeVote(token, msgId)) return true; return acknowledgeMsg(token, msgId); } }; From 82fa54a735903549b5e961dfee9ff41d0141bfae Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Thu, 29 Mar 2018 11:28:23 +0200 Subject: [PATCH 2/2] Avoid using id as JSON field as it may interfere with QML --- libresapi/src/api/ChannelsHandler.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libresapi/src/api/ChannelsHandler.cpp b/libresapi/src/api/ChannelsHandler.cpp index d1812dc3d..52a3527ac 100644 --- a/libresapi/src/api/ChannelsHandler.cpp +++ b/libresapi/src/api/ChannelsHandler.cpp @@ -80,7 +80,7 @@ void ChannelsHandler::handleListChannels(Request& /*req*/, Response& resp) vit != grps.end(); ++vit ) { RsGxsChannelGroup& grp = *vit; - KeyValueReference id("id", grp.mMeta.mGroupId); + KeyValueReference id("channel_id", grp.mMeta.mGroupId); KeyValueReference 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); @@ -159,7 +159,7 @@ void ChannelsHandler::handleGetChannel(Request& req, Response& resp) resp.mDataStream.getStreamToMember() << makeKeyValueReference("channel_id", pMeta.mGroupId) << makeKeyValueReference("name", pMeta.mMsgName) - << makeKeyValueReference("id", pMeta.mMsgId) + << makeKeyValueReference("post_id", pMeta.mMsgId) << makeKeyValueReference("parent_id", pMeta.mParentId) << makeKeyValueReference("author_id", pMeta.mAuthorId) << makeKeyValueReference("orig_msg_id", pMeta.mOrigMsgId) @@ -176,7 +176,7 @@ void ChannelsHandler::handleGetChannel(Request& req, Response& resp) resp.mDataStream.getStreamToMember() << makeKeyValueReference("channel_id", cMeta.mGroupId) << makeKeyValueReference("name", cMeta.mMsgName) - << makeKeyValueReference("id", cMeta.mMsgId) + << makeKeyValueReference("comment_id", cMeta.mMsgId) << makeKeyValueReference("parent_id", cMeta.mParentId) << makeKeyValueReference("author_id", cMeta.mAuthorId) << makeKeyValueReference("orig_msg_id", cMeta.mOrigMsgId)