diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index 238124c48..461020aae 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -681,17 +681,23 @@ newservices { HEADERS += services/p3photoservice.h \ retroshare/rsphoto.h \ + services/p3gxsservice.h \ + retroshare/rsidentity.h \ services/p3wikiservice.h \ retroshare/rswiki.h \ + retroshare/rswire.h \ + services/p3wire.h \ services/p3idservice.h \ - retroshare/rsidentity.h \ - services/p3gxsservice.h \ + retroshare/rsforumsv2.h \ + services/p3forumsv2.h \ SOURCES += services/p3photoservice.cc \ serialiser/rsphotoitems.cc \ - services/p3wikiservice.cc \ - services/p3idservice.cc \ services/p3gxsservice.cc \ + services/p3wikiservice.cc \ + services/p3wire.cc \ + services/p3idservice.cc \ + services/p3forumsv2.cc \ # Other Old Code. # rsserver/p3photo.cc \ diff --git a/libretroshare/src/retroshare/rsforumsv2.h b/libretroshare/src/retroshare/rsforumsv2.h new file mode 100644 index 000000000..2dd29e7bc --- /dev/null +++ b/libretroshare/src/retroshare/rsforumsv2.h @@ -0,0 +1,142 @@ +#ifndef RETROSHARE_FORUMV2_GUI_INTERFACE_H +#define RETROSHARE_FORUMV2_GUI_INTERFACE_H + +/* + * libretroshare/src/retroshare: rsforumv2.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 + +/* The Main Interface Class - for information about your Peers */ +class RsForumsV2; +extern RsForumsV2 *rsForumsV2; + +class RsForumV2Group +{ + public: + + // All the MetaData is Stored here: + RsGroupMetaData mMeta; + + // THESE ARE IN THE META DATA. + //std::string mGroupId; + //std::string mName; + + std::string mDescription; + + // THESE ARE CURRENTLY UNUSED. + //std::string mCategory; + //std::string mHashTags; +}; + +class RsForumV2Msg +{ + public: + + // All the MetaData is Stored here: + RsMsgMetaData mMeta; + + // THESE ARE IN THE META DATA. + //std::string mGroupId; + //std::string mMsgId; + //std::string mOrigMsgId; + //std::string mThreadId; + //std::string mParentId; + //std::string mName; (aka. Title) + + std::string mMsg; // all the text is stored here. + + // THESE ARE CURRENTLY UNUSED. + //std::string mHashTags; +}; + +class RsForumsV2: public RsTokenService +{ + public: + + RsForumsV2() { return; } +virtual ~RsForumsV2() { return; } + + /* changed? */ +virtual bool updated() = 0; + + /* Data Requests */ +//virtual bool requestGroupInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &groupIds) = 0; +//virtual bool requestMsgInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &groupIds) = 0; +//virtual bool requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &msgIds) = 0; + + /* Generic Lists */ +//virtual bool getGroupList( const uint32_t &token, std::list &groupIds) = 0; +//virtual bool getMsgList( const uint32_t &token, std::list &msgIds) = 0; + + /* Generic Summary */ +//virtual bool getGroupSummary( const uint32_t &token, std::list &groupInfo) = 0; +//virtual bool getMsgSummary( const uint32_t &token, std::list &msgInfo) = 0; + + /* Specific Service Data */ +virtual bool getGroupData(const uint32_t &token, RsForumV2Group &group) = 0; +virtual bool getMsgData(const uint32_t &token, RsForumV2Msg &msg) = 0; + + + + /* FUNCTIONS THAT HAVE BEEN COPIED FROM THE ORIGINAL FORUMS.... + * -> TODO, Split into generic and specific functions! + */ + ////////////////////////////////////////////////////////////////////////////// + /* Functions from Forums -> need to be implemented generically */ +//virtual bool groupsChanged(std::list &groupIds) = 0; + + // Get Message Status - is retrived via MessageSummary. +//virtual bool setMessageStatus(const std::string &msgId, const uint32_t status, const uint32_t statusMask) = 0; + + // +//virtual bool groupSubscribe(const std::string &groupId, bool subscribe) = 0; + +//virtual bool groupRestoreKeys(const std::string &groupId) = 0; +//virtual bool groupShareKeys(const std::string &groupId, std::list& peers) = 0; + + + // ONES THAT WE ARE NOT IMPLEMENTING. (YET!) + +//virtual bool getMessageStatus(const std::string& fId, const std::string& mId, uint32_t& status) = 0; + +// THINK WE CAN GENERALISE THIS TO: a list function, and you can just count the list entries... +// requestGroupList(groupId, UNREAD, ...) +//virtual bool getMessageCount(const std::string &groupId, unsigned int &newCount, unsigned int &unreadCount) = 0; + + + +/* details are updated in group - to choose GroupID */ +virtual bool createGroup(RsForumV2Group &group) = 0; +virtual bool createMsg(RsForumV2Msg &msg) = 0; + +}; + + + +#endif diff --git a/libretroshare/src/retroshare/rsidentity.h b/libretroshare/src/retroshare/rsidentity.h index d8764849a..3820354c5 100644 --- a/libretroshare/src/retroshare/rsidentity.h +++ b/libretroshare/src/retroshare/rsidentity.h @@ -30,6 +30,8 @@ #include #include +// FLAGS WILL BE REUSED FROM RSDISTRIB -> FOR NOW. +#include /********** Generic Token Request Interface *********************** * This is packaged here, as most TokenServices will require ID Services too. @@ -37,12 +39,33 @@ */ // This bit will be filled out over time. -#define RS_TOKREQOPT_MSG_VERSIONS 0x0001 -#define RS_TOKREQOPT_MSG_ORIGMSG 0x0002 -#define RS_TOKREQOPT_MSG_LATEST 0x0003 +#define RS_TOKREQOPT_MSG_VERSIONS 0x0001 // MSGRELATED: Returns All MsgIds with OrigMsgId = MsgId. +#define RS_TOKREQOPT_MSG_ORIGMSG 0x0002 // MSGLIST: All Unique OrigMsgIds in a Group. +#define RS_TOKREQOPT_MSG_LATEST 0x0004 // MSGLIST: All Latest MsgIds in Group. MSGRELATED: Latest MsgIds for Input Msgs. + +#define RS_TOKREQOPT_MSG_THREAD 0x0010 // MSGRELATED: All Msgs in Thread. MSGLIST: All Unique Thread Ids in Group. +#define RS_TOKREQOPT_MSG_PARENT 0x0020 // MSGRELATED: All Children Msgs. + +#define RS_TOKREQOPT_MSG_AUTHOR 0x0040 // MSGLIST: Messages from this AuthorId + + + +// Read Status. +#define RS_TOKREQOPT_READ 0x0001 +#define RS_TOKREQOPT_UNREAD 0x0002 + +#define RS_TOKREQ_ANSTYPE_LIST 0x0001 +#define RS_TOKREQ_ANSTYPE_SUMMARY 0x0002 +#define RS_TOKREQ_ANSTYPE_DATA 0x0003 + + + +// TEMP FLAGS... TO FIX. +#define RSGXS_MSG_STATUS_MASK 0x000f +#define RSGXS_MSG_STATUS_READ 0x0001 +#define RSGXS_MSG_STATUS_UNREAD_BY_USER 0x0002 + -#define RS_TOKREQOPT_MSG_THREAD 0x0004 -#define RS_TOKREQOPT_MSG_PARENT 0x0005 class RsTokReqOptions { @@ -54,6 +77,80 @@ class RsTokReqOptions time_t mAfter; }; + + + + +class RsGroupMetaData +{ + public: + + RsGroupMetaData() + { + mGroupFlags = 0; + mSubscribeFlags = 0; + + mPop = 0; + mMsgCount = 0; + mLastPost = 0; + mGroupStatus = 0; + } + + std::string mGroupId; + std::string mGroupName; + uint32_t mGroupFlags; + + // BELOW HERE IS LOCAL DATA, THAT IS NOT FROM MSG. + + uint32_t mSubscribeFlags; + + uint32_t mPop; // HOW DO WE DO THIS NOW. + uint32_t mMsgCount; // ??? + time_t mLastPost; // ??? + + uint32_t mGroupStatus; + +}; + + + + +class RsMsgMetaData +{ + public: + + RsMsgMetaData() + { + mPublishTs = 0; + mMsgFlags = 0; + mMsgStatus = 0; + mChildTs = 0; + } + + std::string mGroupId; + std::string mMsgId; + + std::string mThreadId; + std::string mParentId; + std::string mOrigMsgId; + + std::string mAuthorId; + + std::string mMsgName; + time_t mPublishTs; + + uint32_t mMsgFlags; // Whats this for? + + // BELOW HERE IS LOCAL DATA, THAT IS NOT FROM MSG. + // normally READ / UNREAD flags. LOCAL Data. + uint32_t mMsgStatus; + time_t mChildTs; + +}; + +std::ostream &operator<<(std::ostream &out, const RsGroupMetaData &meta); +std::ostream &operator<<(std::ostream &out, const RsMsgMetaData &meta); + class RsTokenService { public: @@ -62,16 +159,45 @@ class RsTokenService virtual ~RsTokenService() { return; } /* Data Requests */ -virtual bool requestGroupList( uint32_t &token, const RsTokReqOptions &opts) = 0; -virtual bool requestMsgList( uint32_t &token, const RsTokReqOptions &opts, const std::list &groupIds) = 0; -virtual bool requestMsgRelatedList(uint32_t &token, const RsTokReqOptions &opts, const std::list &msgIds) = 0; +virtual bool requestGroupInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &groupIds) = 0; +virtual bool requestMsgInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &groupIds) = 0; +virtual bool requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &msgIds) = 0; + + /* Generic Lists */ +virtual bool getGroupList( const uint32_t &token, std::list &groupIds) = 0; +virtual bool getMsgList( const uint32_t &token, std::list &msgIds) = 0; + + /* Generic Summary */ +virtual bool getGroupSummary( const uint32_t &token, std::list &groupInfo) = 0; +virtual bool getMsgSummary( const uint32_t &token, std::list &msgInfo) = 0; + + /* Actual Data -> specific to Interface */ + -virtual bool requestGroupData( uint32_t &token, const std::list &groupIds) = 0; -virtual bool requestMsgData( uint32_t &token, const std::list &msgIds) = 0; /* Poll */ virtual uint32_t requestStatus(const uint32_t token) = 0; + /* Cancel Request */ +virtual bool cancelRequest(const uint32_t &token) = 0; + + + ////////////////////////////////////////////////////////////////////////////// + /* Functions from Forums -> need to be implemented generically */ +virtual bool groupsChanged(std::list &groupIds) = 0; + + // Get Message Status - is retrived via MessageSummary. +virtual bool setMessageStatus(const std::string &msgId, const uint32_t status, const uint32_t statusMask) = 0; + + // +virtual bool groupSubscribe(const std::string &groupId, bool subscribe) = 0; + +virtual bool groupRestoreKeys(const std::string &groupId) = 0; +virtual bool groupShareKeys(const std::string &groupId, std::list& peers) = 0; + + + + }; @@ -95,12 +221,16 @@ extern RsIdentity *rsIdentity; std::string rsIdTypeToString(uint32_t idtype); -class RsIdData +class RsIdGroup { public: - std::string mNickname; - std::string mKeyId; + + RsGroupMetaData mMeta; + + // In GroupMetaData. + //std::string mNickname; (mGroupName) + //std::string mKeyId; (mGroupId) uint32_t mIdType; @@ -112,6 +242,27 @@ class RsIdData std::string mGpgEmail; // if known. }; + + +class RsIdMsg +{ + public: + + RsMsgMetaData mMeta; + + // In MsgMetaData. + //std::string mKeyId; (mGroupId) + //std::string mPeerId; (mAuthorId) ??? + + int mRating; + int mPeersRating; + std::string mComment; +}; + + + + +#if 0 class RsIdReputation { public: @@ -137,8 +288,10 @@ class RsIdOpinion std::string mComment; }; +#endif -class RsIdentity + +class RsIdentity: public RsTokenService { public: @@ -149,8 +302,30 @@ virtual ~RsIdentity() { return; } /* changed? */ virtual bool updated() = 0; - /* Interface now a request / poll / answer system */ + /* INCLUDES INTERFACE FROM RS TOKEN SERVICE */ + ////////////////////////////////////////////////////////////////////////////// + + + /* Specific Service Data */ +virtual bool getGroupData(const uint32_t &token, RsIdGroup &group) = 0; +virtual bool getMsgData(const uint32_t &token, RsIdMsg &msg) = 0; + +virtual bool createGroup(RsIdGroup &group) = 0; +virtual bool createMsg(RsIdMsg &msg) = 0; + + + + /* In the Identity System - You don't access the Messages Directly. + * as they represent idividuals opinions.... + * This is reflected in the TokenService calls returning false. + * + * Below is the additional interface to look at reputation. + */ + +virtual void generateDummyData() = 0; + +#if 0 /* Data Requests */ virtual bool requestIdentityList(uint32_t &token) = 0; virtual bool requestIdentities(uint32_t &token, const std::list &ids) = 0; @@ -171,8 +346,8 @@ virtual bool getIdPeerOpinion(const uint32_t token, RsIdOpinion &opinion) = 0; virtual bool updateIdentity(RsIdData &data) = 0; virtual bool updateOpinion(RsIdOpinion &opinion) = 0; - /* TEMP */ -virtual void generateDummyData() = 0; +#endif + }; diff --git a/libretroshare/src/retroshare/rsphoto.h b/libretroshare/src/retroshare/rsphoto.h index 6fc43b297..70ccbd607 100644 --- a/libretroshare/src/retroshare/rsphoto.h +++ b/libretroshare/src/retroshare/rsphoto.h @@ -59,10 +59,13 @@ class RsPhotoPhoto { public: - std::string mAlbumId; - std::string mId; + RsMsgMetaData mMeta; + + // THESE ARE IN THE META DATA. + //std::string mAlbumId; + //std::string mId; + //std::string mTitle; // only used by Album. - std::string mTitle; // only used by Album. std::string mCaption; std::string mDescription; std::string mPhotographer; @@ -92,10 +95,30 @@ class RsPhotoAlbumShare uint32_t mResizeMode; }; -class RsPhotoAlbum: public RsPhotoPhoto +class RsPhotoAlbum { public: + RsGroupMetaData mMeta; + + // THESE ARE IN THE META DATA. + //std::string mAlbumId; + //std::string mTitle; // only used by Album. + + std::string mCaption; + std::string mDescription; + std::string mPhotographer; + std::string mWhere; + std::string mWhen; + std::string mOther; + std::string mCategory; + + std::string mHashTags; + + RsPhotoThumbnail mThumbnail; + + int mMode; + std::string mPhotoPath; RsPhotoAlbumShare mShareOptions; }; @@ -111,20 +134,43 @@ virtual ~RsPhoto() { return; } /* changed? */ virtual bool updated() = 0; - /* Data Requests (from RsTokenService) */ -//virtual bool requestGroupList( uint32_t &token, const RsTokReqOptions &opts) = 0; -//virtual bool requestMsgList( uint32_t &token, const RsTokReqOptions &opts, const std::list &groupIds) = 0; -//virtual bool requestMsgRelatedList(uint32_t &token, const RsTokReqOptions &opts, const std::list &msgIds) = 0; + /* Data Requests */ +//virtual bool requestGroupInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &groupIds) = 0; +//virtual bool requestMsgInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &groupIds) = 0; +//virtual bool requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &msgIds) = 0; + + /* Generic Lists */ +//virtual bool getGroupList( const uint32_t &token, std::list &groupIds) = 0; +//virtual bool getMsgList( const uint32_t &token, std::list &msgIds) = 0; + + /* Generic Summary */ +//virtual bool getGroupSummary( const uint32_t &token, std::list &groupInfo) = 0; +//virtual bool getMsgSummary( const uint32_t &token, std::list &msgInfo) = 0; + + /* Actual Data -> specific to Interface */ + -//virtual bool requestGroupData( uint32_t &token, const std::list &groupIds) = 0; -//virtual bool requestMsgData( uint32_t &token, const std::list &msgIds) = 0; /* Poll */ //virtual uint32_t requestStatus(const uint32_t token) = 0; - /* Generic List Data */ -virtual bool getGroupList(const uint32_t &token, std::list &groupIds) = 0; -virtual bool getMsgList(const uint32_t &token, std::list &msgIds) = 0; + /* Cancel Request */ +//virtual bool cancelRequest(const uint32_t &token) = 0; + + + ////////////////////////////////////////////////////////////////////////////// + /* Functions from Forums -> need to be implemented generically */ +//virtual bool groupsChanged(std::list &groupIds) = 0; + + // Get Message Status - is retrived via MessageSummary. +//virtual bool setMessageStatus(const std::string &msgId, const uint32_t status, const uint32_t statusMask) = 0; + + // +//virtual bool groupSubscribe(const std::string &groupId, bool subscribe) = 0; + +//virtual bool groupRestoreKeys(const std::string &groupId) = 0; +//virtual bool groupShareKeys(const std::string &groupId, std::list& peers) = 0; + /* Specific Service Data */ virtual bool getAlbum(const uint32_t &token, RsPhotoAlbum &album) = 0; @@ -134,27 +180,6 @@ virtual bool getPhoto(const uint32_t &token, RsPhotoPhoto &photo) = 0; virtual bool submitAlbumDetails(RsPhotoAlbum &album) = 0; virtual bool submitPhoto(RsPhotoPhoto &photo) = 0; - -#if 0 -virtual bool requestAlbumList(uint32_t &token) = 0; -virtual bool requestPhotoList(uint32_t &token, const std::list &albumids) = 0; - -virtual bool requestAlbums(uint32_t &token, const std::list &albumids) = 0; -virtual bool requestPhotos(uint32_t &token, const std::list &photoids) = 0; - -virtual bool getAlbumList(const uint32_t &token, std::list &albums) = 0; -virtual bool getPhotoList(const uint32_t &token, std::list &photos) = 0; - - - -virtual bool requestGroupList(uint32_t &token) { return requestAlbumList(token); } -virtual bool requestGroupData(uint32_t &token, const std::list &ids) { return requestAlbums(token, ids); } -virtual bool requestMsgList(uint32_t &token, const std::list &ids) { return requestPhotoList(token, ids); } -virtual bool requestMsgData(uint32_t &token, const std::list &ids) { return requestPhotos(token, ids); } -#endif - - - }; diff --git a/libretroshare/src/retroshare/rswiki.h b/libretroshare/src/retroshare/rswiki.h index f98d5131a..4062e8e84 100644 --- a/libretroshare/src/retroshare/rswiki.h +++ b/libretroshare/src/retroshare/rswiki.h @@ -51,9 +51,11 @@ class RsWikiGroup { public: - std::string mGroupId; + RsGroupMetaData mMeta; + + //std::string mGroupId; + //std::string mName; - std::string mName; std::string mDescription; std::string mCategory; @@ -66,13 +68,17 @@ class RsWikiPage { public: + RsMsgMetaData mMeta; - std::string mGroupId; - std::string mOrigPageId; + // IN META DATA. + //std::string mGroupId; + //std::string mOrigPageId; + //std::string mPageId; + //std::string mName; + + // WE SHOULD SWITCH TO USING THREAD/PARENT IDS HERE.... std::string mPrevId; - std::string mPageId; - std::string mName; std::string mPage; // all the text is stored here. std::string mHashTags; diff --git a/libretroshare/src/retroshare/rswire.h b/libretroshare/src/retroshare/rswire.h new file mode 100644 index 000000000..406b13f68 --- /dev/null +++ b/libretroshare/src/retroshare/rswire.h @@ -0,0 +1,106 @@ +#ifndef RETROSHARE_WIRE_GUI_INTERFACE_H +#define RETROSHARE_WIRE_GUI_INTERFACE_H + +/* + * libretroshare/src/retroshare: rswire.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 + +/* The Main Interface Class - for information about your Peers */ +class RsWire; +extern RsWire *rsWire; + +class RsWireGroupShare +{ + public: + + uint32_t mShareType; + std::string mShareGroupId; + std::string mPublishKey; + uint32_t mCommentMode; + uint32_t mResizeMode; +}; + +class RsWireGroup +{ + public: + + RsGroupMetaData mMeta; + + //std::string mGroupId; + //std::string mName; + + std::string mDescription; + std::string mCategory; + + std::string mHashTags; + + RsWireGroupShare mShareOptions; +}; + +class RsWirePulse +{ + public: + + RsMsgMetaData mMeta; + + //std::string mGroupId; + //std::string mOrigPageId; + //std::string mPrevId; + //std::string mPageId; + //std::string mName; + + std::string mPulse; // all the text is stored here. + + std::string mHashTags; +}; + +class RsWire: public RsTokenService +{ + public: + + RsWire() { return; } +virtual ~RsWire() { return; } + + /* changed? */ +virtual bool updated() = 0; + + /* Specific Service Data */ +virtual bool getGroupData(const uint32_t &token, RsWireGroup &group) = 0; +virtual bool getMsgData(const uint32_t &token, RsWirePulse &pulse) = 0; + + /* Create Stuff */ +virtual bool createGroup(RsWireGroup &group) = 0; +virtual bool createPulse(RsWirePulse &pulse) = 0; + +}; + + + +#endif diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index 11f5ecbcd..9428f2c14 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -1734,7 +1734,9 @@ RsTurtle *rsTurtle = NULL ; #include "services/p3photoservice.h" #include "services/p3wikiservice.h" +#include "services/p3wire.h" #include "services/p3idservice.h" +#include "services/p3forumsv2.h" #ifndef PQI_DISABLE_TUNNEL #include "services/p3tunnel.h" @@ -2141,10 +2143,18 @@ int RsServer::StartupRetroShare() p3WikiService *mWikis = new p3WikiService(RS_SERVICE_TYPE_WIKI); pqih -> addService(mWikis); + // Testing New Cache Services. + p3Wire *mWire = new p3Wire(RS_SERVICE_TYPE_WIRE); + pqih -> addService(mWire); + // Testing New Cache Services. p3IdService *mIdentity = new p3IdService(RS_SERVICE_TYPE_IDENTITY); pqih -> addService(mIdentity); + // Testing New Cache Services. + //p3ForumsV2 *mForumsV2 = new p3ForumsV2(RS_SERVICE_TYPE_FORUMSV2); + //pqih -> addService(mForumsV2); + #ifndef RS_RELEASE p3GameLauncher *gameLauncher = new p3GameLauncher(mLinkMgr); pqih -> addService(gameLauncher); @@ -2412,9 +2422,11 @@ int RsServer::StartupRetroShare() rsChannels = mChannels; // Testing of new cache system interfaces. + rsIdentity = mIdentity; rsPhoto = mPhotos; rsWiki = mWikis; - rsIdentity = mIdentity; + rsWire = mWire; + //rsForumsV2 = mForumsV2; #ifdef RS_USE_BLOGS rsBlogs = mBlogs; diff --git a/libretroshare/src/serialiser/rsserviceids.h b/libretroshare/src/serialiser/rsserviceids.h index 32b6ecec8..e417e5e8a 100644 --- a/libretroshare/src/serialiser/rsserviceids.h +++ b/libretroshare/src/serialiser/rsserviceids.h @@ -103,10 +103,11 @@ const uint16_t RS_SERVICE_TYPE_PROXY = 0xf030; const uint16_t RS_SERVICE_TYPE_DSDV = 0xf050; /* New Cache Services */ +const uint16_t RS_SERVICE_TYPE_IDENTITY = 0xf100; 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_IDENTITY = 0xf103; +const uint16_t RS_SERVICE_TYPE_FORUMSV2 = 0xf104; //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 new file mode 100644 index 000000000..1f0e6b3b8 --- /dev/null +++ b/libretroshare/src/services/p3forumsv2.cc @@ -0,0 +1,714 @@ +/* + * libretroshare/src/services p3forumsv2.cc + * + * ForumsV2 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/p3forumsv2.h" + +#include "util/rsrandom.h" + +/**** + * #define FORUMV2_DEBUG 1 + ****/ + +RsForumsV2 *rsForumsV2 = NULL; + + + +/********************************************************************************/ +/******************* Startup / Tick ******************************************/ +/********************************************************************************/ + +p3ForumsV2::p3ForumsV2(uint16_t type) + :p3GxsDataService(type, new ForumDataProxy()), mForumMtx("p3ForumsV2"), mUpdated(true) +{ + RsStackMutex stack(mForumMtx); /********** STACK LOCKED MTX ******/ + + mForumProxy = (ForumDataProxy *) mProxy; + return; +} + + +int p3ForumsV2::tick() +{ + std::cerr << "p3ForumsV2::tick()"; + std::cerr << std::endl; + + fakeprocessrequests(); + + return 0; +} + +bool p3ForumsV2::updated() +{ + RsStackMutex stack(mForumMtx); /********** STACK LOCKED MTX ******/ + + if (mUpdated) + { + mUpdated = false; + return true; + } + return false; +} + + + + /* Data Requests */ +bool p3ForumsV2::requestGroupInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &groupIds) +{ + generateToken(token); + std::cerr << "p3ForumsV2::requestGroupInfo() gets Token: " << token << std::endl; + storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_GROUPS, groupIds); + + return true; +} + +bool p3ForumsV2::requestMsgInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &groupIds) +{ + generateToken(token); + std::cerr << "p3ForumsV2::requestMsgInfo() gets Token: " << token << std::endl; + storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_MSGS, groupIds); + + return true; +} + +bool p3ForumsV2::requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &msgIds) +{ + generateToken(token); + std::cerr << "p3ForumsV2::requestMsgRelatedInfo() gets Token: " << token << std::endl; + storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_MSGRELATED, msgIds); + + return true; +} + + /* Generic Lists */ +bool p3ForumsV2::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 << "p3ForumsV2::getGroupList() ERROR AnsType Wrong" << std::endl; + return false; + } + + if (reqtype != GXS_REQUEST_TYPE_GROUPS) + { + std::cerr << "p3ForumsV2::getGroupList() ERROR ReqType Wrong" << std::endl; + return false; + } + + if (status != GXS_REQUEST_STATUS_COMPLETE) + { + std::cerr << "p3ForumsV2::getGroupList() ERROR Status Incomplete" << std::endl; + return false; + } + + bool ans = loadRequestOutList(token, groupIds); + updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); + + return ans; +} + + + + +bool p3ForumsV2::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 << "p3ForumsV2::getMsgList() ERROR AnsType Wrong" << std::endl; + return false; + } + + if ((reqtype != GXS_REQUEST_TYPE_MSGS) && (reqtype != GXS_REQUEST_TYPE_MSGRELATED)) + { + std::cerr << "p3ForumsV2::getMsgList() ERROR ReqType Wrong" << std::endl; + return false; + } + + if (status != GXS_REQUEST_STATUS_COMPLETE) + { + std::cerr << "p3ForumsV2::getMsgList() ERROR Status Incomplete" << std::endl; + return false; + } + + bool ans = loadRequestOutList(token, msgIds); + updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); + + return ans; +} + + + /* Generic Summary */ +bool p3ForumsV2::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 << "p3ForumsV2::getGroupSummary() ERROR AnsType Wrong" << std::endl; + return false; + } + + if (reqtype != GXS_REQUEST_TYPE_GROUPS) + { + std::cerr << "p3ForumsV2::getGroupSummary() ERROR ReqType Wrong" << std::endl; + return false; + } + + if (status != GXS_REQUEST_STATUS_COMPLETE) + { + std::cerr << "p3ForumsV2::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 p3ForumsV2::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 << "p3ForumsV2::getMsgSummary() ERROR AnsType Wrong" << std::endl; + return false; + } + + if ((reqtype != GXS_REQUEST_TYPE_MSGS) && (reqtype != GXS_REQUEST_TYPE_MSGRELATED)) + { + std::cerr << "p3ForumsV2::getMsgSummary() ERROR ReqType Wrong" << std::endl; + return false; + } + + if (status != GXS_REQUEST_STATUS_COMPLETE) + { + std::cerr << "p3ForumsV2::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 p3ForumsV2::getGroupData(const uint32_t &token, RsForumV2Group &group) +{ + 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 << "p3ForumsV2::getGroupData() ERROR AnsType Wrong" << std::endl; + return false; + } + + if (reqtype != GXS_REQUEST_TYPE_GROUPS) + { + std::cerr << "p3ForumsV2::getGroupData() ERROR ReqType Wrong" << std::endl; + return false; + } + + if (status != GXS_REQUEST_STATUS_COMPLETE) + { + std::cerr << "p3ForumsV2::getGroupData() 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 RsForumAlbum */ + bool ans = mForumProxy->getForumGroup(id, group); + return ans; +} + + +bool p3ForumsV2::getMsgData(const uint32_t &token, RsForumV2Msg &msg) +{ + 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 << "p3ForumsV2::getMsgData() ERROR AnsType Wrong" << std::endl; + return false; + } + + if ((reqtype != GXS_REQUEST_TYPE_MSGS) && (reqtype != GXS_REQUEST_TYPE_MSGRELATED)) + { + std::cerr << "p3ForumsV2::getMsgData() ERROR ReqType Wrong" << std::endl; + return false; + } + + if (status != GXS_REQUEST_STATUS_COMPLETE) + { + std::cerr << "p3ForumsV2::getMsgData() 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 RsForumAlbum */ + bool ans = mForumProxy->getForumMsg(id, msg); + return ans; +} + + + + /* Poll */ +uint32_t p3ForumsV2::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 p3ForumsV2::cancelRequest(const uint32_t &token) +{ + return clearRequest(token); +} + + ////////////////////////////////////////////////////////////////////////////// + /* Functions from Forums -> need to be implemented generically */ +bool p3ForumsV2::groupsChanged(std::list &groupIds) +{ + return false; +} + + // Get Message Status - is retrived via MessageSummary. +bool p3ForumsV2::setMessageStatus(const std::string &msgId, const uint32_t status, const uint32_t statusMask) +{ + return false; +} + + + // +bool p3ForumsV2::groupSubscribe(const std::string &groupId, bool subscribe) +{ + return false; +} + + +bool p3ForumsV2::groupRestoreKeys(const std::string &groupId) +{ + return false; +} + +bool p3ForumsV2::groupShareKeys(const std::string &groupId, std::list& peers) +{ + return false; +} + +#if 0 +/* details are updated in album - to choose Album ID, and storage path */ +bool p3ForumsV2::submitAlbumDetails(RsForumAlbum &album) +{ + return false; +} + +bool p3ForumsV2::submitForum(RsForumForum &photo) +{ + return false; +} + +#endif + + + + +/********************************************************************************************/ + + +std::string p3ForumsV2::genRandomId() +{ + std::string randomId; + for(int i = 0; i < 20; i++) + { + randomId += (char) ('a' + (RSRandom::random_u32() % 26)); + } + + return randomId; +} + +bool p3ForumsV2::createGroup(RsForumV2Group &group) +{ + if (group.mMeta.mGroupId.empty()) + { + /* new photo */ + + /* generate a temp id */ + group.mMeta.mGroupId = genRandomId(); + } + else + { + std::cerr << "p3ForumsV2::createGroup() Group with existing Id... dropping"; + std::cerr << std::endl; + return false; + } + + RsStackMutex stack(mForumMtx); /********** STACK LOCKED MTX ******/ + + mUpdated = true; + + mForumProxy->addForumGroup(group); + + return true; +} + + + + +bool p3ForumsV2::createMsg(RsForumV2Msg &msg) +{ + if (msg.mMeta.mGroupId.empty()) + { + /* new photo */ + std::cerr << "p3ForumsV2::createForumMsg() Missing MsgID"; + std::cerr << std::endl; + return false; + } + + /* check if its a mod or new msg */ + if (msg.mMeta.mOrigMsgId.empty()) + { + std::cerr << "p3ForumsV2::createForumMsg() New Msg"; + std::cerr << std::endl; + + /* new msg, generate a new OrigMsgId */ + msg.mMeta.mOrigMsgId = genRandomId(); + msg.mMeta.mMsgId = msg.mMeta.mOrigMsgId; + } + else + { + std::cerr << "p3ForumsV2::createForumMsg() Modified Msg"; + std::cerr << std::endl; + + /* mod msg, keep orig msg id, generate a new MsgId */ + msg.mMeta.mMsgId = genRandomId(); + } + + std::cerr << "p3ForumsV2::createForumMsg() GroupId: " << msg.mMeta.mGroupId; + std::cerr << std::endl; + std::cerr << "p3ForumsV2::createForumMsg() MsgId: " << msg.mMeta.mMsgId; + std::cerr << std::endl; + std::cerr << "p3ForumsV2::createForumMsg() OrigMsgId: " << msg.mMeta.mOrigMsgId; + std::cerr << std::endl; + + RsStackMutex stack(mForumMtx); /********** STACK LOCKED MTX ******/ + + mUpdated = true; + + mForumProxy->addForumMsg(msg); + + return true; +} + + + +/********************************************************************************************/ + + +bool ForumDataProxy::getForumGroup(const std::string &id, RsForumV2Group &group) +{ + void *groupData = NULL; + RsGroupMetaData meta; + if (getGroupData(id, groupData) && getGroupSummary(id, meta)) + { + RsForumV2Group *pG = (RsForumV2Group *) groupData; + group = *pG; + + // update definitive version of the metadata. + group.mMeta = meta; + + std::cerr << "ForumDataProxy::getForumGroup() Id: " << id; + std::cerr << " MetaData: " << meta << " DataPointer: " << groupData; + std::cerr << std::endl; + return true; + } + + std::cerr << "ForumDataProxy::getForumGroup() FAILED Id: " << id; + std::cerr << std::endl; + + return false; +} + +bool ForumDataProxy::getForumMsg(const std::string &id, RsForumV2Msg &page) +{ + void *msgData = NULL; + RsMsgMetaData meta; + if (getMsgData(id, msgData) && getMsgSummary(id, meta)) + { + RsForumV2Msg *pP = (RsForumV2Msg *) msgData; + // Shallow copy of thumbnail. + page = *pP; + + // update definitive version of the metadata. + page.mMeta = meta; + + std::cerr << "ForumDataProxy::getForumMsg() Id: " << id; + std::cerr << " MetaData: " << meta << " DataPointer: " << msgData; + std::cerr << std::endl; + return true; + } + + std::cerr << "ForumDataProxy::getForumMsg() FAILED Id: " << id; + std::cerr << std::endl; + + return false; +} + +bool ForumDataProxy::addForumGroup(const RsForumV2Group &group) +{ + // Make duplicate. + RsForumV2Group *pG = new RsForumV2Group(); + *pG = group; + + std::cerr << "ForumDataProxy::addForumGroup()"; + std::cerr << " MetaData: " << pG->mMeta << " DataPointer: " << pG; + std::cerr << std::endl; + + return createGroup(pG); +} + + +bool ForumDataProxy::addForumMsg(const RsForumV2Msg &msg) +{ + // Make duplicate. + RsForumV2Msg *pM = new RsForumV2Msg(); + *pM = msg; + + std::cerr << "ForumDataProxy::addForumMsg()"; + std::cerr << " MetaData: " << pM->mMeta << " DataPointer: " << pM; + std::cerr << std::endl; + + return createMsg(pM); +} + + + + /* These Functions must be overloaded to complete the service */ +bool ForumDataProxy::convertGroupToMetaData(void *groupData, RsGroupMetaData &meta) +{ + RsForumV2Group *group = (RsForumV2Group *) groupData; + meta = group->mMeta; + + return true; +} + +bool ForumDataProxy::convertMsgToMetaData(void *msgData, RsMsgMetaData &meta) +{ + RsForumV2Msg *page = (RsForumV2Msg *) msgData; + meta = page->mMeta; + + return true; +} + + +/********************************************************************************************/ + + +#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 + + std::list mGroups; + std::list::iterator git; + + std::list mMsgs; + std::list::iterator mit; + + for(int i = 0; i < MAX_FORUMS; i++) + { + /* generate a new forum */ + RsForumV2Group forum; + + /* key fields to fill in: + * GroupId. + * Name. + * Flags. + * Pop. + */ + + /* use probability to decide which are subscribed / own / popularity. + */ + + + mGroups.push_back(forum); + } + + + for(i = 0; i < MAX_THREADS; i++) + { + /* generate a base thread */ + + /* rotate the Forum Groups Around, then pick one. + */ + + int rnd; + + 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 ???? + */ + + mMsgs.push_back(msg); + + } + + for(i = 0; i < MAX_MSGS; i++) + { + /* generate a base thread */ + + /* rotate the Forum Groups Around, then pick one. + */ + + int rnd; + + 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 ???? + */ + + + + } + + + + /* Then - at the end, we push them all into the Proxy */ + for(git = mGroups.begin(); git != mGroups.end(); git++) + { + /* pushback */ + } + + for(mit = mMsgs.begin(); mit != mMsgs.end(); mit++) + { + /* pushback */ + } + +} + +#endif + diff --git a/libretroshare/src/services/p3forumsv2.h b/libretroshare/src/services/p3forumsv2.h new file mode 100644 index 000000000..bffacbd3d --- /dev/null +++ b/libretroshare/src/services/p3forumsv2.h @@ -0,0 +1,208 @@ +/* + * libretroshare/src/services: p3forumsv2.h + * + * Wiki 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_FORUMSV2_SERVICE_HEADER +#define P3_FORUMSV2_SERVICE_HEADER + +#include "services/p3gxsservice.h" + +#include "retroshare/rsforumsv2.h" + +#include +#include + +/* + * Wiki Service + * + * This is an example service for the new cache system. + * For the moment, it will only hold data passed to it from the GUI. + * and spew that back when asked.... + * + * We are doing it like this - so we can check the required interface functionality. + * + * Expect it won't take long before it'll be properly linked into the backend! + * + * This will be transformed into a Plugin Service, once the basics have been worked out. + * + */ + +class ForumDataProxy: public GxsDataProxy +{ + public: + + bool getForumGroup(const std::string &id, RsForumV2Group &group); + bool getForumMsg(const std::string &id, RsForumV2Msg &msg); + + bool addForumGroup(const RsForumV2Group &group); + bool addForumMsg(const RsForumV2Msg &msg); + + /* These Functions must be overloaded to complete the service */ +virtual bool convertGroupToMetaData(void *groupData, RsGroupMetaData &meta); +virtual bool convertMsgToMetaData(void *msgData, RsMsgMetaData &meta); + +}; + + + + + +class p3ForumsV2: public p3GxsDataService, public RsForumsV2 +{ + public: + + p3ForumsV2(uint16_t type); + +virtual int tick(); + + public: + + +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 getGroupData(const uint32_t &token, RsForumV2Group &group); +virtual bool getMsgData(const uint32_t &token, RsForumV2Msg &msg); + + /* 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); + + +virtual bool createGroup(RsForumV2Group &group); +virtual bool createMsg(RsForumV2Msg &msg); + + + private: + +std::string genRandomId(); + + ForumDataProxy *mForumProxy; + + RsMutex mForumMtx; + + /***** below here is locked *****/ + + bool mUpdated; + + + + +#if 0 + + /* Data Requests */ +virtual bool requestGroupList( uint32_t &token, const RsTokReqOptions &opts); +virtual bool requestMsgList( uint32_t &token, const RsTokReqOptions &opts, const std::list &groupIds); +virtual bool requestMsgRelatedList(uint32_t &token, const RsTokReqOptions &opts, const std::list &msgIds); + +virtual bool requestGroupData( uint32_t &token, const std::list &groupIds); +virtual bool requestMsgData( uint32_t &token, const std::list &msgIds); + +virtual bool getGroupList(const uint32_t &token, std::list &groupIds); +virtual bool getMsgList(const uint32_t &token, std::list &msgIds); + +virtual bool getGroupData(const uint32_t &token, RsForumV2Group &group); +virtual bool getMsgData(const uint32_t &token, RsForumV2Msg &msg); + + /* Poll */ +virtual uint32_t requestStatus(const uint32_t token); + +virtual bool createGroup(RsForumV2Group &group); +virtual bool createPage(RsForumV2Msg &msg); + + +/************* Old Extern Interface *******/ + +virtual bool updated(); +virtual bool getGroupList(std::list &group); + +virtual bool getGroup(const std::string &groupid, RsWikiGroup &group); +virtual bool getPage(const std::string &pageid, RsWikiPage &page); +virtual bool getPageVersions(const std::string &origPageId, std::list &pages); +virtual bool getOrigPageList(const std::string &groupid, std::list &pageIds); +virtual bool getLatestPage(const std::string &origPageId, std::string &page); + +virtual bool createGroup(RsWikiGroup &group); +virtual bool createPage(RsWikiPage &page); + + + private: + +virtual bool InternalgetGroupList(std::list &group); +virtual bool InternalgetGroup(const std::string &groupid, RsForumV2Group &group); +virtual bool InternalgetPage(const std::string &pageid, RsForumV2Msg &msg); +virtual bool InternalgetPageVersions(const std::string &origPageId, std::list &pages); +virtual bool InternalgetOrigPageList(const std::string &groupid, std::list &pageIds); +virtual bool InternalgetLatestPage(const std::string &origPageId, std::string &page); + +std::string genRandomId(); + + ForumDataProxy *mForumProxy; + + RsMutex mForumMtx; + + /***** below here is locked *****/ + + bool mUpdated; + + std::map > mGroupToOrigPages; + std::map > mOrigToPageVersions; + std::map mOrigPageToLatestPage; + std::map mGroups; + std::map mPages; +#endif + +}; + +#endif diff --git a/libretroshare/src/services/p3gxsservice.cc b/libretroshare/src/services/p3gxsservice.cc index 5e7d179e6..27ee1e7c1 100644 --- a/libretroshare/src/services/p3gxsservice.cc +++ b/libretroshare/src/services/p3gxsservice.cc @@ -41,7 +41,7 @@ bool p3GxsService::generateToken(uint32_t &token) return true; } -bool p3GxsService::storeRequest(const uint32_t &token, const uint32_t &type, const std::list &ids) +bool p3GxsService::storeRequest(const uint32_t &token, const uint32_t &ansType, const RsTokReqOptions &opts, const uint32_t &type, const std::list &ids) { RsStackMutex stack(mReqMtx); /****** LOCKED *****/ @@ -49,8 +49,10 @@ bool p3GxsService::storeRequest(const uint32_t &token, const uint32_t &type, con req.token = token; req.reqTime = time(NULL); req.reqType = type; + req.ansType = ansType; + req.Options = opts; req.status = GXS_REQUEST_STATUS_PENDING; - req.IdList = ids; + req.inList = ids; mRequests[token] = req; @@ -92,7 +94,7 @@ bool p3GxsService::updateRequestStatus(const uint32_t &token, const uint32_t &st return true; } -bool p3GxsService::updateRequestList(const uint32_t &token, std::list ids) +bool p3GxsService::updateRequestInList(const uint32_t &token, std::list ids) { RsStackMutex stack(mReqMtx); /****** LOCKED *****/ @@ -107,12 +109,35 @@ bool p3GxsService::updateRequestList(const uint32_t &token, std::list::iterator iit; for(iit = ids.begin(); iit != ids.end(); iit++) { - it->second.IdList.push_back(*iit); + it->second.inList.push_back(*iit); } return true; } + +bool p3GxsService::updateRequestOutList(const uint32_t &token, std::list ids) +{ + RsStackMutex stack(mReqMtx); /****** LOCKED *****/ + + std::map::iterator it; + + it = mRequests.find(token); + if (it == mRequests.end()) + { + return false; + } + + std::list::iterator iit; + for(iit = ids.begin(); iit != ids.end(); iit++) + { + it->second.outList.push_back(*iit); + } + + return true; +} + +#if 0 bool p3GxsService::updateRequestData(const uint32_t &token, std::map data) { RsStackMutex stack(mReqMtx); /****** LOCKED *****/ @@ -133,8 +158,9 @@ bool p3GxsService::updateRequestData(const uint32_t &token, std::mapsecond.status; reqtype = it->second.reqType; + anstype = it->second.ansType; ts = it->second.reqTime; return true; @@ -169,7 +196,7 @@ bool p3GxsService::tokenList(std::list &tokens) return true; } -bool p3GxsService::popRequestList(const uint32_t &token, std::string &id) +bool p3GxsService::popRequestInList(const uint32_t &token, std::string &id) { RsStackMutex stack(mReqMtx); /****** LOCKED *****/ @@ -181,13 +208,61 @@ bool p3GxsService::popRequestList(const uint32_t &token, std::string &id) return false; } - if (it->second.IdList.size() == 0) + if (it->second.inList.size() == 0) { return false; } - id = it->second.IdList.front(); - it->second.IdList.pop_front(); + id = it->second.inList.front(); + it->second.inList.pop_front(); + + return true; +} + + +bool p3GxsService::popRequestOutList(const uint32_t &token, std::string &id) +{ + RsStackMutex stack(mReqMtx); /****** LOCKED *****/ + + std::map::iterator it; + + it = mRequests.find(token); + if (it == mRequests.end()) + { + return false; + } + + if (it->second.outList.size() == 0) + { + return false; + } + + id = it->second.outList.front(); + it->second.outList.pop_front(); + + return true; +} + + +bool p3GxsService::loadRequestOutList(const uint32_t &token, std::list &ids) +{ + RsStackMutex stack(mReqMtx); /****** LOCKED *****/ + + std::map::iterator it; + + it = mRequests.find(token); + if (it == mRequests.end()) + { + return false; + } + + if (it->second.outList.size() == 0) + { + return false; + } + + ids = it->second.outList; + it->second.outList.clear(); return true; } @@ -207,9 +282,10 @@ bool p3GxsService::fakeprocessrequests() { uint32_t status; uint32_t reqtype; + uint32_t anstype; uint32_t token = *it; time_t ts; - checkRequestStatus(token, status, reqtype, ts); + checkRequestStatus(token, status, reqtype, anstype, ts); std::cerr << "p3GxsService::fakeprocessrequests() Token: " << token << " Status: " << status << " ReqType: " << reqtype << "Age: " << now - ts << std::endl; @@ -240,3 +316,570 @@ bool p3GxsService::fakeprocessrequests() +/*********************************************************************************************************/ +/*********************************************************************************************************/ +/*********************************************************************************************************/ +/*********************************************************************************************************/ +/*********************************************************************************************************/ + + +/****** GXS Data Dummy .... Handles generic data storage and access. designed for testing GUIs + * without being dependent on the backend. + * + * + * + * Important to specify the exact behaviour with flags! + * + * + * + ****/ + +GxsDataProxy::GxsDataProxy() + :mDataMtx("GxsDataProxyMtx") +{ + return; +} + + + +bool GxsDataProxy::getGroupList( uint32_t &token, const RsTokReqOptions &opts, const std::list &groupIds, std::list &outGroupIds) +{ + /* CASEs that this handles ... + * 1) if groupIds is Empty... return all groupIds. + * 2) else copy list. + * + */ + std::cerr << "GxsDataProxy::getGroupList()"; + std::cerr << std::endl; + + if (groupIds.size() == 0) + { + /* grab all the ids */ + RsStackMutex stack(mDataMtx); /***** LOCKED *****/ + + std::map::iterator mit; + for(mit = mGroupMetaData.begin(); mit != mGroupMetaData.end(); mit++) + { + outGroupIds.push_back(mit->first); + } + } + else + { + outGroupIds = groupIds; + } + + return true; +} + + +bool GxsDataProxy::getMsgList( uint32_t &token, const RsTokReqOptions &opts, const std::list &groupIds, std::list &outMsgIds) +{ + /* CASEs this handles. + * Input is groupList + Flags. + * 1) No Flags => All Messages in those Groups. + * + */ + + bool onlyOrigMsgs = false; + + if (opts.mOptions & RS_TOKREQOPT_MSG_ORIGMSG) + { + onlyOrigMsgs = true; + } + + std::cerr << "GxsDataProxy::getMsgList()"; + std::cerr << std::endl; + + std::list::const_iterator it; + std::map::iterator mit; + + for(it = groupIds.begin(); it != groupIds.end(); it++) + { + for(mit = mMsgMetaData.begin(); mit != mMsgMetaData.end(); mit++) + { + if (mit->second.mGroupId == *it) + { + bool add = false; + + if (onlyOrigMsgs) + { + if (mit->second.mMsgId == mit->second.mOrigMsgId) + { + add = true; + } + } + else + { + add = true; + } + + if (add) + { + outMsgIds.push_back(mit->first); + } + } + } + } + return true; +} + + +bool GxsDataProxy::getMsgRelatedList(uint32_t &token, const RsTokReqOptions &opts, const std::list &msgIds, std::list &outMsgIds) +{ + /* CASEs this handles. + * Input is msgList + Flags. + * 1) No Flags => just copy msgIds (probably requesting data). + * + */ + + std::cerr << "GxsDataProxy::getMsgRelatedList()"; + std::cerr << std::endl; + + bool onlyLatestMsgs = false; + bool onlyAllVersions = false; + if (opts.mOptions & RS_TOKREQOPT_MSG_LATEST) + { + onlyLatestMsgs = true; + } + else if (opts.mOptions & RS_TOKREQOPT_MSG_VERSIONS) + { + onlyAllVersions = true; + } + + /* FALL BACK OPTION */ + if ((!onlyLatestMsgs) && (!onlyAllVersions)) + { + /* just copy */ + outMsgIds = msgIds; + + return true; + } + + std::list::const_iterator it; + std::map::iterator mit; + + for(it = msgIds.begin(); it != msgIds.end(); it++) + { + /* getOriginal Message */ + mit = mMsgMetaData.find(*it); + if (mit == mMsgMetaData.end()) + { + continue; + } + + std::string origMsgId = mit->second.mOrigMsgId; + + 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 (mit->second.mOrigMsgId == origMsgId) + { + if (mit->second.mPublishTs > latestTs) + { + latestTs = mit->second.mPublishTs; + latestMsgId = mit->first; + } + } + } + outMsgIds.push_back(latestMsgId); + } + else if (onlyAllVersions) + { + for(mit = mMsgMetaData.begin(); mit != mMsgMetaData.end(); mit++) + { + if (mit->second.mOrigMsgId == origMsgId) + { + outMsgIds.push_back(mit->first); + } + } + } + } + + return true; +} + + +bool GxsDataProxy::createGroup(void *groupData) +{ + RsGroupMetaData meta; + if (convertGroupToMetaData(groupData, meta)) + { + if (!isUniqueGroup(meta.mGroupId)) + { + std::cerr << "GxsDataProxy::createGroup() ERROR GroupId Clashes, discarding"; + std::cerr << std::endl; + return false; + } + + RsStackMutex stack(mDataMtx); /***** LOCKED *****/ + + /* push into maps */ + mGroupData[meta.mGroupId] = groupData; + mGroupMetaData[meta.mGroupId] = meta; + + return true; + } + + std::cerr << "GxsDataProxy::createGroup() ERROR Failed to convert Data"; + std::cerr << std::endl; + return false; +} + + +bool GxsDataProxy::createMsg(void *msgData) +{ + RsMsgMetaData meta; + if (convertMsgToMetaData(msgData, meta)) + { + if (!isUniqueMsg(meta.mMsgId)) + { + std::cerr << "GxsDataProxy::createMsg() ERROR MsgId Clashes, discarding"; + std::cerr << std::endl; + return false; + } + + RsStackMutex stack(mDataMtx); /***** LOCKED *****/ + + /* push into maps */ + mMsgData[meta.mMsgId] = msgData; + mMsgMetaData[meta.mMsgId] = meta; + + return true; + } + + std::cerr << "GxsDataProxy::createMsg() ERROR Failed to convert Data"; + std::cerr << std::endl; + return false; +} + + + + /* These Functions must be overloaded to complete the service */ +bool GxsDataProxy::convertGroupToMetaData(void *groupData, RsGroupMetaData &meta) +{ + std::cerr << "GxsDataProxy::convert fn ... please implement!"; + std::cerr << std::endl; + return false; +} + +bool GxsDataProxy::convertMsgToMetaData(void *groupData, RsMsgMetaData &meta) +{ + std::cerr << "GxsDataProxy::convert fn ... please implement!"; + std::cerr << std::endl; + return false; +} + + /* extract Data */ +bool GxsDataProxy::getGroupSummary(const std::string &groupId, RsGroupMetaData &groupSummary) +{ + RsStackMutex stack(mDataMtx); /***** LOCKED *****/ + + std::map::iterator mit; + mit = mGroupMetaData.find(groupId); + + if (mit == mGroupMetaData.end()) + { + // error. + std::cerr << "GxsDataProxy::getGroupMetaData() Error Finding GroupId: " << groupId; + std::cerr << std::endl; + return false; + } + else + { + groupSummary = mit->second; + } + return true; +} + + +bool GxsDataProxy::getMsgSummary(const std::string &msgId, RsMsgMetaData &msgSummary) +{ + RsStackMutex stack(mDataMtx); /***** LOCKED *****/ + + std::map::iterator mit; + mit = mMsgMetaData.find(msgId); + + if (mit == mMsgMetaData.end()) + { + // error. + std::cerr << "GxsDataProxy::getMsgSummary() Error Finding MsgId: " << msgId; + std::cerr << std::endl; + } + else + { + msgSummary = (mit->second); + } + return true; +} + + + /* extract Data */ +bool GxsDataProxy::getGroupSummary(const std::list &groupIds, std::list &groupSummary) +{ + std::list::const_iterator it; + for(it = groupIds.begin(); it != groupIds.end(); it++) + { + RsStackMutex stack(mDataMtx); /***** LOCKED *****/ + + std::map::iterator mit; + mit = mGroupMetaData.find(*it); + + if (mit == mGroupMetaData.end()) + { + // error. + std::cerr << "GxsDataProxy::getGroupMetaData() Error Finding GroupId: " << *it; + std::cerr << std::endl; + } + else + { + groupSummary.push_back(mit->second); + } + } + return true; +} + + +bool GxsDataProxy::getMsgSummary(const std::list &msgIds, std::list &msgSummary) +{ + std::list::const_iterator it; + for(it = msgIds.begin(); it != msgIds.end(); it++) + { + RsStackMutex stack(mDataMtx); /***** LOCKED *****/ + + std::map::iterator mit; + mit = mMsgMetaData.find(*it); + + if (mit == mMsgMetaData.end()) + { + // error. + std::cerr << "GxsDataProxy::getMsgSummary() Error Finding MsgId: " << *it; + std::cerr << std::endl; + } + else + { + msgSummary.push_back(mit->second); + } + } + return true; +} + + +bool GxsDataProxy::getGroupData(const std::string &groupId, void * &groupData) +{ + RsStackMutex stack(mDataMtx); /***** LOCKED *****/ + + std::map::iterator mit; + mit = mGroupData.find(groupId); + + if (mit == mGroupData.end()) + { + // error. + std::cerr << "GxsDataProxy::getGroupData() Error Finding GroupId: " << groupId; + std::cerr << std::endl; + return false; + } + else + { + groupData = mit->second; + } + return true; +} + +bool GxsDataProxy::getMsgData(const std::string &msgId, void * &msgData) +{ + RsStackMutex stack(mDataMtx); /***** LOCKED *****/ + + std::map::iterator mit; + mit = mMsgData.find(msgId); + + if (mit == mMsgData.end()) + { + // error. + std::cerr << "GxsDataProxy::getMsgData() Error Finding MsgId: " << msgId; + std::cerr << std::endl; + return false; + } + else + { + msgData = mit->second; + } + return true; +} + +#if 0 +bool GxsDataProxy::getGroupData(const std::list &groupIds, std::list &groupData) +{ + std::list::const_iterator it; + for(it = groupIds.begin(); it != groupIds.end(); it++) + { + RsStackMutex stack(mDataMtx); /***** LOCKED *****/ + + std::map::iterator mit; + mit = mGroupData.find(*it); + + if (mit == mGroupData.end()) + { + // error. + std::cerr << "GxsDataProxy::getGroupData() Error Finding GroupId: " << *it; + std::cerr << std::endl; + } + else + { + groupData.push_back(mit->second); + } + } + return true; +} + +bool GxsDataProxy::getMsgData(const std::list &msgIds, std::list &msgData) +{ + std::list::const_iterator it; + for(it = msgIds.begin(); it != msgIds.end(); it++) + { + RsStackMutex stack(mDataMtx); /***** LOCKED *****/ + + std::map::iterator mit; + mit = mMsgData.find(*it); + + if (mit == mMsgData.end()) + { + // error. + std::cerr << "GxsDataProxy::getMsgData() Error Finding MsgId: " << *it; + std::cerr << std::endl; + } + else + { + msgData.push_back(mit->second); + } + } + return true; +} +#endif + +bool GxsDataProxy::isUniqueMsg(const std::string &msgId) +{ + RsStackMutex stack(mDataMtx); /***** LOCKED *****/ + + std::map::iterator mit; + mit = mMsgData.find(msgId); + + return (mit == mMsgData.end()); +} + + +bool GxsDataProxy::isUniqueGroup(const std::string &groupId) +{ + RsStackMutex stack(mDataMtx); /***** LOCKED *****/ + + std::map::iterator mit; + mit = mGroupData.find(groupId); + + return (mit == mGroupData.end()); +} + + + +/*********************************************************************************************************/ +/*********************************************************************************************************/ +/*********************************************************************************************************/ +/*********************************************************************************************************/ +/*********************************************************************************************************/ + + +p3GxsDataService::p3GxsDataService(uint16_t type, GxsDataProxy *proxy) + :p3GxsService(type), mProxy(proxy) +{ + return; +} + + + + + +bool p3GxsDataService::fakeprocessrequests() +{ + std::list toClear; + std::list::iterator cit; + time_t now = time(NULL); + + { RsStackMutex stack(mReqMtx); /******* LOCKED *******/ + + std::map::iterator it; + + for(it = mRequests.begin(); it != mRequests.end(); it++) + { + //std::cerr << "p3GxsDataService::fakeprocessrequests() Token: " << it->second.token << " Status: " << it->second.status << " ReqType: " << it->second.reqType << " Age: " << now - it->second.reqTime << std::endl; + + if (it->second.status == GXS_REQUEST_STATUS_PENDING) + { + std::cerr << "p3GxsDataService::fakeprocessrequests() Processing Token: " << it->second.token << " Status: " << it->second.status << " ReqType: " << it->second.reqType << " Age: " << now - it->second.reqTime << std::endl; + it->second.status = GXS_REQUEST_STATUS_PARTIAL; + /* PROCESS REQUEST! */ + switch(it->second.reqType) + { + case GXS_REQUEST_TYPE_GROUPS: + mProxy->getGroupList(it->second.token, it->second.Options, it->second.inList, it->second.outList); + break; + case GXS_REQUEST_TYPE_MSGS: + mProxy->getMsgList(it->second.token, it->second.Options, it->second.inList, it->second.outList); + break; + case GXS_REQUEST_TYPE_MSGRELATED: + mProxy->getMsgRelatedList(it->second.token, it->second.Options, it->second.inList, it->second.outList); + break; + default: + it->second.status = GXS_REQUEST_STATUS_FAILED; + break; + } + } + else if (it->second.status == GXS_REQUEST_STATUS_PARTIAL) + { + it->second.status = GXS_REQUEST_STATUS_COMPLETE; + } + else if (it->second.status == GXS_REQUEST_STATUS_DONE) + { + std::cerr << "p3GxsDataService::fakeprocessrequests() Clearing Done Request Token: " << it->second.token; + std::cerr << std::endl; + toClear.push_back(it->second.token); + } + else if (now - it->second.reqTime > MAX_REQUEST_AGE) + { + std::cerr << "p3GxsDataService::fakeprocessrequests() Clearing Old Request Token: " << it->second.token; + std::cerr << std::endl; + toClear.push_back(it->second.token); + } + } + + } // END OF MUTEX. + + for(cit = toClear.begin(); cit != toClear.end(); cit++) + { + clearRequest(*cit); + } + + return true; +} + + +std::ostream &operator<<(std::ostream &out, const RsGroupMetaData &meta) +{ + out << "[ GroupId: " << meta.mGroupId << " Name: " << meta.mGroupName << " ]"; + return out; +} + +std::ostream &operator<<(std::ostream &out, const RsMsgMetaData &meta) +{ + out << "[ GroupId: " << meta.mGroupId << " MsgId: " << meta.mMsgId << " Name: " << meta.mMsgName << " ]"; + out << " OrigMsgId: " << meta.mOrigMsgId; + out << " ThreadId: " << meta.mThreadId; + out << " ParentId: " << meta.mParentId; + out << " AuthorId: " << meta.mAuthorId; + out << " Name: " << meta.mMsgName << " ]"; + return out; +} + + diff --git a/libretroshare/src/services/p3gxsservice.h b/libretroshare/src/services/p3gxsservice.h index cce667c88..b2b4f45f4 100644 --- a/libretroshare/src/services/p3gxsservice.h +++ b/libretroshare/src/services/p3gxsservice.h @@ -27,6 +27,7 @@ #define P3_GXS_SERVICE_HEADER #include "services/p3service.h" +#include "retroshare/rsidentity.h" /* * This class provides useful generic support for GXS style services. @@ -41,27 +42,28 @@ #define GXS_REQUEST_STATUS_COMPLETE 4 #define GXS_REQUEST_STATUS_DONE 5 // ONCE ALL DATA RETRIEVED. -#define GXS_REQUEST_TYPE_LIST 0x00010000 -#define GXS_REQUEST_TYPE_DATA 0x00020000 - -#define GXS_REQUEST_TYPE_GROUPS 0x01000000 -#define GXS_REQUEST_TYPE_MSGS 0x02000000 +#define GXS_REQUEST_TYPE_GROUPS 0x00010000 +#define GXS_REQUEST_TYPE_MSGS 0x00020000 +#define GXS_REQUEST_TYPE_MSGRELATED 0x00040000 class gxsRequest { public: uint32_t token; uint32_t reqTime; - uint32_t reqType; /* specific to service */ + + uint32_t ansType; + uint32_t reqType; + RsTokReqOptions Options; + uint32_t status; - std::list IdList; - std::map readyData; + std::list inList; + std::list outList; + //std::map readyData; }; - - class p3GxsService: public p3Service { protected: @@ -73,20 +75,24 @@ class p3GxsService: public p3Service //virtual ~p3Service() { p3Service::~p3Service(); return; } bool generateToken(uint32_t &token); -bool storeRequest(const uint32_t &token, const uint32_t &type, const std::list &ids); +bool storeRequest(const uint32_t &token, const uint32_t &ansType, const RsTokReqOptions &opts, const uint32_t &type, const std::list &ids); bool clearRequest(const uint32_t &token); bool updateRequestStatus(const uint32_t &token, const uint32_t &status); -bool updateRequestList(const uint32_t &token, std::list ids); -bool updateRequestData(const uint32_t &token, std::map data); -bool checkRequestStatus(const uint32_t &token, uint32_t &status, uint32_t &reqtype, time_t &ts); +bool updateRequestInList(const uint32_t &token, std::list ids); +bool updateRequestOutList(const uint32_t &token, std::list ids); +//bool updateRequestData(const uint32_t &token, std::map data); +bool checkRequestStatus(const uint32_t &token, uint32_t &status, uint32_t &reqtype, uint32_t &anstype, time_t &ts); // special ones for testing (not in final design) bool tokenList(std::list &tokens); -bool popRequestList(const uint32_t &token, std::string &id); -bool fakeprocessrequests(); +bool popRequestInList(const uint32_t &token, std::string &id); +bool popRequestOutList(const uint32_t &token, std::string &id); +bool loadRequestOutList(const uint32_t &token, std::list &ids); - private: +virtual bool fakeprocessrequests(); + + protected: RsMutex mReqMtx; @@ -97,5 +103,65 @@ bool fakeprocessrequests(); }; +class GxsDataProxy +{ + public: + + GxsDataProxy(); + +virtual bool getGroupList( uint32_t &token, const RsTokReqOptions &opts, const std::list &groupIds, std::list &outGroupIds); +virtual bool getMsgList( uint32_t &token, const RsTokReqOptions &opts, const std::list &groupIds, std::list &outMsgIds); +virtual bool getMsgRelatedList(uint32_t &token, const RsTokReqOptions &opts, const std::list &msgIds, std::list &outMsgIds); + + +virtual bool createGroup(void *groupData); +virtual bool createMsg(void *msgData); + + /* These Functions must be overloaded to complete the service */ +virtual bool convertGroupToMetaData(void *groupData, RsGroupMetaData &meta); +virtual bool convertMsgToMetaData(void *groupData, RsMsgMetaData &meta); + + /* extract Data */ + bool getGroupSummary(const std::list &groupIds, std::list &groupSummary); + bool getMsgSummary(const std::list &msgIds, std::list &msgSummary); + + bool getGroupSummary(const std::string &groupId, RsGroupMetaData &groupSummary); + bool getMsgSummary(const std::string &msgId, RsMsgMetaData &msgSummary); + + //bool getGroupData(const std::list &groupIds, std::list &groupData); + //bool getMsgData(const std::list &msgIds, std::list &msgData); + bool getGroupData(const std::string &groupId, void * &groupData); + bool getMsgData(const std::string &msgId, void * &msgData); + + bool isUniqueGroup(const std::string &groupId); + bool isUniqueMsg(const std::string &msgId); + + + RsMutex mDataMtx; + + std::map mGroupData; + std::map mMsgData; + + std::map mGroupMetaData; + std::map mMsgMetaData; + +}; + + +class p3GxsDataService: public p3GxsService +{ + public: + + p3GxsDataService(uint16_t type, GxsDataProxy *proxy); +virtual bool fakeprocessrequests(); + + + protected: + + GxsDataProxy *mProxy; +}; + + + #endif // P3_GXS_SERVICE_HEADER diff --git a/libretroshare/src/services/p3idservice.cc b/libretroshare/src/services/p3idservice.cc index 513ff5250..d54bfae4d 100644 --- a/libretroshare/src/services/p3idservice.cc +++ b/libretroshare/src/services/p3idservice.cc @@ -7,7 +7,7 @@ * * 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. + * 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 @@ -41,10 +41,16 @@ RsIdentity *rsIdentity = NULL; +/********************************************************************************/ +/******************* Startup / Tick ******************************************/ +/********************************************************************************/ + p3IdService::p3IdService(uint16_t type) - :p3GxsService(type), mIdMtx("p3IdService"), mUpdated(true) + :p3GxsDataService(type, new IdDataProxy()), mIdMtx("p3IdService"), mUpdated(true) { RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + + mIdProxy = (IdDataProxy *) mProxy; return; } @@ -53,9 +59,9 @@ int p3IdService::tick() { std::cerr << "p3IdService::tick()"; std::cerr << std::endl; - - fakeprocessrequests(); + fakeprocessrequests(); + return 0; } @@ -72,328 +78,512 @@ bool p3IdService::updated() } - /* Data Requests */ -bool p3IdService::requestIdentityList(uint32_t &token) + + /* Data Requests */ +bool p3IdService::requestGroupInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &groupIds) { generateToken(token); - std::list ids; - storeRequest(token, GXS_REQUEST_TYPE_LIST | GXS_REQUEST_TYPE_GROUPS | ID_REQUEST_LIST, ids); + std::cerr << "p3IdService::requestGroupInfo() gets Token: " << token << std::endl; + storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_GROUPS, groupIds); return true; } -bool p3IdService::requestIdentities(uint32_t &token, const std::list &ids) +bool p3IdService::requestMsgInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &groupIds) { generateToken(token); - storeRequest(token, GXS_REQUEST_TYPE_DATA | GXS_REQUEST_TYPE_GROUPS | ID_REQUEST_IDENTITY, ids); + std::cerr << "p3IdService::requestMsgInfo() gets Token: " << token << std::endl; + storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_MSGS, groupIds); return true; } -bool p3IdService::requestIdReputations(uint32_t &token, const std::list &ids) +bool p3IdService::requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &msgIds) { generateToken(token); - - // request msg Ids from Groups. - storeRequest(token, GXS_REQUEST_TYPE_LIST | GXS_REQUEST_TYPE_MSGS | ID_REQUEST_REPUTATION, ids); - - // Once they arrive, we need to get the Messages to workout reputation. + std::cerr << "p3IdService::requestMsgRelatedInfo() gets Token: " << token << std::endl; + storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_MSGRELATED, msgIds); return true; } -bool p3IdService::requestIdPeerOpinion(uint32_t &token, const std::string &aboutId, const std::string &peerId) + /* Generic Lists */ +bool p3IdService::getGroupList( const uint32_t &token, std::list &groupIds) { - generateToken(token); + uint32_t status; + uint32_t reqtype; + uint32_t anstype; + time_t ts; + checkRequestStatus(token, status, reqtype, anstype, ts); - // request msg Ids from Groups. - std::list ids; - ids.push_back(aboutId); - ids.push_back(peerId); - storeRequest(token, GXS_REQUEST_TYPE_LIST | GXS_REQUEST_TYPE_MSGS | ID_REQUEST_OPINION, ids); + if (anstype != RS_TOKREQ_ANSTYPE_LIST) + { + std::cerr << "p3IdService::getGroupList() ERROR AnsType Wrong" << std::endl; + return false; + } + + if (reqtype != GXS_REQUEST_TYPE_GROUPS) + { + std::cerr << "p3IdService::getGroupList() ERROR ReqType Wrong" << std::endl; + return false; + } + + if (status != GXS_REQUEST_STATUS_COMPLETE) + { + std::cerr << "p3IdService::getGroupList() ERROR Status Incomplete" << std::endl; + return false; + } - // Once they arrive, we search through the message to find the exact need to get the Messages to workout reputation. + bool ans = loadRequestOutList(token, groupIds); + updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); - return true; + return ans; } + + + +bool p3IdService::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 << "p3IdService::getMsgList() ERROR AnsType Wrong" << std::endl; + return false; + } + + if ((reqtype != GXS_REQUEST_TYPE_MSGS) && (reqtype != GXS_REQUEST_TYPE_MSGRELATED)) + { + std::cerr << "p3IdService::getMsgList() ERROR ReqType Wrong" << std::endl; + return false; + } + + if (status != GXS_REQUEST_STATUS_COMPLETE) + { + std::cerr << "p3IdService::getMsgList() ERROR Status Incomplete" << std::endl; + return false; + } + + bool ans = loadRequestOutList(token, msgIds); + updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); + + return ans; +} + + + /* Generic Summary */ +bool p3IdService::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 << "p3IdService::getGroupSummary() ERROR AnsType Wrong" << std::endl; + return false; + } + + if (reqtype != GXS_REQUEST_TYPE_GROUPS) + { + std::cerr << "p3IdService::getGroupSummary() ERROR ReqType Wrong" << std::endl; + return false; + } + + if (status != GXS_REQUEST_STATUS_COMPLETE) + { + std::cerr << "p3IdService::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 p3IdService::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 << "p3IdService::getMsgSummary() ERROR AnsType Wrong" << std::endl; + return false; + } + + if ((reqtype != GXS_REQUEST_TYPE_MSGS) && (reqtype != GXS_REQUEST_TYPE_MSGRELATED)) + { + std::cerr << "p3IdService::getMsgSummary() ERROR ReqType Wrong" << std::endl; + return false; + } + + if (status != GXS_REQUEST_STATUS_COMPLETE) + { + std::cerr << "p3IdService::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 p3IdService::getGroupData(const uint32_t &token, RsIdGroup &group) +{ + 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 << "p3IdService::getGroupData() ERROR AnsType Wrong" << std::endl; + return false; + } + + if (reqtype != GXS_REQUEST_TYPE_GROUPS) + { + std::cerr << "p3IdService::getGroupData() ERROR ReqType Wrong" << std::endl; + return false; + } + + if (status != GXS_REQUEST_STATUS_COMPLETE) + { + std::cerr << "p3IdService::getGroupData() 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 RsIdGroup */ + bool ans = mIdProxy->getGroup(id, group); + return ans; +} + + +bool p3IdService::getMsgData(const uint32_t &token, RsIdMsg &msg) +{ + 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 << "p3IdService::getMsgData() ERROR AnsType Wrong" << std::endl; + return false; + } + + if ((reqtype != GXS_REQUEST_TYPE_MSGS) && (reqtype != GXS_REQUEST_TYPE_MSGRELATED)) + { + std::cerr << "p3IdService::getMsgData() ERROR ReqType Wrong" << std::endl; + return false; + } + + if (status != GXS_REQUEST_STATUS_COMPLETE) + { + std::cerr << "p3IdService::getMsgData() 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 RsIdMsg */ + bool ans = mIdProxy->getMsg(id, msg); + return ans; +} + + + /* Poll */ uint32_t p3IdService::requestStatus(const uint32_t token) { uint32_t status; uint32_t reqtype; + uint32_t anstype; time_t ts; - checkRequestStatus(token, status, reqtype, ts); - - /* handle cases which need multiple steps */ - if (reqtype & ID_REQUEST_OPINION) - { - - - - } - else if (reqtype & ID_REQUEST_REPUTATION) - { - - - - } + checkRequestStatus(token, status, reqtype, anstype, ts); return status; } - /* Retrieve Data */ - /* For the moment, these don't get real data, just check if the request has been deemed completed - */ -bool p3IdService::getIdentityList(const uint32_t token, std::list &ids) + /* Cancel Request */ +bool p3IdService::cancelRequest(const uint32_t &token) { - uint32_t status; - uint32_t reqtype; - time_t ts; - checkRequestStatus(token, status, reqtype, ts); - - if (reqtype != (GXS_REQUEST_TYPE_LIST | GXS_REQUEST_TYPE_GROUPS | ID_REQUEST_LIST)) - { - std::cerr << "p3IdService ERROR" << std::endl; - return false; - } - - if (status != GXS_REQUEST_STATUS_COMPLETE) - { - std::cerr << "p3IdService ERROR" << std::endl; - return false; - } - - bool ans = InternalgetIdentityList(ids); - - updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); - - return ans; + return clearRequest(token); } -bool p3IdService::getIdentity(const uint32_t token, RsIdData &data) + ////////////////////////////////////////////////////////////////////////////// + /* Functions from Forums -> need to be implemented generically */ +bool p3IdService::groupsChanged(std::list &groupIds) { - uint32_t status; - uint32_t reqtype; - time_t ts; - checkRequestStatus(token, status, reqtype, ts); - - if (reqtype != (GXS_REQUEST_TYPE_DATA | GXS_REQUEST_TYPE_GROUPS | ID_REQUEST_IDENTITY)) - { - std::cerr << "p3IdService ERROR" << std::endl; - return false; - } - - if (status != GXS_REQUEST_STATUS_COMPLETE) - { - std::cerr << "p3IdService ERROR" << std::endl; - return false; - } - - std::string id; - if (!popRequestList(token, id)) - { - /* finished */ - updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); - return false; - } - - bool ans = InternalgetIdentity(id, data); - return ans; -} - -bool p3IdService::getIdReputation(const uint32_t token, RsIdReputation &reputation) -{ - uint32_t status; - uint32_t reqtype; - time_t ts; - checkRequestStatus(token, status, reqtype, ts); - - if (reqtype != (GXS_REQUEST_TYPE_LIST | GXS_REQUEST_TYPE_MSGS | ID_REQUEST_REPUTATION)) - { - std::cerr << "p3IdService ERROR" << std::endl; - return false; - } - - if (status != GXS_REQUEST_STATUS_COMPLETE) - { - std::cerr << "p3IdService ERROR" << std::endl; - return false; - } - - std::string id; - if (!popRequestList(token, id)) - { - /* finished */ - std::cerr << "p3IdService::getIdReputation() List Fully Popped" << std::endl; - updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); - return false; - } - - bool ans = InternalgetIdReputation(id, reputation); - return ans; -} - - -bool p3IdService::getIdPeerOpinion(const uint32_t token, RsIdOpinion &opinion) -{ - uint32_t status; - uint32_t reqtype; - time_t ts; - checkRequestStatus(token, status, reqtype, ts); - - if (reqtype != (GXS_REQUEST_TYPE_LIST | GXS_REQUEST_TYPE_MSGS | ID_REQUEST_OPINION)) - { - std::cerr << "p3IdService ERROR" << std::endl; - return false; - } - - if (status != GXS_REQUEST_STATUS_COMPLETE) - { - std::cerr << "p3IdService ERROR" << std::endl; - return false; - } - - std::string aboutid; - std::string peerid; - popRequestList(token, aboutid); - popRequestList(token, peerid); - - updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); - - bool ans = InternalgetIdPeerOpinion(aboutid, peerid, opinion); - return ans; - -} - -#define MAX_REQUEST_AGE 60 - -bool p3IdService::fakeprocessrequests() -{ - std::list::iterator it; - std::list tokens; - - tokenList(tokens); - - time_t now = time(NULL); - for(it = tokens.begin(); it != tokens.end(); it++) - { - uint32_t status; - uint32_t reqtype; - uint32_t token = *it; - time_t ts; - checkRequestStatus(token, status, reqtype, ts); - - std::cerr << "p3IdService::fakeprocessrequests() Token: " << token << " Status: " << status << " ReqType: " << reqtype << "Age: " << now - ts << std::endl; - - if (status == GXS_REQUEST_STATUS_PENDING) - { - updateRequestStatus(token, GXS_REQUEST_STATUS_PARTIAL); - } - else if (status == GXS_REQUEST_STATUS_PARTIAL) - { - updateRequestStatus(token, GXS_REQUEST_STATUS_COMPLETE); - } - else if (status == GXS_REQUEST_STATUS_DONE) - { - std::cerr << "p3IdService::fakeprocessrequests() Clearing Done Request Token: " << token; - std::cerr << std::endl; - clearRequest(token); - } - else if (now - ts > MAX_REQUEST_AGE) - { - std::cerr << "p3IdService::fakeprocessrequests() Clearing Old Request Token: " << token; - std::cerr << std::endl; - clearRequest(token); - } - } - - return true; -} - - - - -#if 0 - -bool p3IdService::getGpgIdDetails(const std::string &id, std::string &gpgName, std::string &gpgEmail) -{ - gpgName = "aGpgName"; - gpgEmail = "a@GpgMailAddress"; - - return true; -} - -#endif - -bool p3IdService::InternalgetIdentityList(std::list &ids) -{ - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - - std::map::iterator it; - for(it = mIds.begin(); it != mIds.end(); it++) - { - ids.push_back(it->first); - } - return false; } -bool p3IdService::InternalgetIdentity(const std::string &id, RsIdData &data) + // Get Message Status - is retrived via MessageSummary. +bool p3IdService::setMessageStatus(const std::string &msgId, const uint32_t status, const uint32_t statusMask) { - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - - std::map::iterator it; - it = mIds.find(id); - if (it == mIds.end()) - { - return false; - } - - data = it->second; - return true; + return false; } -bool p3IdService::InternalgetIdReputation(const std::string &id, RsIdReputation &reputation) + + // +bool p3IdService::groupSubscribe(const std::string &groupId, bool subscribe) { - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + return false; +} + + +bool p3IdService::groupRestoreKeys(const std::string &groupId) +{ + return false; +} + +bool p3IdService::groupShareKeys(const std::string &groupId, std::list& peers) +{ + return false; +} + + +/********************************************************************************************/ + - std::map::iterator it; - it = mReputations.find(id); - if (it == mReputations.end()) +std::string p3IdService::genRandomId() +{ + std::string randomId; + for(int i = 0; i < 20; i++) { + randomId += (char) ('a' + (RSRandom::random_u32() % 26)); + } + + return randomId; +} + +bool p3IdService::createGroup(RsIdGroup &group) +{ + if (group.mMeta.mGroupId.empty()) + { + /* new photo */ + + /* generate a temp id */ + group.mMeta.mGroupId = genRandomId(); + } + else + { + std::cerr << "p3IdService::createGroup() Group with existing Id... dropping"; + std::cerr << std::endl; return false; } - reputation = it->second; + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + + mUpdated = true; + + mIdProxy->addGroup(group); + return true; } -bool p3IdService::InternalgetIdPeerOpinion(const std::string &aboutid, const std::string &peerId, RsIdOpinion &opinion) + + +bool p3IdService::createMsg(RsIdMsg &msg) { - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - - std::map >::iterator it; - std::map::iterator oit; - it = mOpinions.find(aboutid); - if (it == mOpinions.end()) + if (msg.mMeta.mGroupId.empty()) { + /* new photo */ + std::cerr << "p3IdService::createMsg() Missing MsgID"; + std::cerr << std::endl; return false; } + + /* check if its a mod or new msg */ + if (msg.mMeta.mOrigMsgId.empty()) + { + std::cerr << "p3IdService::createMsg() New Msg"; + std::cerr << std::endl; + + /* new msg, generate a new OrigMsgId */ + msg.mMeta.mOrigMsgId = genRandomId(); + msg.mMeta.mMsgId = msg.mMeta.mOrigMsgId; + } + else + { + std::cerr << "p3IdService::createMsg() Modified Msg"; + std::cerr << std::endl; + + /* mod msg, keep orig msg id, generate a new MsgId */ + msg.mMeta.mMsgId = genRandomId(); + } + + std::cerr << "p3IdService::createMsg() GroupId: " << msg.mMeta.mGroupId; + std::cerr << std::endl; + std::cerr << "p3IdService::createMsg() MsgId: " << msg.mMeta.mMsgId; + std::cerr << std::endl; + std::cerr << "p3IdService::createMsg() OrigMsgId: " << msg.mMeta.mOrigMsgId; + std::cerr << std::endl; + + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + + mUpdated = true; + + mIdProxy->addMsg(msg); - oit = it->second.find(peerId); - if (oit == it->second.end()) - { - return false; - } - - opinion = oit->second; return true; } + +/********************************************************************************************/ + + + +bool IdDataProxy::getGroup(const std::string &id, RsIdGroup &group) +{ + void *groupData = NULL; + RsGroupMetaData meta; + if (getGroupData(id, groupData) && getGroupSummary(id, meta)) + { + RsIdGroup *pG = (RsIdGroup *) groupData; + group = *pG; + + // update definitive version of the metadata. + group.mMeta = meta; + + std::cerr << "IdDataProxy::getGroup() Id: " << id; + std::cerr << " MetaData: " << meta << " DataPointer: " << groupData; + std::cerr << std::endl; + return true; + } + + std::cerr << "IdDataProxy::getGroup() FAILED Id: " << id; + std::cerr << std::endl; + + return false; +} + +bool IdDataProxy::getMsg(const std::string &id, RsIdMsg &msg) +{ + void *msgData = NULL; + RsMsgMetaData meta; + if (getMsgData(id, msgData) && getMsgSummary(id, meta)) + { + RsIdMsg *pM = (RsIdMsg *) msgData; + // Shallow copy of thumbnail. + msg = *pM; + + // update definitive version of the metadata. + msg.mMeta = meta; + + std::cerr << "IdDataProxy::getMsg() Id: " << id; + std::cerr << " MetaData: " << meta << " DataPointer: " << msgData; + std::cerr << std::endl; + return true; + } + + std::cerr << "IdDataProxy::getMsg() FAILED Id: " << id; + std::cerr << std::endl; + + return false; +} + +bool IdDataProxy::addGroup(const RsIdGroup &group) +{ + // Make duplicate. + RsIdGroup *pG = new RsIdGroup(); + *pG = group; + + std::cerr << "IdDataProxy::addGroup()"; + std::cerr << " MetaData: " << pG->mMeta << " DataPointer: " << pG; + std::cerr << std::endl; + + return createGroup(pG); +} + + +bool IdDataProxy::addMsg(const RsIdMsg &msg) +{ + // Make duplicate. + RsIdMsg *pM = new RsIdMsg(); + *pM = msg; + + std::cerr << "IdDataProxy::addMsg()"; + std::cerr << " MetaData: " << pM->mMeta << " DataPointer: " << pM; + std::cerr << std::endl; + + return createMsg(pM); +} + + + + /* These Functions must be overloaded to complete the service */ +bool IdDataProxy::convertGroupToMetaData(void *groupData, RsGroupMetaData &meta) +{ + RsIdGroup *group = (RsIdGroup *) groupData; + meta = group->mMeta; + + return true; +} + +bool IdDataProxy::convertMsgToMetaData(void *msgData, RsMsgMetaData &meta) +{ + RsIdMsg *page = (RsIdMsg *) msgData; + meta = page->mMeta; + + return true; +} + + + + +/************************************************************************************/ +/************************************************************************************/ +/************************************************************************************/ +/************************************************************************************/ +/************************************************************************************/ + +#if 0 + /* details are updated */ bool p3IdService::updateIdentity(RsIdData &data) { @@ -472,20 +662,9 @@ bool p3IdService::updateOpinion(RsIdOpinion &opinion) } +#endif -std::string p3IdService::genRandomId() -{ - std::string randomId; - for(int i = 0; i < 20; i++) - { - randomId += (char) ('a' + (RSRandom::random_u32() % 26)); - } - - return randomId; -} - - void p3IdService::generateDummyData() { @@ -508,11 +687,12 @@ void p3IdService::generateDummyData() int nIds = 1 + (RSRandom::random_u32() % 2); for(i = 0; i < nIds; i++) { - RsIdData id; + RsIdGroup id; RsPeerDetails details; - id.mKeyId = genRandomId(); + //id.mKeyId = genRandomId(); + id.mMeta.mGroupId = genRandomId(); id.mIdType = RSID_TYPE_REALID; id.mGpgIdHash = genRandomId(); @@ -521,7 +701,9 @@ void p3IdService::generateDummyData() std::ostringstream out; out << details.name << "_" << i + 1; - id.mNickname = out.str(); + //id.mNickname = out.str(); + id.mMeta.mGroupName = out.str(); + id.mGpgIdKnown = true; id.mGpgId = *it; @@ -548,11 +730,13 @@ void p3IdService::generateDummyData() std::cerr << std::endl; id.mIdType |= RSID_RELATION_OTHER; - id.mNickname = genRandomId(); + //id.mNickname = genRandomId(); + id.mMeta.mGroupName = genRandomId(); id.mGpgIdKnown = false; } - mIds[id.mKeyId] = id; + //mIds[id.mKeyId] = id; + mIdProxy->addGroup(id); } } @@ -565,42 +749,48 @@ void p3IdService::generateDummyData() /* make some fake gpg ids */ for(i = 0; i < nFakeGPGs; i++) { - RsIdData id; + RsIdGroup id; RsPeerDetails details; - id.mKeyId = genRandomId(); + //id.mKeyId = genRandomId(); + id.mMeta.mGroupId = genRandomId(); id.mIdType = RSID_TYPE_REALID; id.mGpgIdHash = genRandomId(); id.mIdType |= RSID_RELATION_OTHER; - id.mNickname = genRandomId(); + //id.mNickname = genRandomId(); + id.mMeta.mGroupName = genRandomId(); id.mGpgIdKnown = false; id.mGpgId = ""; id.mGpgName = ""; id.mGpgEmail = ""; - mIds[id.mKeyId] = id; + //mIds[id.mKeyId] = id; + mIdProxy->addGroup(id); } /* make lots of pseudo ids */ for(i = 0; i < nFakePseudoIds; i++) { - RsIdData id; + RsIdGroup id; RsPeerDetails details; - id.mKeyId = genRandomId(); + //id.mKeyId = genRandomId(); + id.mMeta.mGroupId = genRandomId(); id.mIdType = RSID_TYPE_PSEUDONYM; id.mGpgIdHash = ""; - id.mNickname = genRandomId(); + //id.mNickname = genRandomId(); + id.mMeta.mGroupName = genRandomId(); id.mGpgIdKnown = false; id.mGpgId = ""; id.mGpgName = ""; id.mGpgEmail = ""; - mIds[id.mKeyId] = id; + //mIds[id.mKeyId] = id; + mIdProxy->addGroup(id); } mUpdated = true; @@ -646,3 +836,8 @@ std::string rsIdTypeToString(uint32_t idtype) + + + + + diff --git a/libretroshare/src/services/p3idservice.h b/libretroshare/src/services/p3idservice.h index c1877e807..d627e319e 100644 --- a/libretroshare/src/services/p3idservice.h +++ b/libretroshare/src/services/p3idservice.h @@ -39,8 +39,23 @@ * */ +class IdDataProxy: public GxsDataProxy +{ + public: -class p3IdService: public p3GxsService, public RsIdentity + bool getGroup(const std::string &id, RsIdGroup &group); + bool getMsg(const std::string &id, RsIdMsg &msg); + + bool addGroup(const RsIdGroup &group); + bool addMsg(const RsIdMsg &msg); + + /* These Functions must be overloaded to complete the service */ +virtual bool convertGroupToMetaData(void *groupData, RsGroupMetaData &meta); +virtual bool convertMsgToMetaData(void *msgData, RsMsgMetaData &meta); +}; + + +class p3IdService: public p3GxsDataService, public RsIdentity { public: @@ -54,8 +69,55 @@ virtual int tick(); /* changed? */ virtual bool updated(); + /* From RsTokenService */ + /* 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 */ + + /* 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); + + ////////////////////////////////////////////////////////////////////////////// + + + /* Specific Service Data */ +virtual bool getGroupData(const uint32_t &token, RsIdGroup &group); +virtual bool getMsgData(const uint32_t &token, RsIdMsg &msg); + +virtual bool createGroup(RsIdGroup &group); +virtual bool createMsg(RsIdMsg &msg); + /* Interface now a request / poll / answer system */ +#if 0 + /* Data Requests */ virtual bool requestIdentityList(uint32_t &token); virtual bool requestIdentities(uint32_t &token, const std::list &ids); @@ -87,21 +149,6 @@ virtual bool InternalgetIdentity(const std::string &id, RsIdData &data); virtual bool InternalgetIdReputation(const std::string &id, RsIdReputation &reputation); virtual bool InternalgetIdPeerOpinion(const std::string &aboutid, const std::string &peerid, RsIdOpinion &opinion); -#if 0 - /* changed? */ -virtual bool updated(); - -virtual bool getIdentityList(std::list &ids); - -virtual bool getIdentity(const std::string &id, RsIdData &data); -virtual bool getIdReputation(const std::string &id, RsIdReputation &reputation); -virtual bool getIdPeerOpinion(const std::string &aboutid, const std::string &peerid, RsIdOpinion &opinion); - -virtual bool getGpgIdDetails(const std::string &id, std::string &gpgName, std::string &gpgEmail); - -virtual bool updateIdentity(RsIdData &data); -virtual bool updateOpinion(RsIdOpinion &opinion); - #endif virtual void generateDummyData(); @@ -110,16 +157,20 @@ virtual void generateDummyData(); std::string genRandomId(); + IdDataProxy *mIdProxy; + RsMutex mIdMtx; /***** below here is locked *****/ bool mUpdated; +#if 0 std::map mIds; std::map > mOpinions; std::map mReputations; // this is created locally. +#endif }; diff --git a/libretroshare/src/services/p3photoservice.cc b/libretroshare/src/services/p3photoservice.cc index 00331ead4..c44b6c53b 100644 --- a/libretroshare/src/services/p3photoservice.cc +++ b/libretroshare/src/services/p3photoservice.cc @@ -1,13 +1,13 @@ /* * libretroshare/src/services p3photoservice.cc * - * Phot Service for RetroShare. + * Photo Service for RetroShare. * - * Copyright 2007-2012 by Robert Fernie. + * 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. + * 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 @@ -33,34 +33,24 @@ RsPhoto *rsPhoto = NULL; -#if 0 -PhotoAlbum::PhotoAlbum() -{ - return; -} -#endif - -#define PHOTO_REQUEST_ALBUMLIST 0x0001 -#define PHOTO_REQUEST_PHOTOLIST 0x0002 -#define PHOTO_REQUEST_ALBUMS 0x0004 -#define PHOTO_REQUEST_PHOTOS 0x0008 - /********************************************************************************/ /******************* Startup / Tick ******************************************/ /********************************************************************************/ p3PhotoService::p3PhotoService(uint16_t type) - :p3GxsService(type), mPhotoMtx("p3PhotoService"), mUpdated(true) + :p3GxsDataService(type, new PhotoDataProxy()), mPhotoMtx("p3PhotoService"), mUpdated(true) { RsStackMutex stack(mPhotoMtx); /********** STACK LOCKED MTX ******/ + + mPhotoProxy = (PhotoDataProxy *) mProxy; return; } int p3PhotoService::tick() { - std::cerr << "p3PhotoService::tick()"; - std::cerr << std::endl; + //std::cerr << "p3PhotoService::tick()"; + //std::cerr << std::endl; fakeprocessrequests(); @@ -80,64 +70,53 @@ bool p3PhotoService::updated() } -bool p3PhotoService::requestGroupList( uint32_t &token, const RsTokReqOptions &opts) + + /* Data Requests */ +bool p3PhotoService::requestGroupInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &groupIds) { - generateToken(token); - std::cerr << "p3PhotoService::requestGroupList() gets Token: " << token << std::endl; - - std::list ids; - storeRequest(token, GXS_REQUEST_TYPE_LIST | GXS_REQUEST_TYPE_GROUPS | PHOTO_REQUEST_ALBUMLIST, ids); + std::cerr << "p3PhotoService::requestGroupInfo() gets Token: " << token << std::endl; + storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_GROUPS, groupIds); return true; } -bool p3PhotoService::requestMsgList( uint32_t &token, const RsTokReqOptions &opts, const std::list &groupIds) +bool p3PhotoService::requestMsgInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &groupIds) { - generateToken(token); - std::cerr << "p3PhotoService::requestMsgList() gets Token: " << token << std::endl; - storeRequest(token, GXS_REQUEST_TYPE_LIST | GXS_REQUEST_TYPE_MSGS | PHOTO_REQUEST_PHOTOLIST, groupIds); + std::cerr << "p3PhotoService::requestMsgInfo() gets Token: " << token << std::endl; + storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_MSGS, groupIds); return true; } -bool p3PhotoService::requestMsgRelatedList( uint32_t &token, const RsTokReqOptions &opts, const std::list &groupIds) -{ - std::cerr << "p3PhotoService::requestMsgRelatedList() gets Token: " << token << std::endl; - return false; -} - -bool p3PhotoService::requestGroupData(uint32_t &token, const std::list &albumids) +bool p3PhotoService::requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &msgIds) { generateToken(token); - std::cerr << "p3PhotoService::requestGroupData() gets Token: " << token << std::endl; - storeRequest(token, GXS_REQUEST_TYPE_DATA | GXS_REQUEST_TYPE_GROUPS | PHOTO_REQUEST_ALBUMS, albumids); + std::cerr << "p3PhotoService::requestMsgRelatedInfo() gets Token: " << token << std::endl; + storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_MSGRELATED, msgIds); return true; } -bool p3PhotoService::requestMsgData(uint32_t &token, const std::list &photoids) -{ - - generateToken(token); - std::cerr << "p3PhotoService::requestMsgData() gets Token: " << token << std::endl; - storeRequest(token, GXS_REQUEST_TYPE_DATA | GXS_REQUEST_TYPE_MSGS | PHOTO_REQUEST_PHOTOS, photoids); - - return true; -} - - -bool p3PhotoService::getGroupList(const uint32_t &token, std::list &groupIds) + /* Generic Lists */ +bool p3PhotoService::getGroupList( const uint32_t &token, std::list &groupIds) { uint32_t status; uint32_t reqtype; + uint32_t anstype; time_t ts; - checkRequestStatus(token, status, reqtype, ts); - - if (reqtype != (GXS_REQUEST_TYPE_LIST | GXS_REQUEST_TYPE_GROUPS | PHOTO_REQUEST_ALBUMLIST)) + checkRequestStatus(token, status, reqtype, anstype, ts); + + if (anstype != RS_TOKREQ_ANSTYPE_LIST) { - std::cerr << "p3PhotoService::getGroupList() ERROR Type Wrong" << std::endl; + std::cerr << "p3PhotoService::getGroupList() ERROR AnsType Wrong" << std::endl; + return false; + } + + if (reqtype != GXS_REQUEST_TYPE_GROUPS) + { + std::cerr << "p3PhotoService::getGroupList() ERROR ReqType Wrong" << std::endl; return false; } @@ -146,24 +125,33 @@ bool p3PhotoService::getGroupList(const uint32_t &token, std::list std::cerr << "p3PhotoService::getGroupList() ERROR Status Incomplete" << std::endl; return false; } - - bool ans = InternalgetAlbumList(groupIds); - + + bool ans = loadRequestOutList(token, groupIds); updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); - + return ans; } -bool p3PhotoService::getMsgList(const uint32_t &token, std::list &msgIds) + + + +bool p3PhotoService::getMsgList( const uint32_t &token, std::list &msgIds) { uint32_t status; uint32_t reqtype; + uint32_t anstype; time_t ts; - checkRequestStatus(token, status, reqtype, ts); - - if (reqtype != (GXS_REQUEST_TYPE_LIST | GXS_REQUEST_TYPE_MSGS | PHOTO_REQUEST_PHOTOLIST)) + checkRequestStatus(token, status, reqtype, anstype, ts); + + if (anstype != RS_TOKREQ_ANSTYPE_LIST) { - std::cerr << "p3PhotoService::getMsgList() ERROR Type Wrong" << std::endl; + std::cerr << "p3PhotoService::getMsgList() ERROR AnsType Wrong" << std::endl; + return false; + } + + if ((reqtype != GXS_REQUEST_TYPE_MSGS) && (reqtype != GXS_REQUEST_TYPE_MSGRELATED)) + { + std::cerr << "p3PhotoService::getMsgList() ERROR ReqType Wrong" << std::endl; return false; } @@ -172,33 +160,110 @@ bool p3PhotoService::getMsgList(const uint32_t &token, std::list &m std::cerr << "p3PhotoService::getMsgList() ERROR Status Incomplete" << std::endl; return false; } - - std::string id; - if (!popRequestList(token, id)) - { - /* finished */ - updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); - return false; - } - - bool ans = InternalgetPhotoList(id, msgIds); - // Only one Album at a time -> so finish it! + bool ans = loadRequestOutList(token, msgIds); updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); - + return ans; } -bool p3PhotoService::getAlbum(const uint32_t &token, RsPhotoAlbum &album) + + /* Generic Summary */ +bool p3PhotoService::getGroupSummary( const uint32_t &token, std::list &groupInfo) { uint32_t status; uint32_t reqtype; + uint32_t anstype; time_t ts; - checkRequestStatus(token, status, reqtype, ts); - - if (reqtype != (GXS_REQUEST_TYPE_DATA | GXS_REQUEST_TYPE_GROUPS | PHOTO_REQUEST_ALBUMS)) + checkRequestStatus(token, status, reqtype, anstype, ts); + + if (anstype != RS_TOKREQ_ANSTYPE_SUMMARY) { - std::cerr << "p3PhotoService::getAlbum() ERROR Type Wrong" << std::endl; + std::cerr << "p3PhotoService::getGroupSummary() ERROR AnsType Wrong" << std::endl; + return false; + } + + if (reqtype != GXS_REQUEST_TYPE_GROUPS) + { + std::cerr << "p3PhotoService::getGroupSummary() ERROR ReqType Wrong" << std::endl; + return false; + } + + if (status != GXS_REQUEST_STATUS_COMPLETE) + { + std::cerr << "p3PhotoService::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 p3PhotoService::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 << "p3PhotoService::getMsgSummary() ERROR AnsType Wrong" << std::endl; + return false; + } + + if ((reqtype != GXS_REQUEST_TYPE_MSGS) && (reqtype != GXS_REQUEST_TYPE_MSGRELATED)) + { + std::cerr << "p3PhotoService::getMsgSummary() ERROR ReqType Wrong" << std::endl; + return false; + } + + if (status != GXS_REQUEST_STATUS_COMPLETE) + { + std::cerr << "p3PhotoService::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 p3PhotoService::getAlbum(const uint32_t &token, RsPhotoAlbum &album) +{ + std::cerr << "p3PhotoService::getAlbum() 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 << "p3PhotoService::getAlbum() ERROR AnsType Wrong" << std::endl; + return false; + } + + if (reqtype != GXS_REQUEST_TYPE_GROUPS) + { + std::cerr << "p3PhotoService::getAlbum() ERROR ReqType Wrong" << std::endl; return false; } @@ -209,28 +274,40 @@ bool p3PhotoService::getAlbum(const uint32_t &token, RsPhotoAlbum &album) } std::string id; - if (!popRequestList(token, id)) + if (!popRequestOutList(token, id)) { /* finished */ updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); return false; } - bool ans = InternalgetAlbum(id, album); + /* convert to RsPhotoAlbum */ + bool ans = mPhotoProxy->getAlbum(id, album); return ans; - } + bool p3PhotoService::getPhoto(const uint32_t &token, RsPhotoPhoto &photo) { + std::cerr << "p3PhotoService::getPhoto() Token: " << token; + std::cerr << std::endl; + uint32_t status; uint32_t reqtype; + uint32_t anstype; time_t ts; - checkRequestStatus(token, status, reqtype, ts); + checkRequestStatus(token, status, reqtype, anstype, ts); - if (reqtype != (GXS_REQUEST_TYPE_DATA | GXS_REQUEST_TYPE_MSGS | PHOTO_REQUEST_PHOTOS)) + + if (anstype != RS_TOKREQ_ANSTYPE_DATA) { - std::cerr << "p3PhotoService::getPhoto() ERROR Type Wrong" << std::endl; + std::cerr << "p3PhotoService::getPhoto() ERROR AnsType Wrong" << std::endl; + return false; + } + + if ((reqtype != GXS_REQUEST_TYPE_MSGS) && (reqtype != GXS_REQUEST_TYPE_MSGRELATED)) + { + std::cerr << "p3PhotoService::getPhoto() ERROR ReqType Wrong" << std::endl; return false; } @@ -241,157 +318,85 @@ bool p3PhotoService::getPhoto(const uint32_t &token, RsPhotoPhoto &photo) } std::string id; - if (!popRequestList(token, id)) + if (!popRequestOutList(token, id)) { /* finished */ updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); return false; } - bool ans = InternalgetPhoto(id, photo); + /* convert to RsPhotoAlbum */ + bool ans = mPhotoProxy->getPhoto(id, photo); return ans; } + + /* Poll */ uint32_t p3PhotoService::requestStatus(const uint32_t token) { uint32_t status; uint32_t reqtype; + uint32_t anstype; time_t ts; - checkRequestStatus(token, status, reqtype, ts); + checkRequestStatus(token, status, reqtype, anstype, ts); return status; } -#if 0 -#define MAX_REQUEST_AGE 60 - -bool p3PhotoService::fakeprocessrequests() - { - std::list::iterator it; - std::list tokens; - - tokenList(tokens); - - time_t now = time(NULL); - for(it = tokens.begin(); it != tokens.end(); it++) - { - uint32_t status; - uint32_t reqtype; - uint32_t token = *it; - time_t ts; - checkRequestStatus(token, status, reqtype, ts); - - std::cerr << "p3PhotoService::fakeprocessrequests() Token: " << token << " Status: " << status << " ReqType: " << reqtype << "Age: " << now - ts << std::endl; - - if (status == GXS_REQUEST_STATUS_PENDING) - { - updateRequestStatus(token, GXS_REQUEST_STATUS_PARTIAL); - } - else if (status == GXS_REQUEST_STATUS_PARTIAL) - { - updateRequestStatus(token, GXS_REQUEST_STATUS_COMPLETE); - } - else if (status == GXS_REQUEST_STATUS_DONE) - { - std::cerr << "p3PhotoService::fakeprocessrequests() Clearing Done Request Token: " << token; - std::cerr << std::endl; - clearRequest(token); - } - else if (now - ts > MAX_REQUEST_AGE) - { - std::cerr << "p3PhotoService::fakeprocessrequests() Clearing Old Request Token: " << token; - std::cerr << std::endl; - clearRequest(token); - } - } - - return true; -} -#endif - - - -/******************* INTERNALS UNTIL ITS PROPERLY LINKED IN ************************/ - -bool p3PhotoService::InternalgetAlbumList(std::list &album) + /* Cancel Request */ +bool p3PhotoService::cancelRequest(const uint32_t &token) { - RsStackMutex stack(mPhotoMtx); /********** STACK LOCKED MTX ******/ + return clearRequest(token); +} - std::map::iterator it; - for(it = mAlbums.begin(); it != mAlbums.end(); it++) - { - album.push_back(it->second.mAlbumId); - } - + ////////////////////////////////////////////////////////////////////////////// + /* Functions from Forums -> need to be implemented generically */ +bool p3PhotoService::groupsChanged(std::list &groupIds) +{ return false; } -bool p3PhotoService::InternalgetAlbum(const std::string &albumid, RsPhotoAlbum &album) + // Get Message Status - is retrived via MessageSummary. +bool p3PhotoService::setMessageStatus(const std::string &msgId, const uint32_t status, const uint32_t statusMask) { - RsStackMutex stack(mPhotoMtx); /********** STACK LOCKED MTX ******/ - - std::map::iterator it; - it = mAlbums.find(albumid); - if (it == mAlbums.end()) - { - return false; - } - - album = it->second; - return true; + return false; } -bool p3PhotoService::InternalgetPhoto(const std::string &photoid, RsPhotoPhoto &photo) + + // +bool p3PhotoService::groupSubscribe(const std::string &groupId, bool subscribe) { - RsStackMutex stack(mPhotoMtx); /********** STACK LOCKED MTX ******/ - - std::map::iterator it; - it = mPhotos.find(photoid); - if (it == mPhotos.end()) - { - return false; - } - - photo = it->second; - return true; + return false; } -bool p3PhotoService::InternalgetPhotoList(const std::string &albumid, std::list &photoIds) -{ - RsStackMutex stack(mPhotoMtx); /********** STACK LOCKED MTX ******/ - std::map >::iterator it; - it = mAlbumToPhotos.find(albumid); - if (it == mAlbumToPhotos.end()) - { - return false; - } - - std::list::iterator lit; - for(lit = it->second.begin(); lit != it->second.end(); lit++) - { - photoIds.push_back(*lit); - } - return true; +bool p3PhotoService::groupRestoreKeys(const std::string &groupId) +{ + return false; } +bool p3PhotoService::groupShareKeys(const std::string &groupId, std::list& peers) +{ + return false; +} + + /* details are updated in album - to choose Album ID, and storage path */ bool p3PhotoService::submitAlbumDetails(RsPhotoAlbum &album) { /* check if its a modification or a new album */ - /* add to database */ /* check if its a mod or new photo */ - if (album.mId.empty()) + if (album.mMeta.mGroupId.empty()) { /* new photo */ /* generate a temp id */ - album.mAlbumId = genRandomId(); + album.mMeta.mGroupId = genRandomId(); } RsStackMutex stack(mPhotoMtx); /********** STACK LOCKED MTX ******/ @@ -399,7 +404,7 @@ bool p3PhotoService::submitAlbumDetails(RsPhotoAlbum &album) mUpdated = true; /* add / modify */ - mAlbums[album.mAlbumId] = album; + mPhotoProxy->addAlbum(album); return true; } @@ -407,158 +412,145 @@ bool p3PhotoService::submitAlbumDetails(RsPhotoAlbum &album) bool p3PhotoService::submitPhoto(RsPhotoPhoto &photo) { - if (photo.mAlbumId.empty()) + if (photo.mMeta.mGroupId.empty()) { /* new photo */ - std::cerr << "p3PhotoService::submitPhoto() Missing AlbumID: ERROR"; + std::cerr << "p3PhotoService::submitPhoto() Missing GroupID: ERROR"; std::cerr << std::endl; return false; } /* check if its a mod or new photo */ - if (photo.mId.empty()) + if (photo.mMeta.mMsgId.empty()) { /* new photo */ /* generate a temp id */ - photo.mId = genRandomId(); + photo.mMeta.mMsgId = genRandomId(); } RsStackMutex stack(mPhotoMtx); /********** STACK LOCKED MTX ******/ mUpdated = true; - std::map >::iterator it; - it = mAlbumToPhotos.find(photo.mAlbumId); - if (it == mAlbumToPhotos.end()) - { - std::list emptyList; - mAlbumToPhotos[photo.mAlbumId] = emptyList; - - it = mAlbumToPhotos.find(photo.mAlbumId); - } - - it->second.push_back(photo.mId); - - /* add / modify */ - mPhotos[photo.mId] = photo; + mPhotoProxy->addPhoto(photo); return true; } -#if 0 -bool p3PhotoService::getPhotoThumbnail(const std::string &photoid, RsPhotoThumbnail &thumbnail) + + +/********************************************************************************************/ + +bool PhotoDataProxy::getAlbum(const std::string &id, RsPhotoAlbum &album) { - RsStackMutex stack(mPhotoMtx); /********** STACK LOCKED MTX ******/ - - std::map::iterator it; - it = mPhotoThumbnails.find(photoid); - if (it == mPhotoThumbnails.end()) + void *groupData = NULL; + RsGroupMetaData meta; + if (getGroupData(id, groupData) && getGroupSummary(id, meta)) { - return false; - } - - // shallow copy??? dangerous! - thumbnail = *(it->second); - return true; -} + RsPhotoAlbum *pA = (RsPhotoAlbum *) groupData; + // Shallow copy of thumbnail. + album = *pA; -bool p3PhotoService::getAlbumThumbnail(const std::string &albumid, RsPhotoThumbnail &thumbnail) -{ - RsStackMutex stack(mPhotoMtx); /********** STACK LOCKED MTX ******/ - - std::map::iterator it; - it = mAlbumThumbnails.find(albumid); - if (it == mAlbumThumbnails.end()) - { - return false; - } - - // shallow copy??? dangerous! - thumbnail = *(it->second); - return true; -} + // update definitive version of the metadata. + album.mMeta = meta; -/* details are updated in album - to choose Album ID, and storage path */ -bool p3PhotoService::submitAlbumDetails(RsPhotoAlbum &album, const RsPhotoThumbnail &thumbnail) -{ - /* check if its a modification or a new album */ - - - /* add to database */ - - /* check if its a mod or new photo */ - if (album.mId.empty()) - { - /* new photo */ - - /* generate a temp id */ - album.mAlbumId = genRandomId(); - } - - RsStackMutex stack(mPhotoMtx); /********** STACK LOCKED MTX ******/ - - mUpdated = true; - - /* add / modify */ - mAlbums[album.mAlbumId] = album; - - /* must fix this up later! */ - RsPhotoThumbnail *thumb = new RsPhotoThumbnail(); - thumb->copyFrom(thumbnail); - mAlbumThumbnails[album.mAlbumId] = thumb; - - return true; -} - - -bool p3PhotoService::submitPhoto(RsPhotoPhoto &photo, const RsPhotoThumbnail &thumbnail) -{ - if (photo.mAlbumId.empty()) - { - /* new photo */ - std::cerr << "p3PhotoService::submitPhoto() Missing AlbumID: ERROR"; + std::cerr << "PhotoDataProxy::getAlbum() Id: " << id; + std::cerr << " MetaData: " << meta << " DataPointer: " << groupData; std::cerr << std::endl; - return false; + return true; } - - /* check if its a mod or new photo */ - if (photo.mId.empty()) + + std::cerr << "PhotoDataProxy::getAlbum() FAILED Id: " << id; + std::cerr << std::endl; + + return false; +} + +bool PhotoDataProxy::getPhoto(const std::string &id, RsPhotoPhoto &photo) +{ + void *msgData = NULL; + RsMsgMetaData meta; + if (getMsgData(id, msgData) && getMsgSummary(id, meta)) { - /* new photo */ + RsPhotoPhoto *pP = (RsPhotoPhoto *) msgData; + // Shallow copy of thumbnail. + photo = *pP; + + // update definitive version of the metadata. + photo.mMeta = meta; - /* generate a temp id */ - photo.mId = genRandomId(); + std::cerr << "PhotoDataProxy::getPhoto() Id: " << id; + std::cerr << " MetaData: " << meta << " DataPointer: " << msgData; + std::cerr << std::endl; + return true; } - RsStackMutex stack(mPhotoMtx); /********** STACK LOCKED MTX ******/ + std::cerr << "PhotoDataProxy::getPhoto() FAILED Id: " << id; + std::cerr << std::endl; - mUpdated = true; + return false; +} - std::map >::iterator it; - it = mAlbumToPhotos.find(photo.mAlbumId); - if (it == mAlbumToPhotos.end()) - { - std::list emptyList; - mAlbumToPhotos[photo.mAlbumId] = emptyList; - it = mAlbumToPhotos.find(photo.mAlbumId); - } - - it->second.push_back(photo.mId); - - /* add / modify */ - mPhotos[photo.mId] = photo; - /* must fix this up later! */ - RsPhotoThumbnail *thumb = new RsPhotoThumbnail(); - thumb->copyFrom(thumbnail); - mPhotoThumbnails[photo.mId] = thumb; - +bool PhotoDataProxy::addAlbum(const RsPhotoAlbum &album) +{ + // Make duplicate. + RsPhotoAlbum *pA = new RsPhotoAlbum(); + *pA = album; + + std::cerr << "PhotoDataProxy::addAlbum()"; + std::cerr << " MetaData: " << pA->mMeta << " DataPointer: " << pA; + std::cerr << std::endl; + + // deep copy thumbnail. + pA->mThumbnail.data = NULL; + pA->mThumbnail.copyFrom(album.mThumbnail); + + return createGroup(pA); +} + + +bool PhotoDataProxy::addPhoto(const RsPhotoPhoto &photo) +{ + // Make duplicate. + RsPhotoPhoto *pP = new RsPhotoPhoto(); + *pP = photo; + + std::cerr << "PhotoDataProxy::addPhoto()"; + std::cerr << " MetaData: " << pP->mMeta << " DataPointer: " << pP; + std::cerr << std::endl; + + // deep copy thumbnail. + pP->mThumbnail.data = NULL; + pP->mThumbnail.copyFrom(photo.mThumbnail); + + return createMsg(pP); +} + + + + /* These Functions must be overloaded to complete the service */ +bool PhotoDataProxy::convertGroupToMetaData(void *groupData, RsGroupMetaData &meta) +{ + RsPhotoAlbum *album = (RsPhotoAlbum *) groupData; + meta = album->mMeta; + return true; } -#endif - + +bool PhotoDataProxy::convertMsgToMetaData(void *msgData, RsMsgMetaData &meta) +{ + RsPhotoPhoto *photo = (RsPhotoPhoto *) msgData; + meta = photo->mMeta; + + return true; +} + + +/********************************************************************************************/ + std::string p3PhotoService::genRandomId() { std::string randomId; @@ -592,7 +584,3 @@ bool RsPhotoThumbnail::copyFrom(const RsPhotoThumbnail &nail) return true; } - - - - diff --git a/libretroshare/src/services/p3photoservice.h b/libretroshare/src/services/p3photoservice.h index 6f90c7963..c500ae83f 100644 --- a/libretroshare/src/services/p3photoservice.h +++ b/libretroshare/src/services/p3photoservice.h @@ -47,26 +47,26 @@ * */ -#if 0 -class PhotoAlbum + +class PhotoDataProxy: public GxsDataProxy { public: - PhotoAlbum(); - std::string albumid; + bool addAlbum(const RsPhotoAlbum &album); + bool addPhoto(const RsPhotoPhoto &photo); - RsPhotoAlbum mAlbum; - RsPhotoThumbnail mAlbumThumbnail; + bool getAlbum(const std::string &id, RsPhotoAlbum &album); + bool getPhoto(const std::string &id, RsPhotoPhoto &photo); + + /* These Functions must be overloaded to complete the service */ +virtual bool convertGroupToMetaData(void *groupData, RsGroupMetaData &meta); +virtual bool convertMsgToMetaData(void *groupData, RsMsgMetaData &meta); - std::map mPhotos; - std::map mNails; }; -#endif - -class p3PhotoService: public p3GxsService, public RsPhoto +class p3PhotoService: public p3GxsDataService, public RsPhoto { public: @@ -81,63 +81,59 @@ virtual int tick(); virtual bool updated(); - /* Data Requests (from RsTokenService) */ -virtual bool requestGroupList( uint32_t &token, const RsTokReqOptions &opts); -virtual bool requestMsgList( uint32_t &token, const RsTokReqOptions &opts, const std::list &groupIds); -virtual bool requestMsgRelatedList(uint32_t &token, const RsTokReqOptions &opts, const std::list &msgIds); + /* 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); -virtual bool requestGroupData( uint32_t &token, const std::list &groupIds); -virtual bool requestMsgData( uint32_t &token, 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 getAlbum(const uint32_t &token, RsPhotoAlbum &album); +virtual bool getPhoto(const uint32_t &token, RsPhotoPhoto &photo); /* Poll */ virtual uint32_t requestStatus(const uint32_t token); - /* Generic List Data */ -virtual bool getGroupList(const uint32_t &token, std::list &groupIds); -virtual bool getMsgList(const uint32_t &token, std::list &msgIds); + /* 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); - /* Specific Service Data */ -virtual bool getAlbum(const uint32_t &token, RsPhotoAlbum &album); -virtual bool getPhoto(const uint32_t &token, RsPhotoPhoto &photo); /* details are updated in album - to choose Album ID, and storage path */ virtual bool submitAlbumDetails(RsPhotoAlbum &album); virtual bool submitPhoto(RsPhotoPhoto &photo); -bool InternalgetAlbumList(std::list &album); -bool InternalgetPhotoList(const std::string &albumid, std::list &photoIds); -bool InternalgetAlbum(const std::string &albumid, RsPhotoAlbum &album); -bool InternalgetPhoto(const std::string &photoid, RsPhotoPhoto &photo); - -#if 0 -virtual bool updated(); -virtual bool getAlbumList(std::list &album); - -virtual bool getAlbum(const std::string &albumid, RsPhotoAlbum &album); -virtual bool getPhoto(const std::string &photoid, RsPhotoPhoto &photo); -virtual bool getPhotoList(const std::string &albumid, std::list &photoIds); -virtual bool getPhotoThumbnail(const std::string &photoid, RsPhotoThumbnail &thumbnail); -virtual bool getAlbumThumbnail(const std::string &albumid, RsPhotoThumbnail &thumbnail); - -/* details are updated in album - to choose Album ID, and storage path */ -virtual bool submitAlbumDetails(RsPhotoAlbum &album, const RsPhotoThumbnail &thumbnail); -virtual bool submitPhoto(RsPhotoPhoto &photo, const RsPhotoThumbnail &thumbnail); -#endif private: std::string genRandomId(); + PhotoDataProxy *mPhotoProxy; + RsMutex mPhotoMtx; - - /***** below here is locked *****/ - bool mUpdated; - std::map > mAlbumToPhotos; - std::map mPhotos; - std::map mAlbums; }; diff --git a/libretroshare/src/services/p3wikiservice.cc b/libretroshare/src/services/p3wikiservice.cc index d5e548ea9..5a5cd7047 100644 --- a/libretroshare/src/services/p3wikiservice.cc +++ b/libretroshare/src/services/p3wikiservice.cc @@ -33,24 +33,17 @@ RsWiki *rsWiki = NULL; -#define WIKI_REQUEST_GROUPLIST 0x0001 -#define WIKI_REQUEST_MSGLIST 0x0002 -#define WIKI_REQUEST_GROUPS 0x0004 -#define WIKI_REQUEST_MSGS 0x0008 - -#define WIKI_REQUEST_PAGEVERSIONS 0x0010 -#define WIKI_REQUEST_ORIGPAGE 0x0020 -#define WIKI_REQUEST_LATESTPAGE 0x0040 - /********************************************************************************/ /******************* Startup / Tick ******************************************/ /********************************************************************************/ p3WikiService::p3WikiService(uint16_t type) - :p3GxsService(type), mWikiMtx("p3WikiService"), mUpdated(true) + :p3GxsDataService(type, new WikiDataProxy()), mWikiMtx("p3WikiService"), mUpdated(true) { RsStackMutex stack(mWikiMtx); /********** STACK LOCKED MTX ******/ + + mWikiProxy = (WikiDataProxy *) mProxy; return; } @@ -59,9 +52,9 @@ int p3WikiService::tick() { std::cerr << "p3WikiService::tick()"; std::cerr << std::endl; - - fakeprocessrequests(); + fakeprocessrequests(); + return 0; } @@ -79,82 +72,52 @@ bool p3WikiService::updated() -/***********************************************************************************************/ - /* Data Requests */ -bool p3WikiService::requestGroupList( uint32_t &token, const RsTokReqOptions &opts) +bool p3WikiService::requestGroupInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &groupIds) { - generateToken(token); - std::cerr << "p3WikiService::requestGroupList() gets Token: " << token << std::endl; + generateToken(token); + std::cerr << "p3WikiService::requestGroupInfo() gets Token: " << token << std::endl; + storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_GROUPS, groupIds); - std::list ids; - storeRequest(token, GXS_REQUEST_TYPE_LIST | GXS_REQUEST_TYPE_GROUPS | WIKI_REQUEST_GROUPLIST, ids); - - return true; + return true; } - -bool p3WikiService::requestMsgList( uint32_t &token, const RsTokReqOptions &opts, const std::list &groupIds) +bool p3WikiService::requestMsgInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &groupIds) { - generateToken(token); - std::cerr << "p3WikiService::requestMsgList() gets Token: " << token << std::endl; - storeRequest(token, GXS_REQUEST_TYPE_LIST | GXS_REQUEST_TYPE_MSGS | WIKI_REQUEST_ORIGPAGE, groupIds); + generateToken(token); + std::cerr << "p3WikiService::requestMsgInfo() gets Token: " << token << std::endl; + storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_MSGS, groupIds); - return true; + return true; } -bool p3WikiService::requestMsgRelatedList(uint32_t &token, const RsTokReqOptions &opts, const std::list &msgIds) +bool p3WikiService::requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &msgIds) { - generateToken(token); - std::cerr << "p3WikiService::requestMsgRelatedList() gets Token: " << token << std::endl; + generateToken(token); + std::cerr << "p3WikiService::requestMsgRelatedInfo() gets Token: " << token << std::endl; + storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_MSGRELATED, msgIds); - // Look at opts to set the flags. - uint32_t optFlags = 0; - if (opts.mOptions == RS_TOKREQOPT_MSG_VERSIONS) - { - optFlags = WIKI_REQUEST_PAGEVERSIONS; - } - else if (opts.mOptions == RS_TOKREQOPT_MSG_LATEST) - { - optFlags = WIKI_REQUEST_LATESTPAGE; - } - - storeRequest(token, GXS_REQUEST_TYPE_LIST | GXS_REQUEST_TYPE_MSGS | optFlags, msgIds); - - return true; + return true; } - -bool p3WikiService::requestGroupData( uint32_t &token, const std::list &groupIds) -{ - generateToken(token); - std::cerr << "p3WikiService::requestGroupData() gets Token: " << token << std::endl; - storeRequest(token, GXS_REQUEST_TYPE_DATA | GXS_REQUEST_TYPE_GROUPS | WIKI_REQUEST_GROUPS, groupIds); - - return true; -} - -bool p3WikiService::requestMsgData( uint32_t &token, const std::list &msgIds) -{ - generateToken(token); - std::cerr << "p3WikiService::requestMsgData() gets Token: " << token << std::endl; - storeRequest(token, GXS_REQUEST_TYPE_DATA | GXS_REQUEST_TYPE_MSGS | WIKI_REQUEST_MSGS, msgIds); - - return true; -} - -/**************** Return Data *************/ - -bool p3WikiService::getGroupList(const uint32_t &token, std::list &groupIds) + /* Generic Lists */ +bool p3WikiService::getGroupList( const uint32_t &token, std::list &groupIds) { uint32_t status; uint32_t reqtype; + uint32_t anstype; time_t ts; - checkRequestStatus(token, status, reqtype, ts); - - if (reqtype != (GXS_REQUEST_TYPE_LIST | GXS_REQUEST_TYPE_GROUPS | WIKI_REQUEST_GROUPLIST)) + checkRequestStatus(token, status, reqtype, anstype, ts); + + if (anstype != RS_TOKREQ_ANSTYPE_LIST) { - std::cerr << "p3WikiService::getGroupList() ERROR Type Wrong" << std::endl; + std::cerr << "p3WikiService::getGroupList() ERROR AnsType Wrong" << std::endl; + return false; + } + + if (reqtype != GXS_REQUEST_TYPE_GROUPS) + { + std::cerr << "p3WikiService::getGroupList() ERROR ReqType Wrong" << std::endl; return false; } @@ -163,25 +126,33 @@ bool p3WikiService::getGroupList(const uint32_t &token, std::list & std::cerr << "p3WikiService::getGroupList() ERROR Status Incomplete" << std::endl; return false; } - - bool ans = InternalgetGroupList(groupIds); + bool ans = loadRequestOutList(token, groupIds); updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); return ans; } - -bool p3WikiService::getMsgList(const uint32_t &token, std::list &msgIds) + + + + +bool p3WikiService::getMsgList( const uint32_t &token, std::list &msgIds) { uint32_t status; uint32_t reqtype; + uint32_t anstype; time_t ts; - checkRequestStatus(token, status, reqtype, ts); + checkRequestStatus(token, status, reqtype, anstype, ts); - // MULTIPLY TYPES MATCH HERE.... - if (!((reqtype & GXS_REQUEST_TYPE_LIST) && (reqtype & GXS_REQUEST_TYPE_MSGS))) + if (anstype != RS_TOKREQ_ANSTYPE_LIST) { - std::cerr << "p3WikiService::getMsgList() ERROR Type Wrong" << std::endl; + std::cerr << "p3WikiService::getMsgList() ERROR AnsType Wrong" << std::endl; + return false; + } + + if ((reqtype != GXS_REQUEST_TYPE_MSGS) && (reqtype != GXS_REQUEST_TYPE_MSGRELATED)) + { + std::cerr << "p3WikiService::getMsgList() ERROR ReqType Wrong" << std::endl; return false; } @@ -190,60 +161,107 @@ bool p3WikiService::getMsgList(const uint32_t &token, std::list &ms std::cerr << "p3WikiService::getMsgList() ERROR Status Incomplete" << std::endl; return false; } - - std::string id; - bool ans = false; - while (popRequestList(token, id)) - { - std::cerr << "p3WikiService::getMsgList() Processing Id: " << id << std::endl; - if (reqtype & WIKI_REQUEST_PAGEVERSIONS) - { - std::cerr << "p3WikiService::getMsgList() get PAGEVERSIONS" << std::endl; - if (InternalgetPageVersions(id, msgIds)) - { - ans = true; - } - } - else if (reqtype & WIKI_REQUEST_ORIGPAGE) - { - std::cerr << "p3WikiService::getMsgList() get ORIGPAGE" << std::endl; - if (InternalgetOrigPageList(id, msgIds)) - { - ans = true; - } - } - else if (reqtype & WIKI_REQUEST_LATESTPAGE) - { - std::cerr << "p3WikiService::getMsgList() get LATESTPAGE" << std::endl; - std::string latestpage; - if (InternalgetLatestPage(id, latestpage)) - { - msgIds.push_back(latestpage); - ans = true; - } - } - else - { - std::cerr << "p3WikiService::getMsgList() ERROR Invalid Request Type" << std::endl; - return false; - } - - } + + bool ans = loadRequestOutList(token, msgIds); updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); + return ans; } + + + /* Generic Summary */ +bool p3WikiService::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 << "p3WikiService::getGroupSummary() ERROR AnsType Wrong" << std::endl; + return false; + } + if (reqtype != GXS_REQUEST_TYPE_GROUPS) + { + std::cerr << "p3WikiService::getGroupSummary() ERROR ReqType Wrong" << std::endl; + return false; + } + if (status != GXS_REQUEST_STATUS_COMPLETE) + { + std::cerr << "p3WikiService::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 p3WikiService::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 << "p3WikiService::getMsgSummary() ERROR AnsType Wrong" << std::endl; + return false; + } + + if ((reqtype != GXS_REQUEST_TYPE_MSGS) && (reqtype != GXS_REQUEST_TYPE_MSGRELATED)) + { + std::cerr << "p3WikiService::getMsgSummary() ERROR ReqType Wrong" << std::endl; + return false; + } + + if (status != GXS_REQUEST_STATUS_COMPLETE) + { + std::cerr << "p3WikiService::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 p3WikiService::getGroupData(const uint32_t &token, RsWikiGroup &group) { uint32_t status; uint32_t reqtype; + uint32_t anstype; time_t ts; - checkRequestStatus(token, status, reqtype, ts); + checkRequestStatus(token, status, reqtype, anstype, ts); - if (reqtype != (GXS_REQUEST_TYPE_DATA | GXS_REQUEST_TYPE_GROUPS | WIKI_REQUEST_GROUPS)) + + if (anstype != RS_TOKREQ_ANSTYPE_DATA) { - std::cerr << "p3WikiService::getGroupData() ERROR Type Wrong" << std::endl; + std::cerr << "p3WikiService::getGroupData() ERROR AnsType Wrong" << std::endl; + return false; + } + + if (reqtype != GXS_REQUEST_TYPE_GROUPS) + { + std::cerr << "p3WikiService::getGroupData() ERROR ReqType Wrong" << std::endl; return false; } @@ -254,14 +272,15 @@ bool p3WikiService::getGroupData(const uint32_t &token, RsWikiGroup &group) } std::string id; - if (!popRequestList(token, id)) + if (!popRequestOutList(token, id)) { /* finished */ updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); return false; } - bool ans = InternalgetGroup(id, group); + /* convert to RsWikiAlbum */ + bool ans = mWikiProxy->getGroup(id, group); return ans; } @@ -270,12 +289,20 @@ bool p3WikiService::getMsgData(const uint32_t &token, RsWikiPage &page) { uint32_t status; uint32_t reqtype; + uint32_t anstype; time_t ts; - checkRequestStatus(token, status, reqtype, ts); + checkRequestStatus(token, status, reqtype, anstype, ts); - if (reqtype != (GXS_REQUEST_TYPE_DATA | GXS_REQUEST_TYPE_MSGS | WIKI_REQUEST_MSGS)) + + if (anstype != RS_TOKREQ_ANSTYPE_DATA) { - std::cerr << "p3WikiService::getMsgData() ERROR Type Wrong" << std::endl; + std::cerr << "p3WikiService::getMsgData() ERROR AnsType Wrong" << std::endl; + return false; + } + + if ((reqtype != GXS_REQUEST_TYPE_MSGS) && (reqtype != GXS_REQUEST_TYPE_MSGRELATED)) + { + std::cerr << "p3WikiService::getMsgData() ERROR ReqType Wrong" << std::endl; return false; } @@ -286,247 +313,73 @@ bool p3WikiService::getMsgData(const uint32_t &token, RsWikiPage &page) } std::string id; - if (!popRequestList(token, id)) + if (!popRequestOutList(token, id)) { /* finished */ updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); return false; } - bool ans = InternalgetPage(id, page); + /* convert to RsWikiAlbum */ + bool ans = mWikiProxy->getPage(id, page); return ans; } + + /* Poll */ uint32_t p3WikiService::requestStatus(const uint32_t token) { uint32_t status; uint32_t reqtype; + uint32_t anstype; time_t ts; - checkRequestStatus(token, status, reqtype, ts); + checkRequestStatus(token, status, reqtype, anstype, ts); return status; } - - - -/****************** INTERNALS ***********************/ - - -bool p3WikiService::InternalgetGroupList(std::list &groups) + /* Cancel Request */ +bool p3WikiService::cancelRequest(const uint32_t &token) { - RsStackMutex stack(mWikiMtx); /********** STACK LOCKED MTX ******/ + return clearRequest(token); +} - std::map::iterator it; - for(it = mGroups.begin(); it != mGroups.end(); it++) - { - groups.push_back(it->second.mGroupId); - } - + ////////////////////////////////////////////////////////////////////////////// + /* Functions from Forums -> need to be implemented generically */ +bool p3WikiService::groupsChanged(std::list &groupIds) +{ return false; } -bool p3WikiService::InternalgetGroup(const std::string &groupid, RsWikiGroup &group) + // Get Message Status - is retrived via MessageSummary. +bool p3WikiService::setMessageStatus(const std::string &msgId, const uint32_t status, const uint32_t statusMask) { - RsStackMutex stack(mWikiMtx); /********** STACK LOCKED MTX ******/ - - std::map::iterator it; - it = mGroups.find(groupid); - if (it == mGroups.end()) - { - return false; - } - - group = it->second; - return true; + return false; } - -bool p3WikiService::InternalgetPage(const std::string &pageid, RsWikiPage &page) + // +bool p3WikiService::groupSubscribe(const std::string &groupId, bool subscribe) { - RsStackMutex stack(mWikiMtx); /********** STACK LOCKED MTX ******/ - - std::map::iterator it; - it = mPages.find(pageid); - if (it == mPages.end()) - { - return false; - } - - page = it->second; - return true; + return false; } -bool p3WikiService::InternalgetLatestPage(const std::string &origPageId, std::string &pageId) +bool p3WikiService::groupRestoreKeys(const std::string &groupId) { - RsStackMutex stack(mWikiMtx); /********** STACK LOCKED MTX ******/ - - std::map::iterator it; - it = mOrigPageToLatestPage.find(origPageId); - if (it == mOrigPageToLatestPage.end()) - { - return false; - } - - pageId = it->second; - return true; + return false; +} + +bool p3WikiService::groupShareKeys(const std::string &groupId, std::list& peers) +{ + return false; } -bool p3WikiService::InternalgetPageVersions(const std::string &origPageId, std::list &pageIds) -{ - RsStackMutex stack(mWikiMtx); /********** STACK LOCKED MTX ******/ +/********************************************************************************************/ - std::map >::iterator it; - it = mOrigToPageVersions.find(origPageId); - if (it == mOrigToPageVersions.end()) - { - return false; - } - - std::list::iterator lit; - for(lit = it->second.begin(); lit != it->second.end(); lit++) - { - pageIds.push_back(*lit); - } - return true; -} - - -bool p3WikiService::InternalgetOrigPageList(const std::string &groupid, std::list &pageIds) -{ - RsStackMutex stack(mWikiMtx); /********** STACK LOCKED MTX ******/ - - std::map >::iterator it; - it = mGroupToOrigPages.find(groupid); - if (it == mGroupToOrigPages.end()) - { - return false; - } - - std::list::iterator lit; - for(lit = it->second.begin(); lit != it->second.end(); lit++) - { - pageIds.push_back(*lit); - } - return true; -} - - -/* details are updated in album - to choose Album ID, and storage path */ -bool p3WikiService::createGroup(RsWikiGroup &group) -{ - if (group.mGroupId.empty()) - { - /* new photo */ - - /* generate a temp id */ - group.mGroupId = genRandomId(); - } - else - { - std::cerr << "p3WikiService::createGroup() Group with existing Id... dropping"; - std::cerr << std::endl; - return false; - } - - RsStackMutex stack(mWikiMtx); /********** STACK LOCKED MTX ******/ - - mUpdated = true; - - /* add / modify */ - mGroups[group.mGroupId] = group; - - return true; -} - - - - -bool p3WikiService::createPage(RsWikiPage &page) -{ - if (page.mGroupId.empty()) - { - /* new photo */ - std::cerr << "p3WikiService::createPage() Missing PageID"; - std::cerr << std::endl; - return false; - } - - /* check if its a mod or new page */ - if (page.mOrigPageId.empty()) - { - std::cerr << "p3WikiService::createPage() New Page"; - std::cerr << std::endl; - - /* new page, generate a new OrigPageId */ - page.mOrigPageId = genRandomId(); - page.mPageId = page.mOrigPageId; - } - else - { - std::cerr << "p3WikiService::createPage() Modified Page"; - std::cerr << std::endl; - - /* mod page, keep orig page id, generate a new PageId */ - page.mPageId = genRandomId(); - } - - std::cerr << "p3WikiService::createPage() GroupId: " << page.mGroupId; - std::cerr << std::endl; - std::cerr << "p3WikiService::createPage() PageId: " << page.mPageId; - std::cerr << std::endl; - std::cerr << "p3WikiService::createPage() OrigPageId: " << page.mOrigPageId; - std::cerr << std::endl; - - RsStackMutex stack(mWikiMtx); /********** STACK LOCKED MTX ******/ - - mUpdated = true; - - std::map >::iterator it; - if (page.mPageId == page.mOrigPageId) - { - it = mGroupToOrigPages.find(page.mGroupId); - if (it == mGroupToOrigPages.end()) - { - std::cerr << "p3WikiService::createPage() First Page in Group"; - std::cerr << std::endl; - - std::list emptyList; - mGroupToOrigPages[page.mGroupId] = emptyList; - - it = mGroupToOrigPages.find(page.mGroupId); - } - it->second.push_back(page.mPageId); - } - - - it = mOrigToPageVersions.find(page.mOrigPageId); - if (it == mOrigToPageVersions.end()) - { - std::cerr << "p3WikiService::createPage() Adding OrigPage"; - std::cerr << std::endl; - - std::list emptyList; - mOrigToPageVersions[page.mOrigPageId] = emptyList; - - it = mOrigToPageVersions.find(page.mOrigPageId); - } - /* push back both Orig and all Mods */ - it->second.push_back(page.mPageId); - - /* add / modify */ - mPages[page.mPageId] = page; - - /* Total HACK - but will work for demo */ - mOrigPageToLatestPage[page.mOrigPageId] = page.mPageId; - - return true; -} std::string p3WikiService::genRandomId() { @@ -539,14 +392,176 @@ std::string p3WikiService::genRandomId() return randomId; } +bool p3WikiService::createGroup(RsWikiGroup &group) +{ + if (group.mMeta.mGroupId.empty()) + { + /* new photo */ + + /* generate a temp id */ + group.mMeta.mGroupId = genRandomId(); + } + else + { + std::cerr << "p3WikiService::createGroup() Group with existing Id... dropping"; + std::cerr << std::endl; + return false; + } + + RsStackMutex stack(mWikiMtx); /********** STACK LOCKED MTX ******/ + + mUpdated = true; + + mWikiProxy->addGroup(group); + + return true; +} +bool p3WikiService::createPage(RsWikiPage &page) +{ + if (page.mMeta.mGroupId.empty()) + { + /* new photo */ + std::cerr << "p3WikiService::createPage() Missing PageID"; + std::cerr << std::endl; + return false; + } + + /* check if its a mod or new page */ + if (page.mMeta.mOrigMsgId.empty()) + { + std::cerr << "p3WikiService::createPage() New Page"; + std::cerr << std::endl; + + /* new page, generate a new OrigPageId */ + page.mMeta.mOrigMsgId = genRandomId(); + page.mMeta.mMsgId = page.mMeta.mOrigMsgId; + } + else + { + std::cerr << "p3WikiService::createPage() Modified Page"; + std::cerr << std::endl; + + /* mod page, keep orig page id, generate a new PageId */ + page.mMeta.mMsgId = genRandomId(); + } + + std::cerr << "p3WikiService::createPage() GroupId: " << page.mMeta.mGroupId; + std::cerr << std::endl; + std::cerr << "p3WikiService::createPage() PageId: " << page.mMeta.mMsgId; + std::cerr << std::endl; + std::cerr << "p3WikiService::createPage() OrigPageId: " << page.mMeta.mOrigMsgId; + std::cerr << std::endl; + + RsStackMutex stack(mWikiMtx); /********** STACK LOCKED MTX ******/ + + mUpdated = true; + + mWikiProxy->addPage(page); + + return true; +} +/********************************************************************************************/ + + + +bool WikiDataProxy::getGroup(const std::string &id, RsWikiGroup &group) +{ + void *groupData = NULL; + RsGroupMetaData meta; + if (getGroupData(id, groupData) && getGroupSummary(id, meta)) + { + RsWikiGroup *pG = (RsWikiGroup *) groupData; + group = *pG; + + // update definitive version of the metadata. + group.mMeta = meta; + + std::cerr << "WikiDataProxy::getGroup() Id: " << id; + std::cerr << " MetaData: " << meta << " DataPointer: " << groupData; + std::cerr << std::endl; + return true; + } + + std::cerr << "WikiDataProxy::getGroup() FAILED Id: " << id; + std::cerr << std::endl; + + return false; +} + +bool WikiDataProxy::getPage(const std::string &id, RsWikiPage &page) +{ + void *msgData = NULL; + RsMsgMetaData meta; + if (getMsgData(id, msgData) && getMsgSummary(id, meta)) + { + RsWikiPage *pP = (RsWikiPage *) msgData; + // Shallow copy of thumbnail. + page = *pP; + + // update definitive version of the metadata. + page.mMeta = meta; + + std::cerr << "WikiDataProxy::getPage() Id: " << id; + std::cerr << " MetaData: " << meta << " DataPointer: " << msgData; + std::cerr << std::endl; + return true; + } + + std::cerr << "WikiDataProxy::getPage() FAILED Id: " << id; + std::cerr << std::endl; + + return false; +} + +bool WikiDataProxy::addGroup(const RsWikiGroup &group) +{ + // Make duplicate. + RsWikiGroup *pG = new RsWikiGroup(); + *pG = group; + + std::cerr << "WikiDataProxy::addGroup()"; + std::cerr << " MetaData: " << pG->mMeta << " DataPointer: " << pG; + std::cerr << std::endl; + + return createGroup(pG); +} + + +bool WikiDataProxy::addPage(const RsWikiPage &page) +{ + // Make duplicate. + RsWikiPage *pP = new RsWikiPage(); + *pP = page; + + std::cerr << "WikiDataProxy::addPage()"; + std::cerr << " MetaData: " << pP->mMeta << " DataPointer: " << pP; + std::cerr << std::endl; + + return createMsg(pP); +} + /* These Functions must be overloaded to complete the service */ +bool WikiDataProxy::convertGroupToMetaData(void *groupData, RsGroupMetaData &meta) +{ + RsWikiGroup *group = (RsWikiGroup *) groupData; + meta = group->mMeta; + return true; +} + +bool WikiDataProxy::convertMsgToMetaData(void *msgData, RsMsgMetaData &meta) +{ + RsWikiPage *page = (RsWikiPage *) msgData; + meta = page->mMeta; + + return true; +} diff --git a/libretroshare/src/services/p3wikiservice.h b/libretroshare/src/services/p3wikiservice.h index a9ee93fdc..7d8a3ef0d 100644 --- a/libretroshare/src/services/p3wikiservice.h +++ b/libretroshare/src/services/p3wikiservice.h @@ -27,7 +27,6 @@ #define P3_WIKI_SERVICE_HEADER #include "services/p3gxsservice.h" - #include "retroshare/rswiki.h" #include @@ -48,7 +47,23 @@ * */ -class p3WikiService: public p3GxsService, public RsWiki +class WikiDataProxy: public GxsDataProxy +{ + public: + + bool getGroup(const std::string &id, RsWikiGroup &group); + bool getPage(const std::string &id, RsWikiPage &wiki); + + bool addGroup(const RsWikiGroup &group); + bool addPage(const RsWikiPage &page); + + /* These Functions must be overloaded to complete the service */ +virtual bool convertGroupToMetaData(void *groupData, RsGroupMetaData &meta); +virtual bool convertMsgToMetaData(void *msgData, RsMsgMetaData &meta); +}; + + +class p3WikiService: public p3GxsDataService, public RsWiki { public: @@ -61,66 +76,57 @@ virtual int tick(); virtual bool updated(); - /* Data Requests */ -virtual bool requestGroupList( uint32_t &token, const RsTokReqOptions &opts); -virtual bool requestMsgList( uint32_t &token, const RsTokReqOptions &opts, const std::list &groupIds); -virtual bool requestMsgRelatedList(uint32_t &token, const RsTokReqOptions &opts, const std::list &msgIds); + /* 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); -virtual bool requestGroupData( uint32_t &token, const std::list &groupIds); -virtual bool requestMsgData( uint32_t &token, 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); -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 getGroupData(const uint32_t &token, RsWikiGroup &group); virtual bool getMsgData(const uint32_t &token, RsWikiPage &page); /* Poll */ virtual uint32_t requestStatus(const uint32_t token); -virtual bool createGroup(RsWikiGroup &group); -virtual bool createPage(RsWikiPage &page); + /* Cancel Request */ +virtual bool cancelRequest(const uint32_t &token); + ////////////////////////////////////////////////////////////////////////////// + /* Functions from Forums -> need to be implemented generically */ +virtual bool groupsChanged(std::list &groupIds); -/************* Old Extern Interface *******/ -#if 0 + // Get Message Status - is retrived via MessageSummary. +virtual bool setMessageStatus(const std::string &msgId, const uint32_t status, const uint32_t statusMask); -virtual bool updated(); -virtual bool getGroupList(std::list &group); + // +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); -virtual bool getGroup(const std::string &groupid, RsWikiGroup &group); -virtual bool getPage(const std::string &pageid, RsWikiPage &page); -virtual bool getPageVersions(const std::string &origPageId, std::list &pages); -virtual bool getOrigPageList(const std::string &groupid, std::list &pageIds); -virtual bool getLatestPage(const std::string &origPageId, std::string &page); virtual bool createGroup(RsWikiGroup &group); virtual bool createPage(RsWikiPage &page); -#endif - private: -virtual bool InternalgetGroupList(std::list &group); -virtual bool InternalgetGroup(const std::string &groupid, RsWikiGroup &group); -virtual bool InternalgetPage(const std::string &pageid, RsWikiPage &page); -virtual bool InternalgetPageVersions(const std::string &origPageId, std::list &pages); -virtual bool InternalgetOrigPageList(const std::string &groupid, std::list &pageIds); -virtual bool InternalgetLatestPage(const std::string &origPageId, std::string &page); - std::string genRandomId(); + WikiDataProxy *mWikiProxy; + RsMutex mWikiMtx; - /***** below here is locked *****/ - bool mUpdated; - std::map > mGroupToOrigPages; - std::map > mOrigToPageVersions; - std::map mOrigPageToLatestPage; - std::map mGroups; - std::map mPages; }; diff --git a/libretroshare/src/services/p3wire.cc b/libretroshare/src/services/p3wire.cc new file mode 100644 index 000000000..cf849187e --- /dev/null +++ b/libretroshare/src/services/p3wire.cc @@ -0,0 +1,567 @@ +/* + * libretroshare/src/services p3wire.cc + * + * Wire 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/p3wire.h" + +#include "util/rsrandom.h" + +/**** + * #define WIKI_DEBUG 1 + ****/ + +RsWire *rsWire = NULL; + + +/********************************************************************************/ +/******************* Startup / Tick ******************************************/ +/********************************************************************************/ + +p3Wire::p3Wire(uint16_t type) + :p3GxsDataService(type, new WireDataProxy()), mWireMtx("p3Wire"), mUpdated(true) +{ + RsStackMutex stack(mWireMtx); /********** STACK LOCKED MTX ******/ + + mWireProxy = (WireDataProxy *) mProxy; + return; +} + + +int p3Wire::tick() +{ + std::cerr << "p3Wire::tick()"; + std::cerr << std::endl; + + fakeprocessrequests(); + + return 0; +} + +bool p3Wire::updated() +{ + RsStackMutex stack(mWireMtx); /********** STACK LOCKED MTX ******/ + + if (mUpdated) + { + mUpdated = false; + return true; + } + return false; +} + + + + /* Data Requests */ +bool p3Wire::requestGroupInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &groupIds) +{ + generateToken(token); + std::cerr << "p3Wire::requestGroupInfo() gets Token: " << token << std::endl; + storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_GROUPS, groupIds); + + return true; +} + +bool p3Wire::requestMsgInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &groupIds) +{ + generateToken(token); + std::cerr << "p3Wire::requestMsgInfo() gets Token: " << token << std::endl; + storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_MSGS, groupIds); + + return true; +} + +bool p3Wire::requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &msgIds) +{ + generateToken(token); + std::cerr << "p3Wire::requestMsgRelatedInfo() gets Token: " << token << std::endl; + storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_MSGRELATED, msgIds); + + return true; +} + + /* Generic Lists */ +bool p3Wire::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 << "p3Wire::getGroupList() ERROR AnsType Wrong" << std::endl; + return false; + } + + if (reqtype != GXS_REQUEST_TYPE_GROUPS) + { + std::cerr << "p3Wire::getGroupList() ERROR ReqType Wrong" << std::endl; + return false; + } + + if (status != GXS_REQUEST_STATUS_COMPLETE) + { + std::cerr << "p3Wire::getGroupList() ERROR Status Incomplete" << std::endl; + return false; + } + + bool ans = loadRequestOutList(token, groupIds); + updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); + + return ans; +} + + + + +bool p3Wire::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 << "p3Wire::getMsgList() ERROR AnsType Wrong" << std::endl; + return false; + } + + if ((reqtype != GXS_REQUEST_TYPE_MSGS) && (reqtype != GXS_REQUEST_TYPE_MSGRELATED)) + { + std::cerr << "p3Wire::getMsgList() ERROR ReqType Wrong" << std::endl; + return false; + } + + if (status != GXS_REQUEST_STATUS_COMPLETE) + { + std::cerr << "p3Wire::getMsgList() ERROR Status Incomplete" << std::endl; + return false; + } + + bool ans = loadRequestOutList(token, msgIds); + updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); + + return ans; +} + + + /* Generic Summary */ +bool p3Wire::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 << "p3Wire::getGroupSummary() ERROR AnsType Wrong" << std::endl; + return false; + } + + if (reqtype != GXS_REQUEST_TYPE_GROUPS) + { + std::cerr << "p3Wire::getGroupSummary() ERROR ReqType Wrong" << std::endl; + return false; + } + + if (status != GXS_REQUEST_STATUS_COMPLETE) + { + std::cerr << "p3Wire::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 p3Wire::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 << "p3Wire::getMsgSummary() ERROR AnsType Wrong" << std::endl; + return false; + } + + if ((reqtype != GXS_REQUEST_TYPE_MSGS) && (reqtype != GXS_REQUEST_TYPE_MSGRELATED)) + { + std::cerr << "p3Wire::getMsgSummary() ERROR ReqType Wrong" << std::endl; + return false; + } + + if (status != GXS_REQUEST_STATUS_COMPLETE) + { + std::cerr << "p3Wire::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 p3Wire::getGroupData(const uint32_t &token, RsWireGroup &group) +{ + 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 << "p3Wire::getGroupData() ERROR AnsType Wrong" << std::endl; + return false; + } + + if (reqtype != GXS_REQUEST_TYPE_GROUPS) + { + std::cerr << "p3Wire::getGroupData() ERROR ReqType Wrong" << std::endl; + return false; + } + + if (status != GXS_REQUEST_STATUS_COMPLETE) + { + std::cerr << "p3Wire::getGroupData() 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 RsWireGroup */ + bool ans = mWireProxy->getGroup(id, group); + return ans; +} + + +bool p3Wire::getMsgData(const uint32_t &token, RsWirePulse &pulse) +{ + 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 << "p3Wire::getMsgData() ERROR AnsType Wrong" << std::endl; + return false; + } + + if ((reqtype != GXS_REQUEST_TYPE_MSGS) && (reqtype != GXS_REQUEST_TYPE_MSGRELATED)) + { + std::cerr << "p3Wire::getMsgData() ERROR ReqType Wrong" << std::endl; + return false; + } + + if (status != GXS_REQUEST_STATUS_COMPLETE) + { + std::cerr << "p3Wire::getMsgData() 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 RsWirePulse */ + bool ans = mWireProxy->getPulse(id, pulse); + return ans; +} + + + + /* Poll */ +uint32_t p3Wire::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 p3Wire::cancelRequest(const uint32_t &token) +{ + return clearRequest(token); +} + + ////////////////////////////////////////////////////////////////////////////// + /* Functions from Forums -> need to be implemented generically */ +bool p3Wire::groupsChanged(std::list &groupIds) +{ + return false; +} + + // Get Message Status - is retrived via MessageSummary. +bool p3Wire::setMessageStatus(const std::string &msgId, const uint32_t status, const uint32_t statusMask) +{ + return false; +} + + + // +bool p3Wire::groupSubscribe(const std::string &groupId, bool subscribe) +{ + return false; +} + + +bool p3Wire::groupRestoreKeys(const std::string &groupId) +{ + return false; +} + +bool p3Wire::groupShareKeys(const std::string &groupId, std::list& peers) +{ + return false; +} + + +/********************************************************************************************/ + + +std::string p3Wire::genRandomId() +{ + std::string randomId; + for(int i = 0; i < 20; i++) + { + randomId += (char) ('a' + (RSRandom::random_u32() % 26)); + } + + return randomId; +} + +bool p3Wire::createGroup(RsWireGroup &group) +{ + if (group.mMeta.mGroupId.empty()) + { + /* new photo */ + + /* generate a temp id */ + group.mMeta.mGroupId = genRandomId(); + } + else + { + std::cerr << "p3Wire::createGroup() Group with existing Id... dropping"; + std::cerr << std::endl; + return false; + } + + RsStackMutex stack(mWireMtx); /********** STACK LOCKED MTX ******/ + + mUpdated = true; + + mWireProxy->addGroup(group); + + return true; +} + + + + +bool p3Wire::createPulse(RsWirePulse &pulse) +{ + if (pulse.mMeta.mGroupId.empty()) + { + /* new photo */ + std::cerr << "p3Wire::createPulse() Missing PulseID"; + std::cerr << std::endl; + return false; + } + + /* check if its a mod or new pulse */ + if (pulse.mMeta.mOrigMsgId.empty()) + { + std::cerr << "p3Wire::createPulse() New Pulse"; + std::cerr << std::endl; + + /* new pulse, generate a new OrigPulseId */ + pulse.mMeta.mOrigMsgId = genRandomId(); + pulse.mMeta.mMsgId = pulse.mMeta.mOrigMsgId; + } + else + { + std::cerr << "p3Wire::createPulse() Modified Pulse"; + std::cerr << std::endl; + + /* mod pulse, keep orig pulse id, generate a new PulseId */ + pulse.mMeta.mMsgId = genRandomId(); + } + + std::cerr << "p3Wire::createPulse() GroupId: " << pulse.mMeta.mGroupId; + std::cerr << std::endl; + std::cerr << "p3Wire::createPulse() PulseId: " << pulse.mMeta.mMsgId; + std::cerr << std::endl; + std::cerr << "p3Wire::createPulse() OrigPulseId: " << pulse.mMeta.mOrigMsgId; + std::cerr << std::endl; + + RsStackMutex stack(mWireMtx); /********** STACK LOCKED MTX ******/ + + mUpdated = true; + + mWireProxy->addPulse(pulse); + + return true; +} + + + +/********************************************************************************************/ + + + +bool WireDataProxy::getGroup(const std::string &id, RsWireGroup &group) +{ + void *groupData = NULL; + RsGroupMetaData meta; + if (getGroupData(id, groupData) && getGroupSummary(id, meta)) + { + RsWireGroup *pG = (RsWireGroup *) groupData; + group = *pG; + + // update definitive version of the metadata. + group.mMeta = meta; + + std::cerr << "WireDataProxy::getGroup() Id: " << id; + std::cerr << " MetaData: " << meta << " DataPointer: " << groupData; + std::cerr << std::endl; + return true; + } + + std::cerr << "WireDataProxy::getGroup() FAILED Id: " << id; + std::cerr << std::endl; + + return false; +} + +bool WireDataProxy::getPulse(const std::string &id, RsWirePulse &pulse) +{ + void *msgData = NULL; + RsMsgMetaData meta; + if (getMsgData(id, msgData) && getMsgSummary(id, meta)) + { + RsWirePulse *pP = (RsWirePulse *) msgData; + // Shallow copy of thumbnail. + pulse = *pP; + + // update definitive version of the metadata. + pulse.mMeta = meta; + + std::cerr << "WireDataProxy::getPulse() Id: " << id; + std::cerr << " MetaData: " << meta << " DataPointer: " << msgData; + std::cerr << std::endl; + return true; + } + + std::cerr << "WireDataProxy::getPulse() FAILED Id: " << id; + std::cerr << std::endl; + + return false; +} + +bool WireDataProxy::addGroup(const RsWireGroup &group) +{ + // Make duplicate. + RsWireGroup *pG = new RsWireGroup(); + *pG = group; + + std::cerr << "WireDataProxy::addGroup()"; + std::cerr << " MetaData: " << pG->mMeta << " DataPointer: " << pG; + std::cerr << std::endl; + + return createGroup(pG); +} + + +bool WireDataProxy::addPulse(const RsWirePulse &pulse) +{ + // Make duplicate. + RsWirePulse *pP = new RsWirePulse(); + *pP = pulse; + + std::cerr << "WireDataProxy::addPulse()"; + std::cerr << " MetaData: " << pP->mMeta << " DataPointer: " << pP; + std::cerr << std::endl; + + return createMsg(pP); +} + + + + /* These Functions must be overloaded to complete the service */ +bool WireDataProxy::convertGroupToMetaData(void *groupData, RsGroupMetaData &meta) +{ + RsWireGroup *group = (RsWireGroup *) groupData; + meta = group->mMeta; + + return true; +} + +bool WireDataProxy::convertMsgToMetaData(void *msgData, RsMsgMetaData &meta) +{ + RsWirePulse *page = (RsWirePulse *) msgData; + meta = page->mMeta; + + return true; +} diff --git a/libretroshare/src/services/p3wire.h b/libretroshare/src/services/p3wire.h new file mode 100644 index 000000000..36d46f0ea --- /dev/null +++ b/libretroshare/src/services/p3wire.h @@ -0,0 +1,125 @@ +/* + * libretroshare/src/services: p3wire.h + * + * Wire 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_WIRE_SERVICE_HEADER +#define P3_WIRE_SERVICE_HEADER + +#include "services/p3gxsservice.h" + +#include "retroshare/rswire.h" + +#include +#include + +/* + * Wire Service + * + */ +class WireDataProxy: public GxsDataProxy +{ + public: + + bool getGroup(const std::string &id, RsWireGroup &group); + bool getPulse(const std::string &id, RsWirePulse &pulse); + + bool addGroup(const RsWireGroup &group); + bool addPulse(const RsWirePulse &pulse); + + /* These Functions must be overloaded to complete the service */ +virtual bool convertGroupToMetaData(void *groupData, RsGroupMetaData &meta); +virtual bool convertMsgToMetaData(void *msgData, RsMsgMetaData &meta); +}; + + +class p3Wire: public p3GxsDataService, public RsWire +{ + public: + + p3Wire(uint16_t type); + +virtual int tick(); + + public: + + +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 getGroupData(const uint32_t &token, RsWireGroup &group); +virtual bool getMsgData(const uint32_t &token, RsWirePulse &page); + + /* 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); + + +virtual bool createGroup(RsWireGroup &group); +virtual bool createPulse(RsWirePulse &pulse); + + + private: + +std::string genRandomId(); + + WireDataProxy *mWireProxy; + + RsMutex mWireMtx; + + /***** below here is locked *****/ + + bool mUpdated; + +}; + +#endif