diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index bc007bde2..54ca3a115 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -201,6 +201,8 @@ void RsGenExchange::generateGroupKeys(RsTlvSecurityKeySet& keySet) bool RsGenExchange::createGroup(RsNxsGrp *grp, RsTlvSecurityKeySet& keySet) { + std::cerr << "RsGenExchange::createGroup()"; + std::cerr << std::endl; RsGxsGrpMetaData* meta = grp->metaData; @@ -224,7 +226,12 @@ bool RsGenExchange::createGroup(RsNxsGrp *grp, RsTlvSecurityKeySet& keySet) } if(mit == keySet.keys.end()) + { + std::cerr << "RsGenExchange::createGroup() Missing ADMIN Key"; + std::cerr << std::endl; + return false; + } // group is self signing // for the creation of group signature @@ -253,6 +260,12 @@ bool RsGenExchange::createGroup(RsNxsGrp *grp, RsTlvSecurityKeySet& keySet) delete[] allGrpData; delete[] metaData; + if (!ok) + { + std::cerr << "RsGenExchange::createGroup() ERROR !okay (getSignature error)"; + std::cerr << std::endl; + } + return ok; } @@ -412,6 +425,9 @@ bool RsGenExchange::getGroupData(const uint32_t &token, std::vector::iterator lit = nxsGrps.begin(); + std::cerr << "RsGenExchange::getGroupData() RsNxsGrp::len: " << nxsGrps.size(); + std::cerr << std::endl; + if(ok) { for(; lit != nxsGrps.end(); lit++) @@ -426,6 +442,11 @@ bool RsGenExchange::getGroupData(const uint32_t &token, std::vectorsecond; - uint32_t size = mSerialiser->size(grpItem); RsTlvSecurityKeySet keySet; generateGroupKeys(keySet); service_CreateGroup(grpItem, keySet); + uint32_t size = mSerialiser->size(grpItem); char gData[size]; bool ok = mSerialiser->serialise(grpItem, gData, &size); + if (!ok) + { + std::cerr << "RsGenExchange::publishGrps() !ok ERROR After First Serialise" << std::endl; + } + grp->grp.setBinData(gData, size); if(ok) @@ -769,14 +795,26 @@ void RsGenExchange::publishGrps() *(grp->metaData) = grpItem->meta; grp->metaData->mSubscribeFlags = GXS_SERV::GROUP_SUBSCRIBE_ADMIN; ok &= createGroup(grp, keySet); + if (!ok) + { + std::cerr << "RsGenExchange::publishGrps() !ok ERROR After createGroup" << std::endl; + } + size = grp->metaData->serial_size(); char mData[size]; grp->metaData->mGroupId = grp->grpId; ok &= grp->metaData->serialise(mData, size); + if (!ok) + { + std::cerr << "RsGenExchange::publishGrps() !ok ERROR After Meta Serialise" << std::endl; + } + grp->meta.setBinData(mData, size); RsGxsGroupId grpId = grp->grpId; mDataAccess->addGroupData(grp); + std::cerr << "RsGenExchange::publishGrps() ok -> pushing to notifies" << std::endl; + // add to published to allow acknowledgement mGrpNotify.insert(std::make_pair(mit->first, grpId)); mDataAccess->updatePublicRequestStatus(mit->first, RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE); @@ -786,8 +824,8 @@ void RsGenExchange::publishGrps() { #ifdef GEN_EXCH_DEBUG - std::cerr << "RsGenExchange::publishGrps() failed to publish grp " << std::endl; #endif + std::cerr << "RsGenExchange::publishGrps() failed to publish grp " << std::endl; delete grp; // add to published to allow acknowledgement, grpid is empty as grp creation failed @@ -890,8 +928,8 @@ void RsGenExchange::createDummyGroup(RsGxsGrpItem *grpItem) { #ifdef GEN_EXCH_DEBUG - std::cerr << "RsGenExchange::createDummyGroup(); failed to publish grp " << std::endl; #endif + std::cerr << "RsGenExchange::createDummyGroup(); failed to publish grp " << std::endl; delete grp; } diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index 0e259ca4c..6b3331d93 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -642,6 +642,14 @@ HEADERS += retroshare/rsgame.h \ SOURCES += services/p3idservice.cc \ serialiser/rsgxsiditems.cc \ + # GxsForums Service + HEADERS += retroshare/rsgxsforums.h \ + services/p3gxsforums.h \ + serialiser/rsgxsforumitems.h + + SOURCES += services/p3gxsforums.cc \ + serialiser/rsgxsforumitems.cc \ + # Wiki Service HEADERS += retroshare/rswiki.h \ services/p3wiki.h \ diff --git a/libretroshare/src/retroshare/rsgxsforums.h b/libretroshare/src/retroshare/rsgxsforums.h new file mode 100644 index 000000000..7fb0da1af --- /dev/null +++ b/libretroshare/src/retroshare/rsgxsforums.h @@ -0,0 +1,87 @@ +#ifndef RETROSHARE_GXS_FORUM_GUI_INTERFACE_H +#define RETROSHARE_GXS_FORUM_GUI_INTERFACE_H + +/* + * libretroshare/src/retroshare: rsgxsforum.h + * + * RetroShare C++ Interface. + * + * 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 +#include +#include + +#include "gxs/rstokenservice.h" +#include "gxs/rsgxsifaceimpl.h" + +/* The Main Interface Class - for information about your Peers */ +class RsGxsForums; +extern RsGxsForums *rsGxsForums; + +class RsGxsForumGroup +{ + public: + RsGroupMetaData mMeta; + std::string mDescription; +}; + +class RsGxsForumMsg +{ + public: + RsMsgMetaData mMeta; + std::string mMsg; +}; + + +//typedef std::map > GxsForumMsgResult; + +std::ostream &operator<<(std::ostream &out, const RsGxsForumGroup &group); +std::ostream &operator<<(std::ostream &out, const RsGxsForumMsg &msg); + +class RsGxsForums: public RsGxsIfaceImpl +{ + public: + + RsGxsForums(RsGenExchange *gxs) + :RsGxsIfaceImpl(gxs) { return; } +virtual ~RsGxsForums() { return; } + + /* Specific Service Data */ +virtual bool getGroupData(const uint32_t &token, std::vector &groups) = 0; +virtual bool getMsgData(const uint32_t &token, std::vector &msgs) = 0; + + ////////////////////////////////////////////////////////////////////////////// +//virtual bool setMessageStatus(const std::string &msgId, const uint32_t status, const uint32_t statusMask); +//virtual bool setGroupSubscribeFlags(const std::string &groupId, uint32_t subscribeFlags, uint32_t subscribeMask); + +//virtual bool groupRestoreKeys(const std::string &groupId); +//virtual bool groupShareKeys(const std::string &groupId, std::list& peers); + +virtual bool createGroup(uint32_t &token, RsGxsForumGroup &group) = 0; +virtual bool createMsg(uint32_t &token, RsGxsForumMsg &msg) = 0; + + +}; + + + +#endif diff --git a/libretroshare/src/retroshare/rswiki.h b/libretroshare/src/retroshare/rswiki.h index 07e527791..3a4648e2b 100644 --- a/libretroshare/src/retroshare/rswiki.h +++ b/libretroshare/src/retroshare/rswiki.h @@ -108,6 +108,10 @@ class RsWikiComment std::string mComment; }; +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 RsGxsIfaceImpl { @@ -125,6 +129,8 @@ 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; + // for testing only. +virtual void generateDummyData() = 0; }; diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index 4d85f3d19..925c303cc 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -1828,12 +1828,13 @@ RsTurtle *rsTurtle = NULL ; #include "services/p3wiki.h" #include "services/p3posted.h" #include "services/p3photoserviceV2.h" +#include "services/p3gxsforums.h" // Not too many to convert now! #include "services/p3wikiserviceVEG.h" #include "services/p3wireVEG.h" //#include "services/p3idserviceVEG.h" -#include "services/p3forumsVEG.h" +//#include "services/p3forumsVEG.h" #endif #ifndef PQI_DISABLE_TUNNEL @@ -2281,16 +2282,16 @@ int RsServer::StartupRetroShare() #ifdef ENABLE_GXS_SERVICES // Testing New Cache Services. - p3WikiServiceVEG *mWikis = new p3WikiServiceVEG(RS_SERVICE_GXSV1_TYPE_WIKI); - pqih -> addService(mWikis); + //p3WikiServiceVEG *mWikis = new p3WikiServiceVEG(RS_SERVICE_GXSV1_TYPE_WIKI); + //pqih -> addService(mWikis); // Testing New Cache Services. p3WireVEG *mWire = new p3WireVEG(RS_SERVICE_GXSV1_TYPE_WIRE); pqih -> addService(mWire); // Testing New Cache Services. - p3ForumsVEG *mForumsV2 = new p3ForumsVEG(RS_SERVICE_GXSV1_TYPE_FORUMS); - pqih -> addService(mForumsV2); + //p3ForumsVEG *mForumsV2 = new p3ForumsVEG(RS_SERVICE_GXSV1_TYPE_FORUMS); + //pqih -> addService(mForumsV2); // TODO: temporary to store GXS service data, remove @@ -2358,11 +2359,26 @@ int RsServer::StartupRetroShare() wiki_ds->resetDataStore(); //TODO: remove, new service data per RS session, for testing - mWiki = new p3Wiki(posted_ds, NULL); + mWiki = new p3Wiki(wiki_ds, NULL); // create GXS photo service RsGxsNetService* wiki_ns = new RsGxsNetService( RS_SERVICE_GXSV1_TYPE_WIKI, wiki_ds, nxsMgr, mWiki); + + /**** Forum GXS service ****/ + + p3GxsForums *mGxsForums = NULL; + + RsGeneralDataService* gxsforums_ds = new RsDataService("./" + mLinkMgr->getOwnId()+ "/", "gxsforums_db", + RS_SERVICE_GXSV1_TYPE_FORUMS); + + gxsforums_ds->resetDataStore(); //TODO: remove, new service data per RS session, for testing + + mGxsForums = new p3GxsForums(gxsforums_ds, NULL); + + // create GXS photo service + RsGxsNetService* gxsforums_ns = new RsGxsNetService( + RS_SERVICE_GXSV1_TYPE_FORUMS, gxsforums_ds, nxsMgr, mGxsForums); #endif #endif // ENABLE_GXS_SERVICES @@ -2378,6 +2394,7 @@ int RsServer::StartupRetroShare() createThread(*mPhotoV2); createThread(*mPosted); createThread(*mWiki); + createThread(*mGxsForums); // // mGxsCore->addService(mPhotoV2); // mGxsCore->addService(mPosted); @@ -2390,6 +2407,7 @@ int RsServer::StartupRetroShare() createThread(*photo_ns); createThread(*posted_ns); createThread(*wiki_ns); + createThread(*gxsforums_ns); #endif // now add to p3service @@ -2398,6 +2416,7 @@ int RsServer::StartupRetroShare() pqih->addService(photo_ns); pqih->addService(posted_ns); pqih->addService(wiki_ns); + pqih->addService(gxsforums_ns); #endif // start up gxs core server @@ -2669,10 +2688,11 @@ int RsServer::StartupRetroShare() rsWiki = mWiki; rsPosted = mPosted; rsPhotoV2 = mPhotoV2; + rsGxsForums = mGxsForums; #endif rsWireVEG = mWire; - rsForumsVEG = mForumsV2; + //rsForumsVEG = mForumsV2; #endif // ENABLE_GXS_SERVICES diff --git a/libretroshare/src/serialiser/rsgxsforumitems.cc b/libretroshare/src/serialiser/rsgxsforumitems.cc new file mode 100644 index 000000000..2d0f90430 --- /dev/null +++ b/libretroshare/src/serialiser/rsgxsforumitems.cc @@ -0,0 +1,402 @@ +/* + * libretroshare/src/serialiser: rsgxsforumitems.cc + * + * RetroShare C++ Interface. + * + * 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 + +#include "rsgxsforumitems.h" +#include "serialiser/rstlvbase.h" +#include "serialiser/rsbaseserial.h" + +#define GXSFORUM_DEBUG 1 + + +uint32_t RsGxsForumSerialiser::size(RsItem *item) +{ + RsGxsForumGroupItem* grp_item = NULL; + RsGxsForumMsgItem* op_item = NULL; + + if((grp_item = dynamic_cast(item)) != NULL) + { + return sizeGxsForumGroupItem(grp_item); + } + else if((op_item = dynamic_cast(item)) != NULL) + { + return sizeGxsForumMsgItem(op_item); + } + std::cerr << "RsGxsForumSerialiser::size() ERROR invalid item" << std::endl; + return 0; +} + +bool RsGxsForumSerialiser::serialise(RsItem *item, void *data, uint32_t *size) +{ + RsGxsForumGroupItem* grp_item = NULL; + RsGxsForumMsgItem* op_item = NULL; + + if((grp_item = dynamic_cast(item)) != NULL) + { + return serialiseGxsForumGroupItem(grp_item, data, size); + } + else if((op_item = dynamic_cast(item)) != NULL) + { + return serialiseGxsForumMsgItem(op_item, data, size); + } + std::cerr << "RsGxsForumSerialiser::serialise() ERROR invalid item" << std::endl; + return false; +} + +RsItem* RsGxsForumSerialiser::deserialise(void* data, uint32_t* size) +{ + +#ifdef GXSFORUM_DEBUG + std::cerr << "RsGxsForumSerialiser::deserialise()" << std::endl; +#endif + /* get the type and size */ + uint32_t rstype = getRsItemId(data); + + if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || + (RS_SERVICE_GXSV1_TYPE_FORUMS != getRsItemService(rstype))) + { + return NULL; /* wrong type */ + } + + switch(getRsItemSubType(rstype)) + { + + case RS_PKT_SUBTYPE_GXSFORUM_GROUP_ITEM: + return deserialiseGxsForumGroupItem(data, size); + break; + case RS_PKT_SUBTYPE_GXSFORUM_MESSAGE_ITEM: + return deserialiseGxsForumMsgItem(data, size); + break; + default: +#ifdef GXSFORUM_DEBUG + std::cerr << "RsGxsForumSerialiser::deserialise(): unknown subtype"; + std::cerr << std::endl; +#endif + break; + } + return NULL; +} + + + +/*****************************************************************************************/ +/*****************************************************************************************/ +/*****************************************************************************************/ + + +void RsGxsForumGroupItem::clear() +{ + mGroup.mDescription.clear(); +} + +std::ostream& RsGxsForumGroupItem::print(std::ostream& out, uint16_t indent) +{ + printRsItemBase(out, "RsGxsForumGroupItem", indent); + uint16_t int_Indent = indent + 2; + + printIndent(out, int_Indent); + out << "Description: " << mGroup.mDescription << std::endl; + + printRsItemEnd(out ,"RsGxsForumGroupItem", indent); + return out; +} + + +uint32_t RsGxsForumSerialiser::sizeGxsForumGroupItem(RsGxsForumGroupItem *item) +{ + + const RsGxsForumGroup& group = item->mGroup; + uint32_t s = 8; // header + + s += GetTlvStringSize(group.mDescription); + + return s; +} + +bool RsGxsForumSerialiser::serialiseGxsForumGroupItem(RsGxsForumGroupItem *item, void *data, uint32_t *size) +{ + +#ifdef GXSFORUM_DEBUG + std::cerr << "RsGxsForumSerialiser::serialiseGxsForumGroupItem()" << std::endl; +#endif + + uint32_t tlvsize = sizeGxsForumGroupItem(item); + uint32_t offset = 0; + + if(*size < tlvsize) + { +#ifdef GXSFORUM_DEBUG + std::cerr << "RsGxsForumSerialiser::serialiseGxsForumGroupItem() Size too small" << std::endl; +#endif + return false; + } + + *size = tlvsize; + + bool ok = true; + + ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize); + + /* skip the header */ + offset += 8; + + /* GxsForumGroupItem */ + ok &= SetTlvString(data, tlvsize, &offset, 1, item->mGroup.mDescription); + + if(offset != tlvsize) + { +#ifdef GXSFORUM_DEBUG + std::cerr << "RsGxsForumSerialiser::serialiseGxsForumGroupItem() FAIL Size Error! " << std::endl; +#endif + ok = false; + } + +#ifdef GXSFORUM_DEBUG + if (!ok) + { + std::cerr << "RsGxsForumSerialiser::serialiseGxsForumGroupItem() NOK" << std::endl; + } +#endif + + return ok; + } + +RsGxsForumGroupItem* RsGxsForumSerialiser::deserialiseGxsForumGroupItem(void *data, uint32_t *size) +{ + +#ifdef GXSFORUM_DEBUG + std::cerr << "RsGxsForumSerialiser::deserialiseGxsForumGroupItem()" << std::endl; +#endif + /* get the type and size */ + uint32_t rstype = getRsItemId(data); + uint32_t rssize = getRsItemSize(data); + + uint32_t offset = 0; + + + if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || + (RS_SERVICE_GXSV1_TYPE_FORUMS != getRsItemService(rstype)) || + (RS_PKT_SUBTYPE_GXSFORUM_GROUP_ITEM != getRsItemSubType(rstype))) + { +#ifdef GXSFORUM_DEBUG + std::cerr << "RsGxsForumSerialiser::deserialiseGxsForumGroupItem() FAIL wrong type" << std::endl; +#endif + return NULL; /* wrong type */ + } + + if (*size < rssize) /* check size */ + { +#ifdef GXSFORUM_DEBUG + std::cerr << "RsGxsForumSerialiser::deserialiseGxsForumGroupItem() FAIL wrong size" << std::endl; +#endif + return NULL; /* not enough data */ + } + + /* set the packet length */ + *size = rssize; + + bool ok = true; + + RsGxsForumGroupItem* item = new RsGxsForumGroupItem(); + /* skip the header */ + offset += 8; + + ok &= GetTlvString(data, rssize, &offset, 1, item->mGroup.mDescription); + + if (offset != rssize) + { +#ifdef GXSFORUM_DEBUG + std::cerr << "RsGxsForumSerialiser::deserialiseGxsForumGroupItem() FAIL size mismatch" << std::endl; +#endif + /* error */ + delete item; + return NULL; + } + + if (!ok) + { +#ifdef GXSFORUM_DEBUG + std::cerr << "RsGxsForumSerialiser::deserialiseGxsForumGroupItem() NOK" << std::endl; +#endif + delete item; + return NULL; + } + + return item; +} + + + +/*****************************************************************************************/ +/*****************************************************************************************/ +/*****************************************************************************************/ + + +void RsGxsForumMsgItem::clear() +{ + mMsg.mMsg.clear(); +} + +std::ostream& RsGxsForumMsgItem::print(std::ostream& out, uint16_t indent) +{ + printRsItemBase(out, "RsGxsForumMsgItem", indent); + uint16_t int_Indent = indent + 2; + + printIndent(out, int_Indent); + out << "Msg: " << mMsg.mMsg << std::endl; + + printRsItemEnd(out ,"RsGxsForumMsgItem", indent); + return out; +} + + +uint32_t RsGxsForumSerialiser::sizeGxsForumMsgItem(RsGxsForumMsgItem *item) +{ + + const RsGxsForumMsg& msg = item->mMsg; + uint32_t s = 8; // header + + s += 4; // mMsg. + + return s; +} + +bool RsGxsForumSerialiser::serialiseGxsForumMsgItem(RsGxsForumMsgItem *item, void *data, uint32_t *size) +{ + +#ifdef GXSFORUM_DEBUG + std::cerr << "RsGxsForumSerialiser::serialiseGxsForumMsgItem()" << std::endl; +#endif + + uint32_t tlvsize = sizeGxsForumMsgItem(item); + uint32_t offset = 0; + + if(*size < tlvsize) + { +#ifdef GXSFORUM_DEBUG + std::cerr << "RsGxsForumSerialiser::serialiseGxsForumMsgItem()" << std::endl; +#endif + return false; + } + + *size = tlvsize; + + bool ok = true; + + ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize); + + /* skip the header */ + offset += 8; + + /* GxsForumMsgItem */ + ok &= SetTlvString(data, tlvsize, &offset, 1, item->mMsg.mMsg); + + if(offset != tlvsize) + { +#ifdef GXSFORUM_DEBUG + std::cerr << "RsGxsForumSerialiser::serialiseGxsForumMsgItem() FAIL Size Error! " << std::endl; +#endif + ok = false; + } + +#ifdef GXSFORUM_DEBUG + if (!ok) + { + std::cerr << "RsGxsForumSerialiser::serialiseGxsForumGroupItem() NOK" << std::endl; + } +#endif + + return ok; + } + +RsGxsForumMsgItem* RsGxsForumSerialiser::deserialiseGxsForumMsgItem(void *data, uint32_t *size) +{ + +#ifdef GXSFORUM_DEBUG + std::cerr << "RsGxsForumSerialiser::deserialiseGxsForumMsgItem()" << std::endl; +#endif + /* get the type and size */ + uint32_t rstype = getRsItemId(data); + uint32_t rssize = getRsItemSize(data); + + uint32_t offset = 0; + + + if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || + (RS_SERVICE_GXSV1_TYPE_FORUMS != getRsItemService(rstype)) || + (RS_PKT_SUBTYPE_GXSFORUM_MESSAGE_ITEM != getRsItemSubType(rstype))) + { +#ifdef GXSFORUM_DEBUG + std::cerr << "RsGxsForumSerialiser::deserialiseGxsForumMsgItem() FAIL wrong type" << std::endl; +#endif + return NULL; /* wrong type */ + } + + if (*size < rssize) /* check size */ + { +#ifdef GXSFORUM_DEBUG + std::cerr << "RsGxsForumSerialiser::deserialiseGxsForumMsgItem() FAIL wrong size" << std::endl; +#endif + return NULL; /* not enough data */ + } + + /* set the packet length */ + *size = rssize; + + bool ok = true; + + RsGxsForumMsgItem* item = new RsGxsForumMsgItem(); + /* skip the header */ + offset += 8; + + ok &= GetTlvString(data, rssize, &offset, 1, item->mMsg.mMsg); + + if (offset != rssize) + { +#ifdef GXSFORUM_DEBUG + std::cerr << "RsGxsForumSerialiser::deserialiseGxsForumMsgItem() FAIL size mismatch" << std::endl; +#endif + /* error */ + delete item; + return NULL; + } + + if (!ok) + { +#ifdef GXSFORUM_DEBUG + std::cerr << "RsGxsForumSerialiser::deserialiseGxsForumMsgItem() NOK" << std::endl; +#endif + delete item; + return NULL; + } + + return item; +} + +/*****************************************************************************************/ +/*****************************************************************************************/ +/*****************************************************************************************/ + diff --git a/libretroshare/src/serialiser/rsgxsforumitems.h b/libretroshare/src/serialiser/rsgxsforumitems.h new file mode 100644 index 000000000..3729f3a91 --- /dev/null +++ b/libretroshare/src/serialiser/rsgxsforumitems.h @@ -0,0 +1,95 @@ +/* + * libretroshare/src/serialiser: rsgxsforumitems.h + * + * RetroShare C++ Interface. + * + * 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 RS_GXS_FORUM_ITEMS_H +#define RS_GXS_FORUM_ITEMS_H + +#include + +#include "serialiser/rsserviceids.h" +#include "serialiser/rsserial.h" +#include "serialiser/rstlvtypes.h" + +#include "rsgxsitems.h" +#include "retroshare/rsgxsforums.h" + +const uint8_t RS_PKT_SUBTYPE_GXSFORUM_GROUP_ITEM = 0x02; +const uint8_t RS_PKT_SUBTYPE_GXSFORUM_MESSAGE_ITEM = 0x03; + +class RsGxsForumGroupItem : public RsGxsGrpItem +{ + +public: + + RsGxsForumGroupItem(): RsGxsGrpItem(RS_SERVICE_GXSV1_TYPE_FORUMS, + RS_PKT_SUBTYPE_GXSFORUM_GROUP_ITEM) { return;} + virtual ~RsGxsForumGroupItem() { return;} + + void clear(); + std::ostream &print(std::ostream &out, uint16_t indent = 0); + + + RsGxsForumGroup mGroup; +}; + +class RsGxsForumMsgItem : public RsGxsMsgItem +{ +public: + + RsGxsForumMsgItem(): RsGxsMsgItem(RS_SERVICE_GXSV1_TYPE_FORUMS, + RS_PKT_SUBTYPE_GXSFORUM_MESSAGE_ITEM) {return; } + virtual ~RsGxsForumMsgItem() { return;} + void clear(); + std::ostream &print(std::ostream &out, uint16_t indent = 0); + + RsGxsForumMsg mMsg; +}; + +class RsGxsForumSerialiser : public RsSerialType +{ +public: + + RsGxsForumSerialiser() + :RsSerialType(RS_PKT_VERSION_SERVICE, RS_SERVICE_GXSV1_TYPE_FORUMS) + { return; } + virtual ~RsGxsForumSerialiser() { return; } + + uint32_t size(RsItem *item); + bool serialise (RsItem *item, void *data, uint32_t *size); + RsItem * deserialise(void *data, uint32_t *size); + + private: + + uint32_t sizeGxsForumGroupItem(RsGxsForumGroupItem *item); + bool serialiseGxsForumGroupItem (RsGxsForumGroupItem *item, void *data, uint32_t *size); + RsGxsForumGroupItem * deserialiseGxsForumGroupItem(void *data, uint32_t *size); + + uint32_t sizeGxsForumMsgItem(RsGxsForumMsgItem *item); + bool serialiseGxsForumMsgItem (RsGxsForumMsgItem *item, void *data, uint32_t *size); + RsGxsForumMsgItem * deserialiseGxsForumMsgItem(void *data, uint32_t *size); + +}; + +#endif /* RS_GXS_FORUM_ITEMS_H */ diff --git a/libretroshare/src/serialiser/rsgxsiditems.cc b/libretroshare/src/serialiser/rsgxsiditems.cc index 565569e7c..02e316bec 100644 --- a/libretroshare/src/serialiser/rsgxsiditems.cc +++ b/libretroshare/src/serialiser/rsgxsiditems.cc @@ -50,7 +50,8 @@ uint32_t RsGxsIdSerialiser::size(RsItem *item) { return sizeGxsIdCommentItem(com_item); } - return NULL; + std::cerr << "RsGxsIdSerialiser::size() ERROR invalid item" << std::endl; + return 0; } bool RsGxsIdSerialiser::serialise(RsItem *item, void *data, uint32_t *size) @@ -71,13 +72,14 @@ bool RsGxsIdSerialiser::serialise(RsItem *item, void *data, uint32_t *size) { return serialiseGxsIdCommentItem(com_item, data, size); } + std::cerr << "RsGxsIdSerialiser::serialise() ERROR invalid item" << std::endl; return false; } RsItem* RsGxsIdSerialiser::deserialise(void* data, uint32_t* size) { -#ifdef RSSERIAL_DEBUG +#ifdef GXSID_DEBUG std::cerr << "RsGxsIdSerialiser::deserialise()" << std::endl; #endif /* get the type and size */ @@ -168,7 +170,7 @@ bool RsGxsIdSerialiser::serialiseGxsIdGroupItem(RsGxsIdGroupItem *item, void *da if(*size < tlvsize) { #ifdef GXSID_DEBUG - std::cerr << "RsGxsIdSerialiser::serialiseGxsIdGroupItem()" << std::endl; + std::cerr << "RsGxsIdSerialiser::serialiseGxsIdGroupItem() Size too small" << std::endl; #endif return false; } diff --git a/libretroshare/src/serialiser/rswikiitems.cc b/libretroshare/src/serialiser/rswikiitems.cc index 2d1bcb272..56d20bb6b 100644 --- a/libretroshare/src/serialiser/rswikiitems.cc +++ b/libretroshare/src/serialiser/rswikiitems.cc @@ -77,7 +77,7 @@ bool RsGxsWikiSerialiser::serialise(RsItem *item, void *data, uint32_t *size) RsItem* RsGxsWikiSerialiser::deserialise(void* data, uint32_t* size) { -#ifdef RSSERIAL_DEBUG +#ifdef GXSID_DEBUG std::cerr << "RsGxsWikiSerialiser::deserialise()" << std::endl; #endif /* get the type and size */ diff --git a/libretroshare/src/services/p3gxsforums.cc b/libretroshare/src/services/p3gxsforums.cc new file mode 100644 index 000000000..85e693d9d --- /dev/null +++ b/libretroshare/src/services/p3gxsforums.cc @@ -0,0 +1,369 @@ +/* + * libretroshare/src/services p3gxsforums.cc + * + * GxsForums 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.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/p3gxsforums.h" +#include "serialiser/rsgxsforumitems.h" + +#include "util/rsrandom.h" +#include + +/**** + * #define GXSFORUM_DEBUG 1 + ****/ + +RsGxsForums *rsGxsForums = NULL; + + + +/********************************************************************************/ +/******************* Startup / Tick ******************************************/ +/********************************************************************************/ + +p3GxsForums::p3GxsForums(RsGeneralDataService *gds, RsNetworkExchangeService *nes) + : RsGenExchange(gds, nes, new RsGxsForumSerialiser(), RS_SERVICE_GXSV1_TYPE_FORUMS), RsGxsForums(this) +{ +} + +void p3GxsForums::notifyChanges(std::vector &changes) +{ + receiveChanges(changes); +} + +void p3GxsForums::service_tick() +{ + return; +} + +bool p3GxsForums::getGroupData(const uint32_t &token, std::vector &groups) +{ + std::vector grpData; + bool ok = RsGenExchange::getGroupData(token, grpData); + + if(ok) + { + std::vector::iterator vit = grpData.begin(); + + for(; vit != grpData.end(); vit++) + { + RsGxsForumGroupItem* item = dynamic_cast(*vit); + RsGxsForumGroup grp = item->mGroup; + item->mGroup.mMeta = item->meta; + grp.mMeta = item->mGroup.mMeta; + delete item; + groups.push_back(grp); + } + } + return ok; +} + +/* Okay - chris is not going to be happy with this... + * but I can't be bothered with crazy data structures + * at the moment - fix it up later + */ + +bool p3GxsForums::getMsgData(const uint32_t &token, std::vector &msgs) +{ + 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& msgItems = mit->second; + std::vector::iterator vit = msgItems.begin(); + + for(; vit != msgItems.end(); vit++) + { + RsGxsForumMsgItem* item = dynamic_cast(*vit); + + if(item) + { + RsGxsForumMsg msg = item->mMsg; + msg.mMeta = item->meta; + msgs.push_back(msg); + delete item; + } + else + { + std::cerr << "Not a GxsForumMsgItem, deleting!" << std::endl; + delete *vit; + } + } + } + } + + return ok; +} + +/********************************************************************************************/ + +bool p3GxsForums::createGroup(uint32_t &token, RsGxsForumGroup &group) +{ + std::cerr << "p3GxsForums::createGroup()" << std::endl; + + RsGxsForumGroupItem* grpItem = new RsGxsForumGroupItem(); + grpItem->mGroup = group; + grpItem->meta = group.mMeta; + + RsGenExchange::publishGroup(token, grpItem); + return true; +} + + +bool p3GxsForums::createMsg(uint32_t &token, RsGxsForumMsg &msg) +{ + std::cerr << "p3GxsForums::createForumMsg() GroupId: " << msg.mMeta.mGroupId; + std::cerr << std::endl; + + RsGxsForumMsgItem* msgItem = new RsGxsForumMsgItem(); + msgItem->mMsg = msg; + msgItem->meta = msg.mMeta; + + RsGenExchange::publishMsg(token, msgItem); + return true; +} + + +/********************************************************************************************/ + + +std::string p3GxsForums::genRandomId() +{ + std::string randomId; + for(int i = 0; i < 20; i++) + { + randomId += (char) ('a' + (RSRandom::random_u32() % 26)); + } + + return randomId; +} + +bool p3GxsForums::generateDummyData() +{ + return false; +} + + +#if 0 + +bool p3GxsForums::generateDummyData() +{ + /* so we want to generate 100's of forums */ +#define MAX_FORUMS 10 //100 +#define MAX_THREADS 10 //1000 +#define MAX_MSGS 100 //10000 + + std::list mGroups; + std::list::iterator git; + + std::list mMsgs; + std::list::iterator mit; + +#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. + * Flags. + * Pop. + */ + + + + /* use probability to decide which are subscribed / own / popularity. + */ + + float rnd = RSRandom::random_f32(); + if (rnd < 0.1) + { + forum.mMeta.mSubscribeFlags = RSGXS_GROUP_SUBSCRIBE_ADMIN; + + } + else if (rnd < 0.3) + { + forum.mMeta.mSubscribeFlags = RSGXS_GROUP_SUBSCRIBE_SUBSCRIBED; + } + else + { + forum.mMeta.mSubscribeFlags = 0; + } + + forum.mMeta.mPop = (int) (RSRandom::random_f32() * 10.0); + + mGroups.push_back(forum); + + + //std::cerr << "p3GxsForums::generateDummyData() Generated Forum: " << forum.mMeta; + //std::cerr << std::endl; + } + + + for(i = 0; i < MAX_THREADS; 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++) + { + RsForumV2Group head = mGroups.front(); + mGroups.pop_front(); + mGroups.push_back(head); + } + + RsForumV2Group forum = mGroups.front(); + + /* now create a new thread */ + + RsForumV2Msg msg; + + /* fill in key data + * GroupId + * MsgId + * OrigMsgId + * ThreadId + * ParentId + * PublishTS (take Forum TS + a bit ). + * + * 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 << "p3GxsForums::generateDummyData() Generated Thread: " << msg.mMeta; + //std::cerr << std::endl; + + } + + for(i = 0; i < MAX_MSGS; 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++) + { + RsForumV2Msg head = mMsgs.front(); + mMsgs.pop_front(); + mMsgs.push_back(head); + } + + RsForumV2Msg parent = mMsgs.front(); + + /* now create a new child msg */ + + RsForumV2Msg msg; + + /* fill in key data + * GroupId + * MsgId + * OrigMsgId + * ThreadId + * ParentId + * PublishTS (take Forum TS + a bit ). + * + * 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 << "p3GxsForums::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/p3gxsforums.h b/libretroshare/src/services/p3gxsforums.h new file mode 100644 index 000000000..db765c980 --- /dev/null +++ b/libretroshare/src/services/p3gxsforums.h @@ -0,0 +1,73 @@ +/* + * libretroshare/src/services: p3gxsforums.h + * + * GxsForum 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_GXSFORUMS_SERVICE_HEADER +#define P3_GXSFORUMS_SERVICE_HEADER + + +#include "retroshare/rsgxsforums.h" +#include "gxs/rsgenexchange.h" + +#include +#include + +/* + * + */ + +class p3GxsForums: public RsGenExchange, public RsGxsForums +{ + public: + + p3GxsForums(RsGeneralDataService* gds, RsNetworkExchangeService* nes); + + protected: + +virtual void notifyChanges(std::vector& changes); +virtual void service_tick(); + + public: + +virtual bool getGroupData(const uint32_t &token, std::vector &groups); +virtual bool getMsgData(const uint32_t &token, std::vector &msgs); + + ////////////////////////////////////////////////////////////////////////////// +//virtual bool setMessageStatus(const std::string &msgId, const uint32_t status, const uint32_t statusMask); +//virtual bool setGroupSubscribeFlags(const std::string &groupId, uint32_t subscribeFlags, uint32_t subscribeMask); + +//virtual bool groupRestoreKeys(const std::string &groupId); +//virtual bool groupShareKeys(const std::string &groupId, std::list& peers); + +virtual bool createGroup(uint32_t &token, RsGxsForumGroup &group); +virtual bool createMsg(uint32_t &token, RsGxsForumMsg &msg); + + private: + +std::string genRandomId(); +bool generateDummyData(); + +}; + +#endif diff --git a/libretroshare/src/services/p3wiki.cc b/libretroshare/src/services/p3wiki.cc index d84cf0f98..da98038b0 100644 --- a/libretroshare/src/services/p3wiki.cc +++ b/libretroshare/src/services/p3wiki.cc @@ -26,6 +26,8 @@ #include "services/p3wiki.h" #include "serialiser/rswikiitems.h" +#include "util/rsrandom.h" + /**** * #define WIKI_DEBUG 1 ****/ @@ -48,12 +50,18 @@ void p3Wiki::service_tick() void p3Wiki::notifyChanges(std::vector& changes) { + std::cerr << "p3Wiki::notifyChanges() New stuff"; + std::cerr << std::endl; + receiveChanges(changes); } /* Specific Service Data */ bool p3Wiki::getCollections(const uint32_t &token, std::vector &collections) { + std::cerr << "p3Wiki::getCollections()"; + std::cerr << std::endl; + std::vector grpData; bool ok = RsGenExchange::getGroupData(token, grpData); @@ -64,10 +72,25 @@ bool p3Wiki::getCollections(const uint32_t &token, std::vector for(; vit != grpData.end(); vit++) { RsGxsWikiCollectionItem* item = dynamic_cast(*vit); - RsWikiCollection collection = item->collection; - collection.mMeta = item->collection.mMeta; - delete item; - collections.push_back(collection); + + 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; + } + } } return ok; @@ -159,6 +182,15 @@ 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; } @@ -188,3 +220,64 @@ bool p3Wiki::submitComment(uint32_t &token, RsWikiComment &comment) } + +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; +} + +std::ostream &operator<<(std::ostream &out, const RsWikiSnapshot &shot) +{ + out << "RsWikiSnapshot [ "; + out << "Title: " << shot.mMeta.mMsgName; + out << "]"; + return out; +} + +std::ostream &operator<<(std::ostream &out, const RsWikiComment &comment) +{ + out << "RsWikiComment [ "; + out << "Title: " << comment.mMeta.mMsgName; + out << "]"; + return out; +} + + +/***** FOR TESTING *****/ + +std::string p3Wiki::genRandomId() +{ + std::string randomId; + for(int i = 0; i < 20; i++) + { + randomId += (char) ('a' + (RSRandom::random_u32() % 26)); + } + + return randomId; +} + +void p3Wiki::generateDummyData() +{ + +#define GEN_COLLECTIONS 10 + + int i; + for(i = 0; i < GEN_COLLECTIONS; i++) + { + RsWikiCollection wiki; + wiki.mMeta.mGroupId = genRandomId(); + wiki.mMeta.mGroupFlags = 0; + wiki.mMeta.mGroupName = genRandomId(); + + uint32_t dummyToken = 0; + submitCollection(dummyToken, wiki); + } +} + + + diff --git a/libretroshare/src/services/p3wiki.h b/libretroshare/src/services/p3wiki.h index 7a8f74b2a..11e347cf1 100644 --- a/libretroshare/src/services/p3wiki.h +++ b/libretroshare/src/services/p3wiki.h @@ -60,9 +60,11 @@ virtual bool submitCollection(uint32_t &token, RsWikiCollection &collection); virtual bool submitSnapshot(uint32_t &token, RsWikiSnapshot &snapshot); virtual bool submitComment(uint32_t &token, RsWikiComment &comment); +virtual void generateDummyData(); + private: -//std::string genRandomId(); +std::string genRandomId(); // RsMutex mWikiMtx;