Merge pull request #228 from alvaro-salort/wiki-modernization-core

libretroshare: implement RsGxsWikiEvent and clean dummy code
This commit is contained in:
csoler 2026-01-07 23:39:38 +01:00 committed by GitHub
commit bee910a95c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 145 additions and 718 deletions

1
.gitignore vendored
View File

@ -14,3 +14,4 @@ CMakeLists.txt.user
Makefile.libretroshare
*.a
*.o
build/

View File

@ -25,9 +25,12 @@
#include <inttypes.h>
#include <string>
#include <list>
#include <vector>
#include <iostream>
#include "retroshare/rstokenservice.h"
#include "retroshare/rsgxsifacehelper.h"
#include "retroshare/rsevents.h"
/* The Main Interface Class - for information about your Peers */
class RsWiki;
@ -61,40 +64,49 @@ extern RsWiki *rsWiki;
#define FLAG_MSG_TYPE_WIKI_SNAPSHOT 0x0001
#define FLAG_MSG_TYPE_WIKI_COMMENT 0x0002
class CollectionRef
/** Wiki Event Codes */
enum class RsWikiEventCode : uint8_t
{
public:
UPDATED_SNAPSHOT = 0x01,
UPDATED_COLLECTION = 0x02
};
std::string KeyWord;
std::string CollectionId;
/** Specific Wiki Event for UI updates */
struct RsGxsWikiEvent : public RsEvent
{
/* Constructor accepts dynamic event type */
RsGxsWikiEvent(RsEventType type) : RsEvent(type) {}
virtual ~RsGxsWikiEvent() override = default;
RsWikiEventCode mWikiEventCode;
RsGxsGroupId mWikiGroupId;
void serial_process(RsGenericSerializer::SerializeJob j, RsGenericSerializer::SerializeContext& ctx) override
{
RsEvent::serial_process(j, ctx);
RS_SERIAL_PROCESS(mWikiEventCode);
RS_SERIAL_PROCESS(mWikiGroupId);
}
};
struct RsWikiCollection: RsGxsGenericGroupData
{
public:
std::string mDescription;
std::string mCategory;
std::string mHashTags;
// std::map<std::string, CollectionRef> linkReferences;
};
class RsWikiSnapshot
{
public:
public:
RsMsgMetaData mMeta;
std::string mPage; // all the text is stored here.
std::string mPage;
std::string mHashTags;
};
class RsWikiComment
{
public:
public:
RsMsgMetaData mMeta;
std::string mComment;
};
@ -103,32 +115,26 @@ std::ostream &operator<<(std::ostream &out, const RsWikiCollection &group);
std::ostream &operator<<(std::ostream &out, const RsWikiSnapshot &shot);
std::ostream &operator<<(std::ostream &out, const RsWikiComment &comment);
class RsWiki: public RsGxsIfaceHelper
{
public:
RsWiki(RsGxsIface& gxs): RsGxsIfaceHelper(gxs) {}
virtual ~RsWiki() {}
/* Specific Service Data */
virtual bool getCollections(const uint32_t &token, std::vector<RsWikiCollection> &collections) = 0;
virtual bool getSnapshots(const uint32_t &token, std::vector<RsWikiSnapshot> &snapshots) = 0;
virtual bool getComments(const uint32_t &token, std::vector<RsWikiComment> &comments) = 0;
virtual bool getRelatedSnapshots(const uint32_t &token, std::vector<RsWikiSnapshot> &snapshots) = 0;
virtual bool submitCollection(uint32_t &token, RsWikiCollection &collection) = 0;
virtual bool submitSnapshot(uint32_t &token, RsWikiSnapshot &snapshot) = 0;
virtual bool submitComment(uint32_t &token, RsWikiComment &comment) = 0;
virtual bool updateCollection(uint32_t &token, RsWikiCollection &collection) = 0;
// Blocking Interfaces.
virtual bool createCollection(RsWikiCollection &collection) = 0;
virtual bool updateCollection(const RsWikiCollection &collection) = 0;
virtual bool getCollections(const std::list<RsGxsGroupId> groupIds, std::vector<RsWikiCollection> &groups) = 0;
/* GXS Data Access */
virtual bool getCollections(const uint32_t &token, std::vector<RsWikiCollection> &collections) = 0;
virtual bool getSnapshots(const uint32_t &token, std::vector<RsWikiSnapshot> &snapshots) = 0;
virtual bool getComments(const uint32_t &token, std::vector<RsWikiComment> &comments) = 0;
virtual bool getRelatedSnapshots(const uint32_t &token, std::vector<RsWikiSnapshot> &snapshots) = 0;
virtual bool submitCollection(uint32_t &token, RsWikiCollection &collection) = 0;
virtual bool submitSnapshot(uint32_t &token, RsWikiSnapshot &snapshot) = 0;
virtual bool submitComment(uint32_t &token, RsWikiComment &comment) = 0;
virtual bool updateCollection(uint32_t &token, RsWikiCollection &collection) = 0;
/* Blocking Interfaces */
virtual bool createCollection(RsWikiCollection &collection) = 0;
virtual bool updateCollection(const RsWikiCollection &collection) = 0;
virtual bool getCollections(const std::list<RsGxsGroupId> groupIds, std::vector<RsWikiCollection> &groups) = 0;
};
#endif

View File

@ -22,308 +22,186 @@
#include "services/p3wiki.h"
#include "retroshare/rsgxsflags.h"
#include "rsitems/rswikiitems.h"
#include "util/rsrandom.h"
/****
* #define WIKI_DEBUG 1
****/
#include "retroshare/rsevents.h"
RsWiki *rsWiki = NULL;
#define WIKI_EVENT_DUMMYTICK 0x0001
#define WIKI_EVENT_DUMMYSTART 0x0002
#define DUMMYSTART_PERIOD 60 // some time for dummyIds to be generated.
#define DUMMYTICK_PERIOD 3
p3Wiki::p3Wiki(RsGeneralDataService* gds, RsNetworkExchangeService* nes, RsGixs *gixs)
:RsGenExchange(gds, nes, new RsGxsWikiSerialiser(), RS_SERVICE_GXS_TYPE_WIKI, gixs, wikiAuthenPolicy()),
RsWiki(static_cast<RsGxsIface&>(*this))
{
// Setup of dummy Pages.
mAboutActive = false;
mImprovActive = false;
mMarkdownActive = false;
// TestData disabled in Repo.
//RsTickEvent::schedule_in(WIKI_EVENT_DUMMYSTART, DUMMYSTART_PERIOD);
}
const std::string GXS_WIKI_APP_NAME = "gxswiki";
const uint16_t GXS_WIKI_APP_MAJOR_VERSION = 1;
const uint16_t GXS_WIKI_APP_MINOR_VERSION = 0;
const uint16_t GXS_WIKI_MIN_MAJOR_VERSION = 1;
const uint16_t GXS_WIKI_MIN_MINOR_VERSION = 0;
RsServiceInfo p3Wiki::getServiceInfo()
{
return RsServiceInfo(RS_SERVICE_GXS_TYPE_WIKI,
GXS_WIKI_APP_NAME,
GXS_WIKI_APP_MAJOR_VERSION,
GXS_WIKI_APP_MINOR_VERSION,
GXS_WIKI_MIN_MAJOR_VERSION,
GXS_WIKI_MIN_MINOR_VERSION);
return RsServiceInfo(RS_SERVICE_GXS_TYPE_WIKI, "gxswiki", 1, 0, 1, 0);
}
uint32_t p3Wiki::wikiAuthenPolicy()
{
uint32_t policy = 0;
uint8_t flag = 0;
// Edits generally need an authors signature.
flag = GXS_SERV::MSG_AUTHEN_ROOT_PUBLISH_SIGN | GXS_SERV::MSG_AUTHEN_CHILD_AUTHOR_SIGN;
uint8_t flag = GXS_SERV::MSG_AUTHEN_ROOT_PUBLISH_SIGN | GXS_SERV::MSG_AUTHEN_CHILD_AUTHOR_SIGN;
RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::PUBLIC_GRP_BITS);
flag |= GXS_SERV::MSG_AUTHEN_CHILD_PUBLISH_SIGN;
RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::RESTRICTED_GRP_BITS);
RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::PRIVATE_GRP_BITS);
flag = 0;
RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::GRP_OPTION_BITS);
return policy;
}
void p3Wiki::service_tick()
{
RsTickEvent::tick_events();
return;
/* Service tick required by RsGenExchange */
}
void p3Wiki::notifyChanges(std::vector<RsGxsNotify*>& changes)
{
std::cerr << "p3Wiki::notifyChanges() New stuff";
std::cerr << std::endl;
if (rsEvents) {
RsEventType wikiEventType = (RsEventType)rsEvents->getDynamicEventType("GXS_WIKI");
for(auto change : changes) {
std::shared_ptr<RsGxsWikiEvent> event = std::make_shared<RsGxsWikiEvent>(wikiEventType);
event->mWikiGroupId = change->mGroupId;
if (dynamic_cast<RsGxsMsgChange*>(change)) {
event->mWikiEventCode = RsWikiEventCode::UPDATED_SNAPSHOT;
} else {
// This handles new Wikis
event->mWikiEventCode = RsWikiEventCode::UPDATED_COLLECTION;
}
rsEvents->postEvent(event);
delete change;
}
} else {
for(auto change : changes) delete change;
}
changes.clear();
}
/* Specific Service Data */
/* GXS Data Retrieval Methods */
bool p3Wiki::getCollections(const uint32_t &token, std::vector<RsWikiCollection> &collections)
{
std::cerr << "p3Wiki::getCollections()";
std::cerr << std::endl;
std::vector<RsGxsGrpItem*> grpData;
bool ok = RsGenExchange::getGroupData(token, grpData);
if(ok)
{
std::vector<RsGxsGrpItem*>::iterator vit = grpData.begin();
for(; vit != grpData.end(); ++vit)
{
RsGxsWikiCollectionItem* item = dynamic_cast<RsGxsWikiCollectionItem*>(*vit);
if (item)
{
if(ok) {
for(auto it : grpData) {
RsGxsWikiCollectionItem* item = dynamic_cast<RsGxsWikiCollectionItem*>(it);
if (item) {
RsWikiCollection collection = item->collection;
collection.mMeta = item->meta;
delete item;
collections.push_back(collection);
std::cerr << "p3Wiki::getCollections() Adding Collection to Vector: ";
std::cerr << std::endl;
std::cerr << collection;
std::cerr << std::endl;
}
else
{
std::cerr << "Not a WikiCollectionItem, deleting!" << std::endl;
delete *vit;
}
delete it;
}
}
return ok;
}
bool p3Wiki::getSnapshots(const uint32_t &token, std::vector<RsWikiSnapshot> &snapshots)
{
GxsMsgDataMap msgData;
bool ok = RsGenExchange::getMsgData(token, msgData);
if(ok)
{
GxsMsgDataMap::iterator mit = msgData.begin();
for(; mit != msgData.end(); ++mit)
{
RsGxsGroupId grpId = mit->first;
std::vector<RsGxsMsgItem*>& msgItems = mit->second;
std::vector<RsGxsMsgItem*>::iterator vit = msgItems.begin();
for(; vit != msgItems.end(); ++vit)
{
RsGxsWikiSnapshotItem* item = dynamic_cast<RsGxsWikiSnapshotItem*>(*vit);
if(item)
{
if(ok) {
for(auto& mit : msgData) {
for(auto vit : mit.second) {
RsGxsWikiSnapshotItem* item = dynamic_cast<RsGxsWikiSnapshotItem*>(vit);
if(item) {
RsWikiSnapshot snapshot = item->snapshot;
snapshot.mMeta = item->meta;
snapshots.push_back(snapshot);
delete item;
}
else
{
std::cerr << "Not a WikiSnapshot Item, deleting!" << std::endl;
delete *vit;
}
delete vit;
}
}
}
return ok;
}
bool p3Wiki::getRelatedSnapshots(const uint32_t &token, std::vector<RsWikiSnapshot> &snapshots)
{
GxsMsgRelatedDataMap msgData;
GxsMsgRelatedDataMap msgData;
bool ok = RsGenExchange::getMsgRelatedData(token, msgData);
if(ok)
{
GxsMsgRelatedDataMap::iterator mit = msgData.begin();
for(; mit != msgData.end(); ++mit)
{
std::vector<RsGxsMsgItem*>& msgItems = mit->second;
std::vector<RsGxsMsgItem*>::iterator vit = msgItems.begin();
for(; vit != msgItems.end(); ++vit)
{
RsGxsWikiSnapshotItem* item = dynamic_cast<RsGxsWikiSnapshotItem*>(*vit);
if(item)
{
if(ok) {
for(auto& mit : msgData) {
for(auto vit : mit.second) {
RsGxsWikiSnapshotItem* item = dynamic_cast<RsGxsWikiSnapshotItem*>(vit);
if(item) {
RsWikiSnapshot snapshot = item->snapshot;
snapshot.mMeta = item->meta;
snapshots.push_back(snapshot);
delete item;
}
else
{
std::cerr << "Not a WikiSnapshot Item, deleting!" << std::endl;
delete *vit;
}
delete vit;
}
}
}
return ok;
}
bool p3Wiki::getComments(const uint32_t &token, std::vector<RsWikiComment> &comments)
{
GxsMsgDataMap msgData;
bool ok = RsGenExchange::getMsgData(token, msgData);
if(ok)
{
GxsMsgDataMap::iterator mit = msgData.begin();
for(; mit != msgData.end(); ++mit)
{
RsGxsGroupId grpId = mit->first;
std::vector<RsGxsMsgItem*>& msgItems = mit->second;
std::vector<RsGxsMsgItem*>::iterator vit = msgItems.begin();
for(; vit != msgItems.end(); vit++)
{
RsGxsWikiCommentItem* item = dynamic_cast<RsGxsWikiCommentItem*>(*vit);
if(item)
{
if(ok) {
for(auto& mit : msgData) {
for(auto vit : mit.second) {
RsGxsWikiCommentItem* item = dynamic_cast<RsGxsWikiCommentItem*>(vit);
if(item) {
RsWikiComment comment = item->comment;
comment.mMeta = item->meta;
comments.push_back(comment);
delete item;
}
else
{
std::cerr << "Not a WikiComment Item, deleting!" << std::endl;
delete *vit;
}
delete vit;
}
}
}
return ok;
return false;
}
/* Submission Methods */
bool p3Wiki::submitCollection(uint32_t &token, RsWikiCollection &collection)
{
RsGxsWikiCollectionItem* collectionItem = new RsGxsWikiCollectionItem();
collectionItem->collection = collection;
collectionItem->meta = collection.mMeta;
std::cerr << "p3Wiki::submitCollection(): ";
std::cerr << std::endl;
std::cerr << collection;
std::cerr << std::endl;
std::cerr << "p3Wiki::submitCollection() pushing to RsGenExchange";
std::cerr << std::endl;
RsGenExchange::publishGroup(token, collectionItem);
return true;
}
bool p3Wiki::submitSnapshot(uint32_t &token, RsWikiSnapshot &snapshot)
{
std::cerr << "p3Wiki::submitSnapshot(): " << snapshot;
std::cerr << std::endl;
RsGxsWikiSnapshotItem* snapshotItem = new RsGxsWikiSnapshotItem();
snapshotItem->snapshot = snapshot;
snapshotItem->meta = snapshot.mMeta;
snapshotItem->meta.mMsgFlags = FLAG_MSG_TYPE_WIKI_SNAPSHOT;
RsGenExchange::publishMsg(token, snapshotItem);
RsGxsWikiSnapshotItem* snapshotItem = new RsGxsWikiSnapshotItem();
snapshotItem->snapshot = snapshot;
snapshotItem->meta = snapshot.mMeta;
snapshotItem->meta.mMsgFlags = FLAG_MSG_TYPE_WIKI_SNAPSHOT;
RsGenExchange::publishMsg(token, snapshotItem);
return true;
}
bool p3Wiki::submitComment(uint32_t &token, RsWikiComment &comment)
{
std::cerr << "p3Wiki::submitComment(): " << comment;
std::cerr << std::endl;
RsGxsWikiCommentItem* commentItem = new RsGxsWikiCommentItem();
commentItem->comment = comment;
commentItem->meta = comment.mMeta;
commentItem->meta.mMsgFlags = FLAG_MSG_TYPE_WIKI_COMMENT;
RsGenExchange::publishMsg(token, commentItem);
RsGxsWikiCommentItem* commentItem = new RsGxsWikiCommentItem();
commentItem->comment = comment;
commentItem->meta = comment.mMeta;
commentItem->meta.mMsgFlags = FLAG_MSG_TYPE_WIKI_COMMENT;
RsGenExchange::publishMsg(token, commentItem);
return true;
}
bool p3Wiki::updateCollection(uint32_t &token, RsWikiCollection &group)
{
std::cerr << "p3Wiki::updateCollection()" << std::endl;
RsGxsWikiCollectionItem* grpItem = new RsGxsWikiCollectionItem();
grpItem->collection = group;
grpItem->meta = group.mMeta;
RsGenExchange::updateGroup(token, grpItem);
return true;
RsGxsWikiCollectionItem* grpItem = new RsGxsWikiCollectionItem();
grpItem->collection = group;
grpItem->meta = group.mMeta;
RsGenExchange::updateGroup(token, grpItem);
return true;
}
// Blocking Interfaces.
/* Blocking Interfaces */
bool p3Wiki::createCollection(RsWikiCollection &group)
{
uint32_t token;
@ -343,456 +221,30 @@ bool p3Wiki::getCollections(const std::list<RsGxsGroupId> groupIds, std::vector<
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA;
if (groupIds.empty())
{
if (!requestGroupInfo(token, opts) || waitToken(token) != RsTokenService::COMPLETE )
return false;
}
else
{
if (!requestGroupInfo(token, opts, groupIds) || waitToken(token) != RsTokenService::COMPLETE )
return false;
if (groupIds.empty()) {
if (!requestGroupInfo(token, opts) || waitToken(token) != RsTokenService::COMPLETE ) return false;
} else {
if (!requestGroupInfo(token, opts, groupIds) || waitToken(token) != RsTokenService::COMPLETE ) return false;
}
return getCollections(token, groups) && !groups.empty();
}
/* Stream operators for debugging */
std::ostream &operator<<(std::ostream &out, const RsWikiCollection &group)
{
out << "RsWikiCollection [ ";
out << " Name: " << group.mMeta.mGroupName;
out << " Desc: " << group.mDescription;
out << " Category: " << group.mCategory;
out << " ]";
return out;
out << "RsWikiCollection [ Name: " << group.mMeta.mGroupName << " ]";
return out;
}
std::ostream &operator<<(std::ostream &out, const RsWikiSnapshot &shot)
{
out << "RsWikiSnapshot [ ";
out << "Title: " << shot.mMeta.mMsgName;
out << "]";
return out;
out << "RsWikiSnapshot [ Title: " << shot.mMeta.mMsgName << "]";
return out;
}
std::ostream &operator<<(std::ostream &out, const RsWikiComment &comment)
{
out << "RsWikiComment [ ";
out << "Title: " << comment.mMeta.mMsgName;
out << "]";
return out;
}
/***** FOR TESTING *****/
const int about_len = 10;
const std::string about_txt[] =
{ "Welcome to RsWiki, a fully distributed Wiki system that anyone can edit.",
"Please read through these dummy Wiki pages to learn how it should work\n",
"Basic Functionality:",
" - New Group: creates a collection of Wiki Pages, the creator of group",
" and anyone they share the publish keys with) is the moderator\n",
" - New Page: Create a new Wiki Page, only Group Moderators can do this\n",
" - Edit: Anyone Can Edit the Wiki Page, and the changes form a tree under the original\n",
" - RePublish: This is used by the Moderators to accept and reject Edits.",
" the republished page becomes a new version of the Root Page, allowing more edits to be done\n",
"Please read the improvements section to see how we envision the wiki's working",
};
const int improvements_len = 14;
const std::string improvements_txt[] =
{ "As you can see, the current Wiki is a basic framework waiting to be expanded.",
"There are lots of potential improvements... some of my ideas are listed below\n",
"Ideas:",
" - Formatting: No HTML, lets use Markdown or something similar.\n",
" - Diffs, lots of edits will lead to complex merges - a robust merge tool is essential\n",
" - Read Mode... hide all the Edits, and only show the most recently published versions\n",
" - Easy Duplication - to take over an Abandoned or badly moderated Wiki. Copies All base versions to a new group\n",
" - WikiLinks. A generic Wiki Cross Linking system. This should be combined with Easy Duplication option,",
" to allow easy replacement of groups if necessary... A good design here is critical to a successful Wiki ecosystem\n",
" - work out how to include media (photos, audio, video, etc) without embedding in pages",
" this would leverage the turtle transfer system somehow - maybe like channels.\n",
" - Comments, reviews etc can be incorporated - ideas here are welcome.\n",
" - Any other suggestion???",
" - Come on more ideas!"
};
const int markdown_len = 34;
const std::string markdown_txt[] = {
"# An Example of Markdown Editing.",
"",
"Markdown is quite simple to use, and allows simple HTML.",
"",
"## Some Blocks below an H2 heading.",
"",
" * Firstly, we can put a link [in here][]",
" * Secondly, as you can see we're in a list.",
" * Thirdly, I don't know.",
"",
"### A Sub (H3) heading.",
"",
"#### If we want to get into the very small details. (H6).",
"",
" A bit of code.",
" This is a lit",
" foreach(in loop)",
" a++",
" Double quoted stuff.",
"",
"Or it can be indented like this:",
"",
"> A block of indented stuff looks like this",
"> > With double indenting and ",
"> > > triple indenting possible too",
"",
"Images can be embedded, but thats somethinng to work on in the future.",
"",
"Sadly it doesn't support tables or div's or anything that complex.",
"",
"Keep it simple and help write good wiki pages, thx.",
"",
"[in here]: http://example.com/ \"Optional Title Here\"",
""
};
void p3Wiki::generateDummyData()
{
std::cerr << "p3Wiki::generateDummyData()";
std::cerr << std::endl;
#define GEN_COLLECTIONS 0
int i;
for(i = 0; i < GEN_COLLECTIONS; i++)
{
RsWikiCollection wiki;
wiki.mMeta.mGroupId = RsGxsGroupId::random();
wiki.mMeta.mGroupFlags = 0;
wiki.mMeta.mGroupName = RsGxsGroupId::random().toStdString();
uint32_t dummyToken = 0;
submitCollection(dummyToken, wiki);
}
RsWikiCollection wiki;
wiki.mMeta.mGroupFlags = 0;
wiki.mMeta.mGroupName = "About RsWiki";
submitCollection(mAboutToken, wiki);
wiki.mMeta.mGroupFlags = 0;
wiki.mMeta.mGroupName = "RsWiki Improvements";
submitCollection(mImprovToken, wiki);
wiki.mMeta.mGroupFlags = 0;
wiki.mMeta.mGroupName = "RsWiki Markdown";
submitCollection(mMarkdownToken, wiki);
mAboutLines = 0;
mImprovLines = 0;
mMarkdownLines = 0;
mAboutActive = true;
mImprovActive = true;
mMarkdownActive = true;
RsTickEvent::schedule_in(WIKI_EVENT_DUMMYTICK, DUMMYTICK_PERIOD);
}
bool generateNextDummyPage(const RsGxsMessageId &threadId, const int lines, const RsGxsGrpMsgIdPair &parentId,
const std::string *page_lines, const int num_pagelines, RsWikiSnapshot &snapshot)
{
snapshot.mMeta.mGroupId = parentId.first;
// Create an About Page.
#define NUM_SUB_PAGES 3
if ((lines % NUM_SUB_PAGES == 0) || (lines == num_pagelines))
{
/* do a new baseline */
snapshot.mMeta.mOrigMsgId = threadId;
}
else
{
snapshot.mMeta.mParentId = parentId.second;
snapshot.mMeta.mThreadId = threadId;
}
std::string page;
for(int i = 0; (i < lines) && (i < num_pagelines); i++)
{
snapshot.mPage += page_lines[i];
snapshot.mPage += '\n';
}
return (lines <= num_pagelines);
}
#include <retroshare/rsidentity.h>
RsGxsId chooseRandomAuthorId()
{
/* chose a random Id to sign with */
std::list<RsGxsId> ownIds;
std::list<RsGxsId>::iterator it;
rsIdentity->getOwnIds(ownIds);
uint32_t idx = (uint32_t) (RSRandom::random_u32() % (int)ownIds.size()) ;
int i = 0;
for(it = ownIds.begin(); (it != ownIds.end()) && (i < idx); ++it, i++) ;
return *it ;
}
void p3Wiki::dummyTick()
{
if (mAboutActive)
{
std::cerr << "p3Wiki::dummyTick() AboutActive";
std::cerr << std::endl;
uint32_t status = RsGenExchange::getTokenService()->requestStatus(mAboutToken);
if (status == RsTokenService::COMPLETE)
{
std::cerr << "p3Wiki::dummyTick() AboutActive, Lines: " << mAboutLines;
std::cerr << std::endl;
if (mAboutLines == 0)
{
/* get the group Id */
RsGxsGroupId groupId;
if (!acknowledgeTokenGrp(mAboutToken, groupId))
{
std::cerr << " ERROR ";
std::cerr << std::endl;
mAboutActive = false;
}
/* create baseline snapshot */
RsWikiSnapshot page;
page.mMeta.mGroupId = groupId;
page.mPage = "Baseline page... a placeholder for About Wiki";
page.mMeta.mMsgName = "About RsWiki";
page.mMeta.mAuthorId = chooseRandomAuthorId();
submitSnapshot(mAboutToken, page);
mAboutLines++;
}
else
{
/* get the msg Id, and generate next snapshot */
RsGxsGrpMsgIdPair msgId;
if (!acknowledgeTokenMsg(mAboutToken, msgId))
{
std::cerr << " ERROR ";
std::cerr << std::endl;
mAboutActive = false;
}
if (mAboutLines == 1)
{
mAboutThreadId = msgId.second;
}
RsWikiSnapshot page;
page.mMeta.mMsgName = "About RsWiki";
page.mMeta.mAuthorId = chooseRandomAuthorId();
if (!generateNextDummyPage(mAboutThreadId, mAboutLines, msgId, about_txt, about_len, page))
{
std::cerr << "About Pages Done";
std::cerr << std::endl;
mAboutActive = false;
}
else
{
mAboutLines++;
submitSnapshot(mAboutToken, page);
}
}
}
}
if (mImprovActive)
{
std::cerr << "p3Wiki::dummyTick() ImprovActive";
std::cerr << std::endl;
uint32_t status = RsGenExchange::getTokenService()->requestStatus(mImprovToken);
if (status == RsTokenService::COMPLETE)
{
std::cerr << "p3Wiki::dummyTick() ImprovActive, Lines: " << mImprovLines;
std::cerr << std::endl;
if (mImprovLines == 0)
{
/* get the group Id */
RsGxsGroupId groupId;
if (!acknowledgeTokenGrp(mImprovToken, groupId))
{
std::cerr << " ERROR ";
std::cerr << std::endl;
mImprovActive = false;
}
/* create baseline snapshot */
RsWikiSnapshot page;
page.mMeta.mGroupId = groupId;
page.mPage = "Baseline page... a placeholder for Improv Wiki";
page.mMeta.mMsgName = "Improv RsWiki";
page.mMeta.mAuthorId = chooseRandomAuthorId();
submitSnapshot(mImprovToken, page);
mImprovLines++;
}
else
{
/* get the msg Id, and generate next snapshot */
RsGxsGrpMsgIdPair msgId;
if (!acknowledgeTokenMsg(mImprovToken, msgId))
{
std::cerr << " ERROR ";
std::cerr << std::endl;
mImprovActive = false;
}
if (mImprovLines == 1)
{
mImprovThreadId = msgId.second;
}
RsWikiSnapshot page;
page.mMeta.mMsgName = "Improv RsWiki";
page.mMeta.mAuthorId = chooseRandomAuthorId();
if (!generateNextDummyPage(mImprovThreadId, mImprovLines, msgId, improvements_txt, improvements_len, page))
{
std::cerr << "Improv Pages Done";
std::cerr << std::endl;
mImprovActive = false;
}
else
{
mImprovLines++;
submitSnapshot(mImprovToken, page);
}
}
}
}
if (mMarkdownActive)
{
std::cerr << "p3Wiki::dummyTick() MarkdownActive";
std::cerr << std::endl;
uint32_t status = RsGenExchange::getTokenService()->requestStatus(mMarkdownToken);
if (status == RsTokenService::COMPLETE)
{
std::cerr << "p3Wiki::dummyTick() MarkdownActive, Lines: " << mMarkdownLines;
std::cerr << std::endl;
if (mMarkdownLines == 0)
{
/* get the group Id */
RsGxsGroupId groupId;
if (!acknowledgeTokenGrp(mMarkdownToken, groupId))
{
std::cerr << " ERROR ";
std::cerr << std::endl;
mMarkdownActive = false;
}
/* create baseline snapshot */
RsWikiSnapshot page;
page.mMeta.mGroupId = groupId;
page.mPage = "Baseline page... a placeholder for Markdown Wiki";
page.mMeta.mMsgName = "Markdown RsWiki";
page.mMeta.mAuthorId = chooseRandomAuthorId();
submitSnapshot(mMarkdownToken, page);
mMarkdownLines++;
}
else
{
/* get the msg Id, and generate next snapshot */
RsGxsGrpMsgIdPair msgId;
if (!acknowledgeTokenMsg(mMarkdownToken, msgId))
{
std::cerr << " ERROR ";
std::cerr << std::endl;
mMarkdownActive = false;
}
if (mMarkdownLines == 1)
{
mMarkdownThreadId = msgId.second;
}
RsWikiSnapshot page;
page.mMeta.mMsgName = "Markdown RsWiki";
page.mMeta.mAuthorId = chooseRandomAuthorId();
if (!generateNextDummyPage(mMarkdownThreadId, mMarkdownLines, msgId, markdown_txt, markdown_len, page))
{
std::cerr << "Markdown Pages Done";
std::cerr << std::endl;
mMarkdownActive = false;
}
else
{
mMarkdownLines++;
submitSnapshot(mMarkdownToken, page);
}
}
}
}
if ((mAboutActive) || (mImprovActive) || (mMarkdownActive))
{
/* reschedule next one */
RsTickEvent::schedule_in(WIKI_EVENT_DUMMYTICK, DUMMYTICK_PERIOD);
}
}
// Overloaded from RsTickEvent for Event callbacks.
void p3Wiki::handle_event(uint32_t event_type, const std::string &elabel)
{
std::cerr << "p3Wiki::handle_event(" << event_type << ")";
std::cerr << std::endl;
// stuff.
switch(event_type)
{
case WIKI_EVENT_DUMMYSTART:
generateDummyData();
break;
case WIKI_EVENT_DUMMYTICK:
dummyTick();
break;
default:
/* error */
std::cerr << "p3Wiki::handle_event() Unknown Event Type: " << event_type;
std::cerr << std::endl;
break;
}
}
out << "RsWikiComment [ Title: " << comment.mMeta.mMsgName << "]";
return out;
}

View File

@ -36,68 +36,36 @@
*
*/
class p3Wiki: public RsGenExchange, public RsWiki,
public RsTickEvent
class p3Wiki: public RsGenExchange, public RsWiki
{
public:
p3Wiki(RsGeneralDataService* gds, RsNetworkExchangeService* nes, RsGixs *gixs);
virtual RsServiceInfo getServiceInfo();
static uint32_t wikiAuthenPolicy();
p3Wiki(RsGeneralDataService* gds, RsNetworkExchangeService* nes, RsGixs *gixs);
virtual RsServiceInfo getServiceInfo() override;
static uint32_t wikiAuthenPolicy();
/* Required by base class */
virtual void service_tick() override;
protected:
virtual void notifyChanges(std::vector<RsGxsNotify*>& changes) ;
// Overloaded from RsTickEvent.
virtual void handle_event(uint32_t event_type, const std::string &elabel);
/* Triggered on GXS updates */
virtual void notifyChanges(std::vector<RsGxsNotify*>& changes) override;
public:
/* GXS Data Access Methods */
virtual bool getCollections(const uint32_t &token, std::vector<RsWikiCollection> &collections) override;
virtual bool getSnapshots(const uint32_t &token, std::vector<RsWikiSnapshot> &snapshots) override;
virtual bool getComments(const uint32_t &token, std::vector<RsWikiComment> &comments) override;
virtual bool getRelatedSnapshots(const uint32_t &token, std::vector<RsWikiSnapshot> &snapshots) override;
virtual bool submitCollection(uint32_t &token, RsWikiCollection &collection) override;
virtual bool submitSnapshot(uint32_t &token, RsWikiSnapshot &snapshot) override;
virtual bool submitComment(uint32_t &token, RsWikiComment &comment) override;
virtual bool updateCollection(uint32_t &token, RsWikiCollection &collection) override;
virtual void service_tick();
/* Specific Service Data */
virtual bool getCollections(const uint32_t &token, std::vector<RsWikiCollection> &collections) override;
virtual bool getSnapshots(const uint32_t &token, std::vector<RsWikiSnapshot> &snapshots) override;
virtual bool getComments(const uint32_t &token, std::vector<RsWikiComment> &comments) override;
virtual bool getRelatedSnapshots(const uint32_t &token, std::vector<RsWikiSnapshot> &snapshots) override;
virtual bool submitCollection(uint32_t &token, RsWikiCollection &collection) override;
virtual bool submitSnapshot(uint32_t &token, RsWikiSnapshot &snapshot) override;
virtual bool submitComment(uint32_t &token, RsWikiComment &comment) override;
virtual bool updateCollection(uint32_t &token, RsWikiCollection &collection) override;
// Blocking Interfaces.
virtual bool createCollection(RsWikiCollection &collection) override;
virtual bool updateCollection(const RsWikiCollection &collection) override;
virtual bool getCollections(const std::list<RsGxsGroupId> groupIds, std::vector<RsWikiCollection> &groups) override;
private:
std::string genRandomId();
// RsMutex mWikiMtx;
virtual void generateDummyData();
// Dummy Stuff.
void dummyTick();
bool mAboutActive;
uint32_t mAboutToken;
int mAboutLines;
RsGxsMessageId mAboutThreadId;
bool mImprovActive;
uint32_t mImprovToken;
int mImprovLines;
RsGxsMessageId mImprovThreadId;
bool mMarkdownActive;
uint32_t mMarkdownToken;
int mMarkdownLines;
RsGxsMessageId mMarkdownThreadId;
/* Blocking Interfaces */
virtual bool createCollection(RsWikiCollection &collection) override;
virtual bool updateCollection(const RsWikiCollection &collection) override;
virtual bool getCollections(const std::list<RsGxsGroupId> groupIds, std::vector<RsWikiCollection> &groups) override;
};
#endif