From d83e1ea6ec18c19128709f74998dfef56620c489 Mon Sep 17 00:00:00 2001 From: drbob Date: Sun, 1 Jul 2012 23:00:54 +0000 Subject: [PATCH] More improvements to new Cache Services. * Added p3Posted service. This is a *better* Links Cloud, based on the new Cache system. * Fixed p3GxsService retrival of Thread / Children messages. (for Forum support). * Added Dummy Data for testing Forum integration. * switched on both these services in libretroshare git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-new_cache_system@5268 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/libretroshare.pro | 3 + libretroshare/src/retroshare/rsposted.h | 112 ++ libretroshare/src/rsserver/rsinit.cc | 12 +- libretroshare/src/serialiser/rsserviceids.h | 1 + libretroshare/src/services/p3forumsv2.cc | 99 +- libretroshare/src/services/p3forumsv2.h | 1 + libretroshare/src/services/p3gxsservice.cc | 145 ++- libretroshare/src/services/p3posted.cc | 1102 +++++++++++++++++++ libretroshare/src/services/p3posted.h | 138 +++ 9 files changed, 1583 insertions(+), 30 deletions(-) create mode 100644 libretroshare/src/retroshare/rsposted.h create mode 100644 libretroshare/src/services/p3posted.cc create mode 100644 libretroshare/src/services/p3posted.h diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index 5bbc5d387..b214ed1ce 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -692,6 +692,8 @@ HEADERS += services/p3photoservice.h \ services/p3idservice.h \ retroshare/rsforumsv2.h \ services/p3forumsv2.h \ + retroshare/rsposted.h \ + services/p3posted.h \ SOURCES += services/p3photoservice.cc \ serialiser/rsphotoitems.cc \ @@ -700,6 +702,7 @@ SOURCES += services/p3photoservice.cc \ services/p3wire.cc \ services/p3idservice.cc \ services/p3forumsv2.cc \ + services/p3posted.cc \ # Other Old Code. # rsserver/p3photo.cc \ diff --git a/libretroshare/src/retroshare/rsposted.h b/libretroshare/src/retroshare/rsposted.h new file mode 100644 index 000000000..7bbe1fed8 --- /dev/null +++ b/libretroshare/src/retroshare/rsposted.h @@ -0,0 +1,112 @@ +#ifndef RETROSHARE_POSTED_GUI_INTERFACE_H +#define RETROSHARE_POSTED_GUI_INTERFACE_H + +/* + * libretroshare/src/retroshare: rsposted.h + * + * RetroShare C++ Interface. + * + * Copyright 2008-2012 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#include +#include +#include +#include + +/* The Main Interface Class - for information about your Peers */ +class RsPosted; +extern RsPosted *rsPosted; + + +class RsPostedGroup +{ + public: + RsGroupMetaData mMeta; + RsPostedGroup() { return; } +}; + +class RsPostedMsg +{ + public: + RsPostedMsg(uint32_t t) + :postedType(t) { return; } + + RsMsgMetaData mMeta; + uint32_t postedType; +}; + +#define RSPOSTED_MSG_POST 1 +#define RSPOSTED_MSG_VOTE 1 +#define RSPOSTED_MSG_COMMENT 1 + + +class RsPostedPost: public RsPostedMsg +{ + public: + RsPostedPost(): RsPostedMsg(RSPOSTED_MSG_POST) { return; } +}; + + +class RsPostedVote: public RsPostedMsg +{ + public: + RsPostedVote(): RsPostedMsg(RSPOSTED_MSG_VOTE) { return; } +}; + + +class RsPostedComment: public RsPostedMsg +{ + public: + RsPostedComment(): RsPostedMsg(RSPOSTED_MSG_COMMENT) { return; } +}; + + +std::ostream &operator<<(std::ostream &out, const RsPostedGroup &group); +std::ostream &operator<<(std::ostream &out, const RsPostedPost &post); +std::ostream &operator<<(std::ostream &out, const RsPostedVote &vote); +std::ostream &operator<<(std::ostream &out, const RsPostedComment &comment); + + +class RsPosted: public RsTokenService +{ + public: + + RsPosted() { return; } +virtual ~RsPosted() { return; } + + /* changed? */ +virtual bool updated() = 0; + + /* Specific Service Data */ +virtual bool getGroup(const uint32_t &token, RsPostedGroup &group) = 0; +virtual bool getPost(const uint32_t &token, RsPostedPost &post) = 0; +virtual bool getComment(const uint32_t &token, RsPostedComment &comment) = 0; + +/* details are updated in album - to choose Album ID, and storage path */ +virtual bool submitGroup(RsPostedGroup &group, bool isNew) = 0; +virtual bool submitPost(RsPostedPost &post, bool isNew) = 0; +virtual bool submitVote(RsPostedVote &vote, bool isNew) = 0; +virtual bool submitComment(RsPostedComment &comment, bool isNew) = 0; + +}; + + +#endif diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index 9428f2c14..f1ba13b8c 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -1737,6 +1737,7 @@ RsTurtle *rsTurtle = NULL ; #include "services/p3wire.h" #include "services/p3idservice.h" #include "services/p3forumsv2.h" +#include "services/p3posted.h" #ifndef PQI_DISABLE_TUNNEL #include "services/p3tunnel.h" @@ -2152,8 +2153,12 @@ int RsServer::StartupRetroShare() pqih -> addService(mIdentity); // Testing New Cache Services. - //p3ForumsV2 *mForumsV2 = new p3ForumsV2(RS_SERVICE_TYPE_FORUMSV2); - //pqih -> addService(mForumsV2); + p3ForumsV2 *mForumsV2 = new p3ForumsV2(RS_SERVICE_TYPE_FORUMSV2); + pqih -> addService(mForumsV2); + + // Testing New Cache Services. + p3PostedService *mPosted = new p3PostedService(RS_SERVICE_TYPE_POSTED); + pqih -> addService(mPosted); #ifndef RS_RELEASE p3GameLauncher *gameLauncher = new p3GameLauncher(mLinkMgr); @@ -2426,7 +2431,8 @@ int RsServer::StartupRetroShare() rsPhoto = mPhotos; rsWiki = mWikis; rsWire = mWire; - //rsForumsV2 = mForumsV2; + rsForumsV2 = mForumsV2; + rsPosted = mPosted; #ifdef RS_USE_BLOGS rsBlogs = mBlogs; diff --git a/libretroshare/src/serialiser/rsserviceids.h b/libretroshare/src/serialiser/rsserviceids.h index e417e5e8a..3b1eaa92f 100644 --- a/libretroshare/src/serialiser/rsserviceids.h +++ b/libretroshare/src/serialiser/rsserviceids.h @@ -108,6 +108,7 @@ const uint16_t RS_SERVICE_TYPE_PHOTO = 0xf101; const uint16_t RS_SERVICE_TYPE_WIKI = 0xf102; const uint16_t RS_SERVICE_TYPE_WIRE = 0xf103; const uint16_t RS_SERVICE_TYPE_FORUMSV2 = 0xf104; +const uint16_t RS_SERVICE_TYPE_POSTED = 0xf105; //const uint16_t RS_SERVICE_TYPE_DISTRIB = 0xf110; //const uint16_t RS_SERVICE_TYPE_FORUM = 0xf120; diff --git a/libretroshare/src/services/p3forumsv2.cc b/libretroshare/src/services/p3forumsv2.cc index 1f0e6b3b8..16f9f23c3 100644 --- a/libretroshare/src/services/p3forumsv2.cc +++ b/libretroshare/src/services/p3forumsv2.cc @@ -26,6 +26,7 @@ #include "services/p3forumsv2.h" #include "util/rsrandom.h" +#include /**** * #define FORUMV2_DEBUG 1 @@ -42,9 +43,14 @@ RsForumsV2 *rsForumsV2 = NULL; p3ForumsV2::p3ForumsV2(uint16_t type) :p3GxsDataService(type, new ForumDataProxy()), mForumMtx("p3ForumsV2"), mUpdated(true) { - RsStackMutex stack(mForumMtx); /********** STACK LOCKED MTX ******/ + { + RsStackMutex stack(mForumMtx); /********** STACK LOCKED MTX ******/ + + mForumProxy = (ForumDataProxy *) mProxy; + } + + generateDummyData(); - mForumProxy = (ForumDataProxy *) mProxy; return; } @@ -586,14 +592,13 @@ bool ForumDataProxy::convertMsgToMetaData(void *msgData, RsMsgMetaData &meta) /********************************************************************************************/ -#if 0 bool p3ForumsV2::generateDummyData() { /* so we want to generate 100's of forums */ -#define MAX_FORUMS 100 -#define MAX_THREADS 1000 -#define MAX_MSGS 10000 +#define MAX_FORUMS 10 //100 +#define MAX_THREADS 10 //1000 +#define MAX_MSGS 100 //10000 std::list mGroups; std::list::iterator git; @@ -601,11 +606,25 @@ bool p3ForumsV2::generateDummyData() std::list mMsgs; std::list::iterator mit; - for(int i = 0; i < MAX_FORUMS; i++) +#define DUMMY_NAME_MAX_LEN 10000 + char name[DUMMY_NAME_MAX_LEN]; + int i, j; + time_t now = time(NULL); + + for(i = 0; i < MAX_FORUMS; i++) { /* generate a new forum */ RsForumV2Group forum; + /* generate a temp id */ + forum.mMeta.mGroupId = genRandomId(); + + snprintf(name, DUMMY_NAME_MAX_LEN, "TestForum_%d", i+1); + + forum.mMeta.mGroupId = genRandomId(); + forum.mMeta.mGroupName = name; + + forum.mMeta.mPublishTs = now - (RSRandom::random_f32() * 100000); /* key fields to fill in: * GroupId. * Name. @@ -613,11 +632,33 @@ bool p3ForumsV2::generateDummyData() * Pop. */ + + /* use probability to decide which are subscribed / own / popularity. */ + float rnd = RSRandom::random_f32(); + if (rnd < 0.1) + { + forum.mMeta.mSubscribeFlags = RS_DISTRIB_ADMIN; + + } + else if (rnd < 0.3) + { + forum.mMeta.mSubscribeFlags = RS_DISTRIB_SUBSCRIBED; + } + else + { + forum.mMeta.mSubscribeFlags = 0; + } + + forum.mMeta.mPop = (int) (RSRandom::random_f32() * 10.0); mGroups.push_back(forum); + + + //std::cerr << "p3ForumsV2::generateDummyData() Generated Forum: " << forum.mMeta; + //std::cerr << std::endl; } @@ -628,7 +669,7 @@ bool p3ForumsV2::generateDummyData() /* rotate the Forum Groups Around, then pick one. */ - int rnd; + int rnd = (int) (RSRandom::random_f32() * 10.0); for(j = 0; j < rnd; j++) { @@ -653,8 +694,23 @@ bool p3ForumsV2::generateDummyData() * * ChildTS ???? */ + snprintf(name, DUMMY_NAME_MAX_LEN, "%s => ThreadMsg_%d", forum.mMeta.mGroupName.c_str(), i+1); + msg.mMeta.mMsgName = name; + + msg.mMeta.mGroupId = forum.mMeta.mGroupId; + msg.mMeta.mMsgId = genRandomId(); + msg.mMeta.mOrigMsgId = msg.mMeta.mMsgId; + msg.mMeta.mThreadId = msg.mMeta.mMsgId; + msg.mMeta.mParentId = ""; + + msg.mMeta.mPublishTs = forum.mMeta.mPublishTs + (RSRandom::random_f32() * 10000); + if (msg.mMeta.mPublishTs > now) + msg.mMeta.mPublishTs = now - 1; mMsgs.push_back(msg); + + //std::cerr << "p3ForumsV2::generateDummyData() Generated Thread: " << msg.mMeta; + //std::cerr << std::endl; } @@ -665,7 +721,7 @@ bool p3ForumsV2::generateDummyData() /* rotate the Forum Groups Around, then pick one. */ - int rnd; + int rnd = (int) (RSRandom::random_f32() * 10.0); for(j = 0; j < rnd; j++) { @@ -690,25 +746,44 @@ bool p3ForumsV2::generateDummyData() * * ChildTS ???? */ + snprintf(name, DUMMY_NAME_MAX_LEN, "%s => Msg_%d", parent.mMeta.mMsgName.c_str(), i+1); + msg.mMeta.mMsgName = name; + msg.mMsg = name; + msg.mMeta.mGroupId = parent.mMeta.mGroupId; + msg.mMeta.mMsgId = genRandomId(); + msg.mMeta.mOrigMsgId = msg.mMeta.mMsgId; + msg.mMeta.mThreadId = parent.mMeta.mThreadId; + msg.mMeta.mParentId = parent.mMeta.mOrigMsgId; + + msg.mMeta.mPublishTs = parent.mMeta.mPublishTs + (RSRandom::random_f32() * 10000); + if (msg.mMeta.mPublishTs > now) + msg.mMeta.mPublishTs = now - 1; + + mMsgs.push_back(msg); + + //std::cerr << "p3ForumsV2::generateDummyData() Generated Child Msg: " << msg.mMeta; + //std::cerr << std::endl; - } + mUpdated = true; /* Then - at the end, we push them all into the Proxy */ for(git = mGroups.begin(); git != mGroups.end(); git++) { /* pushback */ + mForumProxy->addForumGroup(*git); + } for(mit = mMsgs.begin(); mit != mMsgs.end(); mit++) { /* pushback */ + mForumProxy->addForumMsg(*mit); } + return true; } -#endif - diff --git a/libretroshare/src/services/p3forumsv2.h b/libretroshare/src/services/p3forumsv2.h index bffacbd3d..2aeff0f49 100644 --- a/libretroshare/src/services/p3forumsv2.h +++ b/libretroshare/src/services/p3forumsv2.h @@ -127,6 +127,7 @@ virtual bool createMsg(RsForumV2Msg &msg); private: std::string genRandomId(); +bool generateDummyData(); ForumDataProxy *mForumProxy; diff --git a/libretroshare/src/services/p3gxsservice.cc b/libretroshare/src/services/p3gxsservice.cc index ca741bc8c..bfc116d97 100644 --- a/libretroshare/src/services/p3gxsservice.cc +++ b/libretroshare/src/services/p3gxsservice.cc @@ -385,20 +385,29 @@ bool GxsDataProxy::getMsgList( uint32_t &token, const RsTokReqOptions &opt bool onlyOrigMsgs = false; bool onlyLatestMsgs = false; + bool onlyThreadHeadMsgs = false; // Can only choose one of these two. if (opts.mOptions & RS_TOKREQOPT_MSG_ORIGMSG) { + std::cerr << "GxsDataProxy::getMsgList() MSG_ORIGMSG"; + std::cerr << std::endl; onlyOrigMsgs = true; } else if (opts.mOptions & RS_TOKREQOPT_MSG_LATEST) { - std::cerr << "GxsDataProxy::getMsgList() REQUESTED LATEST!!!"; + std::cerr << "GxsDataProxy::getMsgList() MSG_LATEST"; std::cerr << std::endl; - onlyLatestMsgs = true; } + if (opts.mOptions & RS_TOKREQOPT_MSG_THREAD) + { + std::cerr << "GxsDataProxy::getMsgList() MSG_THREAD"; + std::cerr << std::endl; + onlyThreadHeadMsgs = true; + } + std::list::const_iterator it; std::map::iterator mit; @@ -416,6 +425,16 @@ bool GxsDataProxy::getMsgList( uint32_t &token, const RsTokReqOptions &opt continue; } + /* if we are grabbing thread Head... then parentId == empty. */ + if (onlyThreadHeadMsgs) + { + if (!(mit->second.mParentId.empty())) + { + continue; + } + } + + oit = origMsgTs.find(mit->second.mOrigMsgId); bool addMsg = false; if (oit == origMsgTs.end()) @@ -460,6 +479,16 @@ bool GxsDataProxy::getMsgList( uint32_t &token, const RsTokReqOptions &opt if (mit->second.mGroupId == *it) { bool add = false; + + /* if we are grabbing thread Head... then parentId == empty. */ + if (onlyThreadHeadMsgs) + { + if (!(mit->second.mParentId.empty())) + { + continue; + } + } + if (onlyOrigMsgs) { @@ -498,18 +527,50 @@ bool GxsDataProxy::getMsgRelatedList(uint32_t &token, const RsTokReqOptions &opt bool onlyLatestMsgs = false; bool onlyAllVersions = false; + bool onlyChildMsgs = false; + if (opts.mOptions & RS_TOKREQOPT_MSG_LATEST) { + std::cerr << "GxsDataProxy::getMsgRelatedList() MSG_LATEST"; + std::cerr << std::endl; onlyLatestMsgs = true; } else if (opts.mOptions & RS_TOKREQOPT_MSG_VERSIONS) { + std::cerr << "GxsDataProxy::getMsgRelatedList() MSG_VERSIONS"; + std::cerr << std::endl; onlyAllVersions = true; } - /* FALL BACK OPTION */ - if ((!onlyLatestMsgs) && (!onlyAllVersions)) + if (opts.mOptions & RS_TOKREQOPT_MSG_PARENT) { + std::cerr << "GxsDataProxy::getMsgRelatedList() MSG_PARENTS"; + std::cerr << std::endl; + onlyChildMsgs = true; + } + + if (onlyAllVersions && onlyChildMsgs) + { + std::cerr << "GxsDataProxy::getMsgRelatedList() ERROR Incompatible FLAGS (VERSIONS & PARENT)"; + std::cerr << std::endl; + + return false; + } + + if ((!onlyLatestMsgs) && onlyChildMsgs) + { + std::cerr << "GxsDataProxy::getMsgRelatedList() ERROR Incompatible FLAGS (!LATEST & PARENT)"; + std::cerr << std::endl; + + return false; + } + + + /* FALL BACK OPTION */ + if ((!onlyLatestMsgs) && (!onlyAllVersions) && (!onlyChildMsgs)) + { + std::cerr << "GxsDataProxy::getMsgRelatedList() FALLBACK -> NO FLAGS -> JUST COPY"; + std::cerr << std::endl; /* just copy */ outMsgIds = msgIds; @@ -532,22 +593,75 @@ bool GxsDataProxy::getMsgRelatedList(uint32_t &token, const RsTokReqOptions &opt if (onlyLatestMsgs) { - /* first guess is potentially better than Orig (can't be worse!) */ - time_t latestTs = mit->second.mPublishTs; - std::string latestMsgId = mit->second.mMsgId; - - for(mit = mMsgMetaData.begin(); mit != mMsgMetaData.end(); mit++) + if (onlyChildMsgs) { - if (mit->second.mOrigMsgId == origMsgId) + // RUN THROUGH ALL MSGS... in map origId -> TS. + std::map > origMsgTs; + std::map >::iterator oit; + for(mit = mMsgMetaData.begin(); mit != mMsgMetaData.end(); mit++) { - if (mit->second.mPublishTs > latestTs) + // skip msgs that aren't children. + if (mit->second.mParentId != origMsgId) { - latestTs = mit->second.mPublishTs; - latestMsgId = mit->first; + continue; + } + + oit = origMsgTs.find(mit->second.mOrigMsgId); + bool addMsg = false; + if (oit == origMsgTs.end()) + { + std::cerr << "GxsDataProxy::getMsgList() Found New OrigMsgId: "; + std::cerr << mit->second.mOrigMsgId; + std::cerr << " MsgId: " << mit->second.mMsgId; + std::cerr << " TS: " << mit->second.mPublishTs; + std::cerr << std::endl; + + addMsg = true; + } + // check timestamps. + else if (oit->second.second < mit->second.mPublishTs) + { + std::cerr << "GxsDataProxy::getMsgList() Found Later Msg. OrigMsgId: "; + std::cerr << mit->second.mOrigMsgId; + std::cerr << " MsgId: " << mit->second.mMsgId; + std::cerr << " TS: " << mit->second.mPublishTs; + + addMsg = true; + } + + if (addMsg) + { + // add as latest. (overwriting if necessary) + origMsgTs[mit->second.mOrigMsgId] = std::make_pair(mit->second.mMsgId, mit->second.mPublishTs); } } + + // Add the discovered Latest Msgs. + for(oit = origMsgTs.begin(); oit != origMsgTs.end(); oit++) + { + outMsgIds.push_back(oit->second.first); + } + } + else + { + + /* first guess is potentially better than Orig (can't be worse!) */ + time_t latestTs = mit->second.mPublishTs; + std::string latestMsgId = mit->second.mMsgId; + + for(mit = mMsgMetaData.begin(); mit != mMsgMetaData.end(); mit++) + { + if (mit->second.mOrigMsgId == origMsgId) + { + if (mit->second.mPublishTs > latestTs) + { + latestTs = mit->second.mPublishTs; + latestMsgId = mit->first; + } + } + } + outMsgIds.push_back(latestMsgId); } - outMsgIds.push_back(latestMsgId); } else if (onlyAllVersions) { @@ -934,7 +1048,8 @@ std::ostream &operator<<(std::ostream &out, const RsGroupMetaData &meta) std::ostream &operator<<(std::ostream &out, const RsMsgMetaData &meta) { - out << "[ GroupId: " << meta.mGroupId << " MsgId: " << meta.mMsgId << " Name: " << meta.mMsgName << " ]"; + out << "[ GroupId: " << meta.mGroupId << " MsgId: " << meta.mMsgId; + out << " Name: " << meta.mMsgName; out << " OrigMsgId: " << meta.mOrigMsgId; out << " ThreadId: " << meta.mThreadId; out << " ParentId: " << meta.mParentId; diff --git a/libretroshare/src/services/p3posted.cc b/libretroshare/src/services/p3posted.cc new file mode 100644 index 000000000..0c51e5030 --- /dev/null +++ b/libretroshare/src/services/p3posted.cc @@ -0,0 +1,1102 @@ +/* + * libretroshare/src/services p3photoservice.cc + * + * Photo Service for RetroShare. + * + * Copyright 2012-2012 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2.1 as published by the Free Software Foundation. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#include "services/p3posted.h" +#include "util/rsrandom.h" +#include +#include + +/**** + * #define POSTED_DEBUG 1 + ****/ + +RsPosted *rsPosted = NULL; + + +/********************************************************************************/ +/******************* Startup / Tick ******************************************/ +/********************************************************************************/ + +p3PostedService::p3PostedService(uint16_t type) + :p3GxsDataService(type, new PostedDataProxy()), mPostedMtx("p3PostedService"), mUpdated(true) +{ + { + RsStackMutex stack(mPostedMtx); /********** STACK LOCKED MTX ******/ + + mPostedProxy = (PostedDataProxy *) mProxy; + } + + generateDummyData(); + return; +} + + +int p3PostedService::tick() +{ + //std::cerr << "p3PostedService::tick()"; + //std::cerr << std::endl; + + fakeprocessrequests(); + + return 0; +} + +bool p3PostedService::updated() +{ + RsStackMutex stack(mPostedMtx); /********** STACK LOCKED MTX ******/ + + if (mUpdated) + { + mUpdated = false; + return true; + } + return false; +} + + + + /* Data Requests */ +bool p3PostedService::requestGroupInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &groupIds) +{ + generateToken(token); + std::cerr << "p3PostedService::requestGroupInfo() gets Token: " << token << std::endl; + storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_GROUPS, groupIds); + + return true; +} + +bool p3PostedService::requestMsgInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &groupIds) +{ + generateToken(token); + std::cerr << "p3PostedService::requestMsgInfo() gets Token: " << token << std::endl; + storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_MSGS, groupIds); + + return true; +} + +bool p3PostedService::requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &msgIds) +{ + generateToken(token); + std::cerr << "p3PostedService::requestMsgRelatedInfo() gets Token: " << token << std::endl; + storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_MSGRELATED, msgIds); + + return true; +} + + /* Generic Lists */ +bool p3PostedService::getGroupList( const uint32_t &token, std::list &groupIds) +{ + uint32_t status; + uint32_t reqtype; + uint32_t anstype; + time_t ts; + checkRequestStatus(token, status, reqtype, anstype, ts); + + if (anstype != RS_TOKREQ_ANSTYPE_LIST) + { + std::cerr << "p3PostedService::getGroupList() ERROR AnsType Wrong" << std::endl; + return false; + } + + if (reqtype != GXS_REQUEST_TYPE_GROUPS) + { + std::cerr << "p3PostedService::getGroupList() ERROR ReqType Wrong" << std::endl; + return false; + } + + if (status != GXS_REQUEST_STATUS_COMPLETE) + { + std::cerr << "p3PostedService::getGroupList() ERROR Status Incomplete" << std::endl; + return false; + } + + bool ans = loadRequestOutList(token, groupIds); + updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); + + return ans; +} + + + + +bool p3PostedService::getMsgList( const uint32_t &token, std::list &msgIds) +{ + uint32_t status; + uint32_t reqtype; + uint32_t anstype; + time_t ts; + checkRequestStatus(token, status, reqtype, anstype, ts); + + if (anstype != RS_TOKREQ_ANSTYPE_LIST) + { + std::cerr << "p3PostedService::getMsgList() ERROR AnsType Wrong" << std::endl; + return false; + } + + if ((reqtype != GXS_REQUEST_TYPE_MSGS) && (reqtype != GXS_REQUEST_TYPE_MSGRELATED)) + { + std::cerr << "p3PostedService::getMsgList() ERROR ReqType Wrong" << std::endl; + return false; + } + + if (status != GXS_REQUEST_STATUS_COMPLETE) + { + std::cerr << "p3PostedService::getMsgList() ERROR Status Incomplete" << std::endl; + return false; + } + + bool ans = loadRequestOutList(token, msgIds); + updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); + + return ans; +} + + + /* Generic Summary */ +bool p3PostedService::getGroupSummary( const uint32_t &token, std::list &groupInfo) +{ + uint32_t status; + uint32_t reqtype; + uint32_t anstype; + time_t ts; + checkRequestStatus(token, status, reqtype, anstype, ts); + + if (anstype != RS_TOKREQ_ANSTYPE_SUMMARY) + { + std::cerr << "p3PostedService::getGroupSummary() ERROR AnsType Wrong" << std::endl; + return false; + } + + if (reqtype != GXS_REQUEST_TYPE_GROUPS) + { + std::cerr << "p3PostedService::getGroupSummary() ERROR ReqType Wrong" << std::endl; + return false; + } + + if (status != GXS_REQUEST_STATUS_COMPLETE) + { + std::cerr << "p3PostedService::getGroupSummary() ERROR Status Incomplete" << std::endl; + return false; + } + + std::list groupIds; + bool ans = loadRequestOutList(token, groupIds); + updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); + + /* convert to RsGroupMetaData */ + mProxy->getGroupSummary(groupIds, groupInfo); + + return ans; +} + +bool p3PostedService::getMsgSummary( const uint32_t &token, std::list &msgInfo) +{ + uint32_t status; + uint32_t reqtype; + uint32_t anstype; + time_t ts; + checkRequestStatus(token, status, reqtype, anstype, ts); + + if (anstype != RS_TOKREQ_ANSTYPE_SUMMARY) + { + std::cerr << "p3PostedService::getMsgSummary() ERROR AnsType Wrong" << std::endl; + return false; + } + + if ((reqtype != GXS_REQUEST_TYPE_MSGS) && (reqtype != GXS_REQUEST_TYPE_MSGRELATED)) + { + std::cerr << "p3PostedService::getMsgSummary() ERROR ReqType Wrong" << std::endl; + return false; + } + + if (status != GXS_REQUEST_STATUS_COMPLETE) + { + std::cerr << "p3PostedService::getMsgSummary() ERROR Status Incomplete" << std::endl; + return false; + } + + std::list msgIds; + bool ans = loadRequestOutList(token, msgIds); + updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); + + /* convert to RsMsgMetaData */ + mProxy->getMsgSummary(msgIds, msgInfo); + + return ans; +} + + + /* Specific Service Data */ +bool p3PostedService::getGroup(const uint32_t &token, RsPostedGroup &group) +{ + std::cerr << "p3PostedService::getGroup() Token: " << token; + std::cerr << std::endl; + + uint32_t status; + uint32_t reqtype; + uint32_t anstype; + time_t ts; + checkRequestStatus(token, status, reqtype, anstype, ts); + + + if (anstype != RS_TOKREQ_ANSTYPE_DATA) + { + std::cerr << "p3PostedService::getGroup() ERROR AnsType Wrong" << std::endl; + return false; + } + + if (reqtype != GXS_REQUEST_TYPE_GROUPS) + { + std::cerr << "p3PostedService::getGroup() ERROR ReqType Wrong" << std::endl; + return false; + } + + if (status != GXS_REQUEST_STATUS_COMPLETE) + { + std::cerr << "p3PostedService::getGroup() ERROR Status Incomplete" << std::endl; + return false; + } + + std::string id; + if (!popRequestOutList(token, id)) + { + /* finished */ + updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); + return false; + } + + /* convert to RsPhotoAlbum */ + bool ans = mPostedProxy->getGroup(id, group); + return ans; +} + + +bool p3PostedService::getPost(const uint32_t &token, RsPostedPost &post) +{ + std::cerr << "p3PostedService::getPost() Token: " << token; + std::cerr << std::endl; + + uint32_t status; + uint32_t reqtype; + uint32_t anstype; + time_t ts; + checkRequestStatus(token, status, reqtype, anstype, ts); + + + if (anstype != RS_TOKREQ_ANSTYPE_DATA) + { + std::cerr << "p3PostedService::getPost() ERROR AnsType Wrong" << std::endl; + return false; + } + + if ((reqtype != GXS_REQUEST_TYPE_MSGS) && (reqtype != GXS_REQUEST_TYPE_MSGRELATED)) + { + std::cerr << "p3PostedService::getPost() ERROR ReqType Wrong" << std::endl; + return false; + } + + if (status != GXS_REQUEST_STATUS_COMPLETE) + { + std::cerr << "p3PostedService::getPost() ERROR Status Incomplete" << std::endl; + return false; + } + + std::string id; + if (!popRequestOutList(token, id)) + { + /* finished */ + updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); + return false; + } + + /* convert to RsPhotoAlbum */ + bool ans = mPostedProxy->getPost(id, post); + return ans; +} + + +bool p3PostedService::getComment(const uint32_t &token, RsPostedComment &comment) +{ + std::cerr << "p3PostedService::getComment() Token: " << token; + std::cerr << std::endl; + + uint32_t status; + uint32_t reqtype; + uint32_t anstype; + time_t ts; + checkRequestStatus(token, status, reqtype, anstype, ts); + + + if (anstype != RS_TOKREQ_ANSTYPE_DATA) + { + std::cerr << "p3PostedService::getComment() ERROR AnsType Wrong" << std::endl; + return false; + } + + if ((reqtype != GXS_REQUEST_TYPE_MSGS) && (reqtype != GXS_REQUEST_TYPE_MSGRELATED)) + { + std::cerr << "p3PostedService::getComment() ERROR ReqType Wrong" << std::endl; + return false; + } + + if (status != GXS_REQUEST_STATUS_COMPLETE) + { + std::cerr << "p3PostedService::getComment() ERROR Status Incomplete" << std::endl; + return false; + } + + std::string id; + if (!popRequestOutList(token, id)) + { + /* finished */ + updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); + return false; + } + + /* convert to RsPhotoAlbum */ + bool ans = mPostedProxy->getComment(id, comment); + return ans; +} + + + + + + /* Poll */ +uint32_t p3PostedService::requestStatus(const uint32_t token) +{ + uint32_t status; + uint32_t reqtype; + uint32_t anstype; + time_t ts; + checkRequestStatus(token, status, reqtype, anstype, ts); + + return status; +} + + + /* Cancel Request */ +bool p3PostedService::cancelRequest(const uint32_t &token) +{ + return clearRequest(token); +} + + ////////////////////////////////////////////////////////////////////////////// + /* Functions from Forums -> need to be implemented generically */ +bool p3PostedService::groupsChanged(std::list &groupIds) +{ + return false; +} + + // Get Message Status - is retrived via MessageSummary. +bool p3PostedService::setMessageStatus(const std::string &msgId, const uint32_t status, const uint32_t statusMask) +{ + return false; +} + + + // +bool p3PostedService::groupSubscribe(const std::string &groupId, bool subscribe) +{ + return false; +} + + +bool p3PostedService::groupRestoreKeys(const std::string &groupId) +{ + return false; +} + +bool p3PostedService::groupShareKeys(const std::string &groupId, std::list& peers) +{ + return false; +} + + +bool p3PostedService::submitGroup(RsPostedGroup &group, bool isNew) +{ + /* check if its a modification or a new album */ + + /* add to database */ + + /* check if its a mod or new photo */ + if (group.mMeta.mGroupId.empty()) + { + /* new photo */ + + /* generate a temp id */ + group.mMeta.mGroupId = genRandomId(); + group.mMeta.mPublishTs = time(NULL); + + std::cerr << "p3PostedService::submitGroup() Generated New GroupID: " << group.mMeta.mGroupId; + std::cerr << std::endl; + } + + //group.mModFlags = 0; // These are always cleared. + + RsStackMutex stack(mPostedMtx); /********** STACK LOCKED MTX ******/ + + mUpdated = true; + + /* add / modify */ + mPostedProxy->addGroup(group); + + return true; +} + + +bool p3PostedService::submitPost(RsPostedPost &post, bool isNew) +{ + if (post.mMeta.mGroupId.empty()) + { + /* new photo */ + std::cerr << "p3PostedService::submitPost() Missing GroupID: ERROR"; + std::cerr << std::endl; + return false; + } + + /* generate a new id */ + post.mMeta.mMsgId = genRandomId(); + post.mMeta.mPublishTs = time(NULL); + + if (isNew) + { + /* new (Original Msg) photo */ + post.mMeta.mOrigMsgId = post.mMeta.mMsgId; + std::cerr << "p3PostedService::submitPost() New Msg"; + std::cerr << std::endl; + } + else + { + std::cerr << "p3PostedService::submitPost() Updated Msg"; + std::cerr << std::endl; + } + + //post.mModFlags = 0; // These are always cleared. + + std::cerr << "p3PostedService::submitPost() OrigMsgId: " << post.mMeta.mOrigMsgId; + std::cerr << " MsgId: " << post.mMeta.mMsgId; + std::cerr << std::endl; + + RsStackMutex stack(mPostedMtx); /********** STACK LOCKED MTX ******/ + + mUpdated = true; + + mPostedProxy->addPost(post); + + return true; +} + + + +bool p3PostedService::submitVote(RsPostedVote &vote, bool isNew) +{ + if (vote.mMeta.mGroupId.empty()) + { + /* new photo */ + std::cerr << "p3PostedService::submitVote() Missing GroupID: ERROR"; + std::cerr << std::endl; + return false; + } + + /* generate a new id */ + vote.mMeta.mMsgId = genRandomId(); + vote.mMeta.mPublishTs = time(NULL); + + if (isNew) + { + /* new (Original Msg) photo */ + vote.mMeta.mOrigMsgId = vote.mMeta.mMsgId; + std::cerr << "p3PostedService::submitVote() New Msg"; + std::cerr << std::endl; + } + else + { + std::cerr << "p3PostedService::submitVote() Updated Msg"; + std::cerr << std::endl; + } + + //vote.mModFlags = 0; // These are always cleared. + + std::cerr << "p3PostedService::submitVote() OrigMsgId: " << vote.mMeta.mOrigMsgId; + std::cerr << " MsgId: " << vote.mMeta.mMsgId; + std::cerr << std::endl; + + RsStackMutex stack(mPostedMtx); /********** STACK LOCKED MTX ******/ + + mUpdated = true; + + mPostedProxy->addVote(vote); + + return true; +} + + + +bool p3PostedService::submitComment(RsPostedComment &comment, bool isNew) +{ + if (comment.mMeta.mGroupId.empty()) + { + /* new photo */ + std::cerr << "p3PostedService::submitPost() Missing GroupID: ERROR"; + std::cerr << std::endl; + return false; + } + + /* generate a new id */ + comment.mMeta.mMsgId = genRandomId(); + comment.mMeta.mPublishTs = time(NULL); + + if (isNew) + { + /* new (Original Msg) photo */ + comment.mMeta.mOrigMsgId = comment.mMeta.mMsgId; + std::cerr << "p3PostedService::submitComment() New Msg"; + std::cerr << std::endl; + } + else + { + std::cerr << "p3PostedService::submitComment() Updated Msg"; + std::cerr << std::endl; + } + + //comment.mModFlags = 0; // These are always cleared. + + std::cerr << "p3PostedService::submitComment() OrigMsgId: " << comment.mMeta.mOrigMsgId; + std::cerr << " MsgId: " << comment.mMeta.mMsgId; + std::cerr << std::endl; + + RsStackMutex stack(mPostedMtx); /********** STACK LOCKED MTX ******/ + + mUpdated = true; + + mPostedProxy->addComment(comment); + + return true; +} + + + +/********************************************************************************************/ + +bool PostedDataProxy::getGroup(const std::string &id, RsPostedGroup &group) +{ + void *groupData = NULL; + RsGroupMetaData meta; + if (getGroupData(id, groupData) && getGroupSummary(id, meta)) + { + RsPostedGroup *pG = (RsPostedGroup *) groupData; + group = *pG; + + group.mMeta = meta; + + std::cerr << "PostedDataProxy::getGroup() Id: " << id; + std::cerr << " MetaData: " << meta << " DataPointer: " << groupData; + std::cerr << std::endl; + return true; + } + + std::cerr << "PostedDataProxy::getGroup() FAILED Id: " << id; + std::cerr << std::endl; + + return false; +} + + + +bool PostedDataProxy::getPost(const std::string &id, RsPostedPost &post) +{ + void *msgData = NULL; + RsMsgMetaData meta; + if (getMsgData(id, msgData) && getMsgSummary(id, meta)) + { + RsPostedMsg *pM = (RsPostedMsg *) msgData; + + if (pM->postedType == RSPOSTED_MSG_POST) + { + RsPostedPost *pP = (RsPostedPost *) pM; + post = *pP; + + // update definitive version of the metadata. + post.mMeta = meta; + + std::cerr << "PostedDataProxy::getPost() Id: " << id; + std::cerr << " MetaData: " << meta << " DataPointer: " << msgData; + std::cerr << std::endl; + return true; + } + else + { + std::cerr << "PostedDataProxy::getPost() ERROR NOT POST Id: " << id; + std::cerr << " MetaData: " << meta << " DataPointer: " << msgData; + std::cerr << std::endl; + return false; + } + } + + std::cerr << "PostedDataProxy::getPost() FAILED Id: " << id; + std::cerr << std::endl; + + return false; +} + + + + +bool PostedDataProxy::getVote(const std::string &id, RsPostedVote &vote) +{ + void *msgData = NULL; + RsMsgMetaData meta; + if (getMsgData(id, msgData) && getMsgSummary(id, meta)) + { + RsPostedMsg *pM = (RsPostedMsg *) msgData; + + if (pM->postedType == RSPOSTED_MSG_VOTE) + { + RsPostedVote *pP = (RsPostedVote *) pM; + vote = *pP; + + // update definitive version of the metadata. + vote.mMeta = meta; + + std::cerr << "PostedDataProxy::getVote() Id: " << id; + std::cerr << " MetaData: " << meta << " DataPointer: " << msgData; + std::cerr << std::endl; + return true; + } + else + { + std::cerr << "PostedDataProxy::getVote() ERROR NOT VOTE Id: " << id; + std::cerr << " MetaData: " << meta << " DataPointer: " << msgData; + std::cerr << std::endl; + return false; + } + } + + std::cerr << "PostedDataProxy::getVote() FAILED Id: " << id; + std::cerr << std::endl; + + return false; +} + + + + +bool PostedDataProxy::getComment(const std::string &id, RsPostedComment &comment) +{ + void *msgData = NULL; + RsMsgMetaData meta; + if (getMsgData(id, msgData) && getMsgSummary(id, meta)) + { + RsPostedMsg *pM = (RsPostedMsg *) msgData; + + if (pM->postedType == RSPOSTED_MSG_COMMENT) + { + RsPostedComment *pP = (RsPostedComment *) pM; + comment = *pP; + + // update definitive version of the metadata. + comment.mMeta = meta; + + std::cerr << "PostedDataProxy::getComment() Id: " << id; + std::cerr << " MetaData: " << meta << " DataPointer: " << msgData; + std::cerr << std::endl; + return true; + } + else + { + std::cerr << "PostedDataProxy::getComment() ERROR NOT POST Id: " << id; + std::cerr << " MetaData: " << meta << " DataPointer: " << msgData; + std::cerr << std::endl; + return false; + } + } + + std::cerr << "PostedDataProxy::getComment() FAILED Id: " << id; + std::cerr << std::endl; + + return false; +} + + + + +bool PostedDataProxy::addGroup(const RsPostedGroup &group) +{ + // Make duplicate. + RsPostedGroup *pG = new RsPostedGroup(); + *pG = group; + + std::cerr << "PostedDataProxy::addGroup()"; + std::cerr << " MetaData: " << pG->mMeta << " DataPointer: " << pG; + std::cerr << std::endl; + + return createGroup(pG); +} + + +bool PostedDataProxy::addPost(const RsPostedPost &post) +{ + // Make duplicate. + RsPostedPost *pP = new RsPostedPost(); + *pP = post; + + std::cerr << "PostedDataProxy::addPost()"; + std::cerr << " MetaData: " << pP->mMeta << " DataPointer: " << pP; + std::cerr << std::endl; + + return createMsg(pP); +} + + +bool PostedDataProxy::addVote(const RsPostedVote &vote) +{ + // Make duplicate. + RsPostedVote *pP = new RsPostedVote(); + *pP = vote; + + std::cerr << "PostedDataProxy::addVote()"; + std::cerr << " MetaData: " << pP->mMeta << " DataPointer: " << pP; + std::cerr << std::endl; + + return createMsg(pP); +} + + +bool PostedDataProxy::addComment(const RsPostedComment &comment) +{ + // Make duplicate. + RsPostedComment *pP = new RsPostedComment(); + *pP = comment; + + std::cerr << "PostedDataProxy::addComment()"; + std::cerr << " MetaData: " << pP->mMeta << " DataPointer: " << pP; + std::cerr << std::endl; + + return createMsg(pP); +} + + + /* These Functions must be overloaded to complete the service */ +bool PostedDataProxy::convertGroupToMetaData(void *groupData, RsGroupMetaData &meta) +{ + RsPostedGroup *group = (RsPostedGroup *) groupData; + meta = group->mMeta; + + return true; +} + +bool PostedDataProxy::convertMsgToMetaData(void *msgData, RsMsgMetaData &meta) +{ + RsPostedMsg *msg = (RsPostedMsg *) msgData; + meta = msg->mMeta; + + return true; +} + + +/********************************************************************************************/ + +std::string p3PostedService::genRandomId() +{ + std::string randomId; + for(int i = 0; i < 20; i++) + { + randomId += (char) ('a' + (RSRandom::random_u32() % 26)); + } + + return randomId; +} + + +/********************************************************************************************/ + +std::ostream &operator<<(std::ostream &out, const RsPostedPost &post) +{ + out << "RsPostedPost [ "; + out << "Title: " << post.mMeta.mMsgName; + out << "]"; + return out; +} + +std::ostream &operator<<(std::ostream &out, const RsPostedVote &vote) +{ + out << "RsPostedVote [ "; + out << "Title: " << vote.mMeta.mMsgName; + out << "]"; + return out; +} + +std::ostream &operator<<(std::ostream &out, const RsPostedComment &comment) +{ + out << "RsPostedComment [ "; + out << "Title: " << comment.mMeta.mMsgName; + out << "]"; + return out; +} + +std::ostream &operator<<(std::ostream &out, const RsPostedGroup &group) +{ + out << "RsPostedGroup [ "; + out << "Title: " << group.mMeta.mGroupName; + out << "]"; + return out; +} + + +/********************************************************************************************/ +/********************************************************************************************/ + +bool p3PostedService::generateDummyData() +{ +#define MAX_GROUPS 10 //100 +#define MAX_POSTS 100 //1000 +#define MAX_COMMENTS 100 //10000 +#define MAX_VOTES 100 //10000 + + std::list mGroups; + std::list::iterator git; + + std::list mPosts; + std::list::iterator pit; + + std::list mVotes; + std::list::iterator vit; + + std::list mComments; + std::list::iterator cit; + +#define DUMMY_NAME_MAX_LEN 10000 + char name[DUMMY_NAME_MAX_LEN]; + int i, j; + time_t now = time(NULL); + + for(i = 0; i < MAX_GROUPS; i++) + { + /* generate a new forum */ + RsPostedGroup group; + + snprintf(name, DUMMY_NAME_MAX_LEN, "TestTopic_%d", i+1); + + group.mMeta.mGroupId = genRandomId(); + group.mMeta.mGroupName = name; + + group.mMeta.mPublishTs = now - (RSRandom::random_f32() * 100000); + /* key fields to fill in: + * GroupId. + * Name. + * Flags. + * Pop. + */ + + + + /* use probability to decide which are subscribed / own / popularity. + */ + + float rnd = RSRandom::random_f32(); + if (rnd < 0.1) + { + group.mMeta.mSubscribeFlags = RS_DISTRIB_ADMIN; + + } + else if (rnd < 0.3) + { + group.mMeta.mSubscribeFlags = RS_DISTRIB_SUBSCRIBED; + } + else + { + group.mMeta.mSubscribeFlags = 0; + } + + group.mMeta.mPop = (int) (RSRandom::random_f32() * 10.0); + mGroups.push_back(group); + + } + + for(i = 0; i < MAX_POSTS; i++) + { + /* generate a base thread */ + + /* rotate the Forum Groups Around, then pick one. + */ + + int rnd = (int) (RSRandom::random_f32() * 10.0); + + for(j = 0; j < rnd; j++) + { + RsPostedGroup head = mGroups.front(); + mGroups.pop_front(); + mGroups.push_back(head); + } + + RsPostedGroup group = mGroups.front(); + + /* now create a new thread */ + + RsPostedPost post; + + snprintf(name, DUMMY_NAME_MAX_LEN, "%s => Post_%d", group.mMeta.mGroupName.c_str(), i+1); + post.mMeta.mMsgName = name; + + post.mMeta.mGroupId = group.mMeta.mGroupId; + post.mMeta.mMsgId = genRandomId(); + post.mMeta.mOrigMsgId = post.mMeta.mMsgId; + post.mMeta.mThreadId = post.mMeta.mMsgId; + post.mMeta.mParentId = ""; + + post.mMeta.mPublishTs = group.mMeta.mPublishTs + (RSRandom::random_f32() * 10000); + if (post.mMeta.mPublishTs > now) + post.mMeta.mPublishTs = now - 1; + + mPosts.push_back(post); + + } + + for(i = 0; i < MAX_COMMENTS; i++) + { + /* generate a base thread */ + + /* rotate the Forum Groups Around, then pick one. + */ + + int rnd = (int) (RSRandom::random_f32() * 10.0); + + for(j = 0; j < rnd; j++) + { + RsPostedPost head = mPosts.front(); + mPosts.pop_front(); + mPosts.push_back(head); + } + + RsPostedPost parent = mPosts.front(); + + /* now create a new child msg */ + + RsPostedComment comment; + + /* fill in key data + * GroupId + * MsgId + * OrigMsgId + * ThreadId + * ParentId + * PublishTS (take Forum TS + a bit ). + * + * ChildTS ???? + */ + snprintf(name, DUMMY_NAME_MAX_LEN, "%s => Comment_%d", parent.mMeta.mMsgName.c_str(), i+1); + comment.mMeta.mMsgName = name; + //comment.mMsg = name; + + comment.mMeta.mGroupId = parent.mMeta.mGroupId; + comment.mMeta.mMsgId = genRandomId(); + comment.mMeta.mOrigMsgId = comment.mMeta.mMsgId; + comment.mMeta.mThreadId = parent.mMeta.mThreadId; + comment.mMeta.mParentId = parent.mMeta.mOrigMsgId; + + comment.mMeta.mPublishTs = parent.mMeta.mPublishTs + (RSRandom::random_f32() * 10000); + if (comment.mMeta.mPublishTs > now) + comment.mMeta.mPublishTs = now - 1; + + mComments.push_back(comment); + } + + + for(i = 0; i < MAX_VOTES; i++) + { + /* generate a base thread */ + + /* rotate the Forum Groups Around, then pick one. + */ + + int rnd = (int) (RSRandom::random_f32() * 10.0); + + for(j = 0; j < rnd; j++) + { + RsPostedPost head = mPosts.front(); + mPosts.pop_front(); + mPosts.push_back(head); + } + + RsPostedPost parent = mPosts.front(); + + /* now create a new child msg */ + + RsPostedVote vote; + + snprintf(name, DUMMY_NAME_MAX_LEN, "%s => Vote_%d", parent.mMeta.mMsgName.c_str(), i+1); + vote.mMeta.mMsgName = name; + //vote.mMsg = name; + + vote.mMeta.mGroupId = parent.mMeta.mGroupId; + vote.mMeta.mMsgId = genRandomId(); + vote.mMeta.mOrigMsgId = vote.mMeta.mMsgId; + vote.mMeta.mThreadId = parent.mMeta.mThreadId; + vote.mMeta.mParentId = parent.mMeta.mOrigMsgId; + + vote.mMeta.mPublishTs = parent.mMeta.mPublishTs + (RSRandom::random_f32() * 10000); + if (vote.mMeta.mPublishTs > now) + vote.mMeta.mPublishTs = now - 1; + + mVotes.push_back(vote); + } + + + mUpdated = true; + + /* Then - at the end, we push them all into the Proxy */ + for(git = mGroups.begin(); git != mGroups.end(); git++) + { + /* pushback */ + mPostedProxy->addGroup(*git); + + } + + for(pit = mPosts.begin(); pit != mPosts.end(); pit++) + { + /* pushback */ + mPostedProxy->addPost(*pit); + } + + for(cit = mComments.begin(); cit != mComments.end(); cit++) + { + /* pushback */ + mPostedProxy->addComment(*cit); + } + + + for(vit = mVotes.begin(); vit != mVotes.end(); vit++) + { + /* pushback */ + mPostedProxy->addVote(*vit); + } + + return true; +} + + +/********************************************************************************************/ +/********************************************************************************************/ diff --git a/libretroshare/src/services/p3posted.h b/libretroshare/src/services/p3posted.h new file mode 100644 index 000000000..cd628afe2 --- /dev/null +++ b/libretroshare/src/services/p3posted.h @@ -0,0 +1,138 @@ +/* + * libretroshare/src/services: p3posted.h + * + * 3P/PQI network interface for RetroShare. + * + * Copyright 2012-2012 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#ifndef P3_POSTED_SERVICE_HEADER +#define P3_POSTED_SERVICE_HEADER + +#include "services/p3gxsservice.h" +#include "retroshare/rsposted.h" + +#include +#include + +/* + * Posted Service + * + */ + + +class PostedDataProxy: public GxsDataProxy +{ + public: + + bool addGroup(const RsPostedGroup &group); + bool addPost(const RsPostedPost &post); + bool addVote(const RsPostedVote &vote); + bool addComment(const RsPostedComment &comment); + + bool getGroup(const std::string &id, RsPostedGroup &group); + bool getPost(const std::string &id, RsPostedPost &post); + bool getVote(const std::string &id, RsPostedVote &vote); + bool getComment(const std::string &id, RsPostedComment &comment); + + /* These Functions must be overloaded to complete the service */ +virtual bool convertGroupToMetaData(void *groupData, RsGroupMetaData &meta); +virtual bool convertMsgToMetaData(void *groupData, RsMsgMetaData &meta); + +}; + + + +class p3PostedService: public p3GxsDataService, public RsPosted +{ + public: + + p3PostedService(uint16_t type); + +virtual int tick(); + + public: + +// NEW INTERFACE. +/************* Extern Interface *******/ + +virtual bool updated(); + + /* Data Requests */ +virtual bool requestGroupInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &groupIds); +virtual bool requestMsgInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &groupIds); +virtual bool requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &msgIds); + + /* Generic Lists */ +virtual bool getGroupList( const uint32_t &token, std::list &groupIds); +virtual bool getMsgList( const uint32_t &token, std::list &msgIds); + + /* Generic Summary */ +virtual bool getGroupSummary( const uint32_t &token, std::list &groupInfo); +virtual bool getMsgSummary( const uint32_t &token, std::list &msgInfo); + + /* Actual Data -> specific to Interface */ + /* Specific Service Data */ +virtual bool getGroup(const uint32_t &token, RsPostedGroup &group); +virtual bool getPost(const uint32_t &token, RsPostedPost &post); +virtual bool getComment(const uint32_t &token, RsPostedComment &comment); + + + /* Poll */ +virtual uint32_t requestStatus(const uint32_t token); + + /* Cancel Request */ +virtual bool cancelRequest(const uint32_t &token); + + ////////////////////////////////////////////////////////////////////////////// + /* Functions from Forums -> need to be implemented generically */ +virtual bool groupsChanged(std::list &groupIds); + + // Get Message Status - is retrived via MessageSummary. +virtual bool setMessageStatus(const std::string &msgId, const uint32_t status, const uint32_t statusMask); + + // +virtual bool groupSubscribe(const std::string &groupId, bool subscribe); + +virtual bool groupRestoreKeys(const std::string &groupId); +virtual bool groupShareKeys(const std::string &groupId, std::list& peers); + +/* details are updated in album - to choose Album ID, and storage path */ +virtual bool submitGroup(RsPostedGroup &group, bool isNew); +virtual bool submitPost(RsPostedPost &post, bool isNew); +virtual bool submitVote(RsPostedVote &vote, bool isNew); +virtual bool submitComment(RsPostedComment &comment, bool isNew); + + + + private: + +std::string genRandomId(); +bool generateDummyData(); + + PostedDataProxy *mPostedProxy; + + RsMutex mPostedMtx; + bool mUpdated; + + +}; + +#endif