mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-02-17 13:24:15 -05:00
added more virtual methods to network exchange service
removed xml parser utility removed extraneous info from retrodb git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-new_cache_system@5073 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
parent
030b009f9a
commit
e560e00029
@ -11,48 +11,41 @@ Please not all request* functions have a receive pair if not noted below
|
|||||||
1.1) Display of subscribed forums. Service must provide:
|
1.1) Display of subscribed forums. Service must provide:
|
||||||
1.1.1) list of subscribed Groups.
|
1.1.1) list of subscribed Groups.
|
||||||
----------------
|
----------------
|
||||||
int GXService::requestSubscribedGroupList(); @return token
|
int requestSubscribedGrps();
|
||||||
void receiveGroupList(token, list<grpId>); //call back
|
|
||||||
|
|
||||||
-> This function will get the group list from
|
|
||||||
Component:
|
Component:
|
||||||
GDService::requestGroup()
|
RsGnp::requestGroups()
|
||||||
|
|
||||||
|
|
||||||
->
|
|
||||||
----------------
|
----------------
|
||||||
1.1.2) list of messages for each Group.
|
1.1.2) list of messages for each Group.
|
||||||
----------------
|
----------------
|
||||||
int GDService::requestGroupMsgs(std::string grpId); @return token
|
int requestGrpMsgs(std::list<RsGxsGrpId>&);
|
||||||
-> Return a request token that will be redeemed by:
|
|
||||||
void receiveMsgs(int token, std::list<RsGxsMsg*>); // call back
|
|
||||||
Component:
|
|
||||||
GDService::request(string grpId) X
|
|
||||||
-> which further uses the client service's implemented
|
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
1.1.3) details of group by group Id.
|
1.1.3) details of group by group Id.
|
||||||
----------------
|
----------------
|
||||||
int GDService::requestGroup(std::string grpId);
|
int requestGrp(std::list<RsGxsGrpId>& grpIds);
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
1.1.4) details of messages by message Id.
|
1.1.4) details of messages by message Id.
|
||||||
----------------
|
----------------
|
||||||
int GXService::requestMessages(multimap<grpId, pair<msgId,version> >)
|
int requestMsgs(std::list<RsGxsMsgId>& msgs);
|
||||||
void receiveMsgs(int token, std::list<RsGxsMsg*>); // call back
|
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
1.1.5) newest version of each message -> get version list.
|
1.1.5) newest version of each message
|
||||||
|
|
||||||
----------------
|
----------------
|
||||||
? newest version returned by default
|
1.1.4 : not intitialising RsGxsMsgId::version default to returning
|
||||||
int GDService::requestMsgVersions(multimap<grpId, msgId>)
|
newest version of message
|
||||||
int receiveMsgVersionList(list<uint32_t>)
|
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
1.1.6) status of message (read / unread).
|
1.1.6) status of message (read / unread).
|
||||||
|
|
||||||
----------------
|
----------------
|
||||||
returned with msgs see 1.1.2 & 1.1.3
|
returned with msg data
|
||||||
|
int flagMsgRead(const RsGxsMsgId& msgId, bool read)
|
||||||
|
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
1.1.7) access to Identity associated with Group and Messages
|
1.1.7) access to Identity associated with Group and Messages
|
||||||
@ -64,27 +57,24 @@ Please not all request* functions have a receive pair if not noted below
|
|||||||
1.1.8) updates when new groups arrive.
|
1.1.8) updates when new groups arrive.
|
||||||
|
|
||||||
----------------
|
----------------
|
||||||
int receivedNewGrp(list<string> grpIds)
|
virtual void notifyGroupChanged(std::list<RsGxsGrpId> grpId) = 0
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
1.1.9) updates when new messages arrive.
|
1.1.9) updates when new messages arrive.
|
||||||
----------------
|
----------------
|
||||||
int receivedNewMsgs(multimap<grpId, pair<msgId,version> >)
|
virtual void notifyMsgChanged(std::list<RsGxsMsgId> msgId) = 0
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
1.1.10) updates when groups / messages change.
|
1.1.10) updates when groups / messages change.
|
||||||
|
|
||||||
----------------
|
----------------
|
||||||
int receivedNewUpdates(multimap<grpId, pair<msgId,version> >)
|
1.1.8 and 1.1.9
|
||||||
int receivedNewUpdates(map<grpId, version> >)
|
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
1.1.11) Search forums for Keywords.
|
1.1.11) Search forums for Keywords.
|
||||||
|
|
||||||
----------------
|
----------------
|
||||||
int searchForum(string keyword, grpId)
|
int requestLocalSearch(RsGxsSearch* term);
|
||||||
// all msgs and grps that contain keyword
|
|
||||||
int receiveSearchResult(list<RsGxsMsg*>, list<RsGxsGrp*>)
|
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
1.1.12) Access new (time restricted) messages.
|
1.1.12) Access new (time restricted) messages.
|
||||||
@ -96,30 +86,29 @@ Please not all request* functions have a receive pair if not noted below
|
|||||||
1.2.1) ability to create Groups.
|
1.2.1) ability to create Groups.
|
||||||
|
|
||||||
----------------
|
----------------
|
||||||
GDService::createGroup(name, descrip, title, thumbnail);
|
int pushGrp(std::set<RsGxsGroup*>& grp, std::string& profileName);
|
||||||
//or rather user
|
int pushGrp(std::set<RsGxsGroup*>& grp, RsIdentityExchangeService::IdentityType type, const std::set<std::string>& peers,
|
||||||
|
const std::string& pseudonymName = "");
|
||||||
|
|
||||||
// user needs to instantiate their top class members
|
|
||||||
// where RsGxpGrp is base class
|
|
||||||
// user provides identity to associate group to
|
|
||||||
bool GDService::publishGroup(const RsGxsGrp&, identity);
|
|
||||||
RsGixsProfile* GXIService::createIdentity(int type, string pseudonym);
|
|
||||||
RsGixsProfile* GXIService::getRealIdentity();
|
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
1.2.2) ability to create Messages.
|
1.2.2) ability to create Messages.
|
||||||
|
|
||||||
GXService::publishMsg(const RsGxsMsg&, identity);
|
void pushMsg(std::set<RsGxsMsg*>& msg);
|
||||||
|
|
||||||
1.3) Deletion of forums and posts.
|
1.3) Deletion of forums and posts.
|
||||||
1.3.1) discard forum (can't do this currently).
|
1.3.1) discard forum (can't do this currently).
|
||||||
|
----------------
|
||||||
|
done automatically by GDService based on cutoff
|
||||||
|
----------------
|
||||||
|
|
||||||
1.3.2) delete post.
|
1.3.2) delete post.
|
||||||
----------------
|
----------------
|
||||||
// post is removed from system and note made in db not to syn it
|
// post is removed from system and note made in db not to syn it
|
||||||
// this is cleaned from db after grp expires
|
// this is cleaned from db post expires
|
||||||
int GXService::deleteMsg(multimap<grpId, msgId >)
|
// very likely to also propagate to friends
|
||||||
int GXService::deleteGrp(grpId)
|
int requestDeleteMsg(const RsGxsMsgId& msgId);
|
||||||
|
int requestDeleteGrp(const RsGxsGrpId& grpId);
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
1.3.3) discard old posts.
|
1.3.3) discard old posts.
|
||||||
@ -132,13 +121,13 @@ Please not all request* functions have a receive pair if not noted below
|
|||||||
1.4.1) Storage Period of subscribed forums
|
1.4.1) Storage Period of subscribed forums
|
||||||
|
|
||||||
----------------
|
----------------
|
||||||
int GXService::setSubscribedGrpsCutOff(uint32_t secs)
|
void setSubscribedGroupDiscardAge(uint32_t length);
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
1.4.2) Storage Period of unsubscribed forums.
|
1.4.2) Storage Period of unsubscribed forums.
|
||||||
|
|
||||||
----------------
|
----------------
|
||||||
int GXService::setUnSubscribedGrpsCutOff(uint32_t secs)
|
void setUnsubscribedGrpDiscardAge(uint32_t length);
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
1.4.3) transfer unsubscribed forums and posts (yes/no)
|
1.4.3) transfer unsubscribed forums and posts (yes/no)
|
||||||
@ -161,12 +150,12 @@ Please not all request* functions have a receive pair if not noted below
|
|||||||
1.4.5) modify read status.
|
1.4.5) modify read status.
|
||||||
|
|
||||||
----------------
|
----------------
|
||||||
int GXService::setMsgRead(multimap<grpId, version> >)
|
int flagMsgRead(const RsGxsMsgId& msgId, bool read) ;
|
||||||
----------------
|
----------------
|
||||||
1.4.6) Subscribe to forums
|
1.4.6) Subscribe to forums
|
||||||
|
|
||||||
----------------
|
----------------
|
||||||
bool GXService::subscribeToGroup(grpId)
|
int requestSubscribeToGrp(const RsGxsGrpId& grpId, bool subscribe);
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
1.5) Finding other forums.
|
1.5) Finding other forums.
|
||||||
@ -180,13 +169,12 @@ Please not all request* functions have a receive pair if not noted below
|
|||||||
// service will have to provide own search module (can RsGDService can
|
// service will have to provide own search module (can RsGDService can
|
||||||
// service remote search requests concurrent with GXS)
|
// service remote search requests concurrent with GXS)
|
||||||
// module return message and groups (msgs can be marked compile time as not // searchable
|
// module return message and groups (msgs can be marked compile time as not // searchable
|
||||||
GXService::localSearch(RsGxsSearch key)
|
int requestRemoteSearch(RsGxsSearch* term, uint32_t hops);
|
||||||
GXService::searchRemote(RsGxsSearch key)
|
|
||||||
----------------
|
----------------
|
||||||
1.5.4) optional download of friends forums.
|
1.5.4) optional download of friends forums.
|
||||||
----------------
|
----------------
|
||||||
int GXService::downloadPeersGroups(sslid)
|
int requestPeersGrps(const std::string& sslId);
|
||||||
int GXService::downloadPeersMessage(ssld, grpId)
|
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
|
|
||||||
@ -202,18 +190,20 @@ Please not all request* functions have a receive pair if not noted below
|
|||||||
2.2) Comments
|
2.2) Comments
|
||||||
2.2.1) Write a comment.
|
2.2.1) Write a comment.
|
||||||
----------------
|
----------------
|
||||||
see 1.2.2. Message with required top level members
|
see 1.2.2. RsGxsMsg with required indirection data members
|
||||||
|
to associate with message the comment is being made on
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
2.2.2) Reject (downgrade) bad comment.
|
2.2.2) Reject (downgrade) bad comment.
|
||||||
----------------
|
----------------
|
||||||
user just needs to verify publisher sent message
|
user needs to verify publisher sent downgrage message
|
||||||
bool GIXService::verify(Identity, data, dataLen, signature)
|
bool RsGxis::bool verify(const KeyRef& keyref, unsigned char* data, uint32_t dataLen, std::string& signature);
|
||||||
|
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
2.2.3) Control Comments: Allow / Disallow, Pseudo / Authed Comments.
|
2.2.3) Control Comments: Allow / Disallow, Pseudo / Authed Comments.
|
||||||
----------------
|
----------------
|
||||||
bool GIXService::verify(Identity, data, dataLen, signature)
|
bool RsGxis::bool sign(const KeyRef& keyref, unsigned char* data, uint32_t dataLen, std::string& signature);
|
||||||
|
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
@ -230,7 +220,7 @@ Please not all request* functions have a receive pair if not noted below
|
|||||||
3.1.2) Access to Version History. (including who edited).
|
3.1.2) Access to Version History. (including who edited).
|
||||||
|
|
||||||
----------------
|
----------------
|
||||||
// need to include list<authors> as top level RsGxsMsg
|
// need to include std::map<version,authors> as top level RsGxsMsg
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
3.2) Controlling Editing Rights.
|
3.2) Controlling Editing Rights.
|
||||||
@ -267,6 +257,7 @@ using 1.2.2, publisher sends new publish key under old private key signature, an
|
|||||||
----------------
|
----------------
|
||||||
Bit more detail on search type
|
Bit more detail on search type
|
||||||
RsGxsSearch{ int searchType; const int PATTERN_TYPE, TERM_TYPE; ....}
|
RsGxsSearch{ int searchType; const int PATTERN_TYPE, TERM_TYPE; ....}
|
||||||
|
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
|
|
||||||
|
@ -33,10 +33,28 @@
|
|||||||
#include "inttypes.h"
|
#include "inttypes.h"
|
||||||
#include "rsgnp.h"
|
#include "rsgnp.h"
|
||||||
|
|
||||||
typedef std::map<std::string, std::set<std::string> > MsgGrpId;
|
#include "gxs/rsgxs.h"
|
||||||
typedef std::map<std::string, std::set<RsGxsSignedMessage*> > SignedMsgGrp;
|
|
||||||
|
|
||||||
|
|
||||||
|
class RsGxsSignedMsg {
|
||||||
|
|
||||||
|
|
||||||
|
RsGxsMsgId mMsgId;
|
||||||
|
RsTlvBinaryData mMsgData;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Might be better off simply sending request codes
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class RsGxsSearch {
|
||||||
|
|
||||||
|
/*!
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
virtual int code() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* The main role of GDS is the preparation and handing out of messages requested from
|
* The main role of GDS is the preparation and handing out of messages requested from
|
||||||
* RsGeneralExchangeService and RsGeneralExchangeService
|
* RsGeneralExchangeService and RsGeneralExchangeService
|
||||||
@ -56,158 +74,100 @@ typedef std::map<std::string, std::set<RsGxsSignedMessage*> > SignedMsgGrp;
|
|||||||
* - As this is the point where data is accessed by both the GNP and GXS the identities
|
* - As this is the point where data is accessed by both the GNP and GXS the identities
|
||||||
* used to decrypt, encrypt and verify is handle here.
|
* used to decrypt, encrypt and verify is handle here.
|
||||||
*
|
*
|
||||||
*
|
* Please note all function are blocking.
|
||||||
*/
|
*/
|
||||||
class RsGeneralDataService
|
class RsGeneralDataService
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Retrieves signed message
|
||||||
|
* @param msgGrp this contains grp and the message to retrieve
|
||||||
|
* @return error code
|
||||||
|
*/
|
||||||
|
virtual int retrieveMsgs(const std::list<RsGxsMsgId>& msgId, std::set<RsGxsMsg*> msg, bool cache) = 0;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Retrieves a group item by grpId
|
||||||
|
* @param grpId the ID of the group to retrieve
|
||||||
|
* @return error code
|
||||||
|
*/
|
||||||
|
virtual int retrieveGrps(const std::list<RsGxsGrpId>& grpId, std::set<RsGxsGroup*> grp, bool cache) = 0;
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* allows for more complex queries specific to the service
|
||||||
|
* BLOBs type columns will not be searched
|
||||||
|
* @param search generally stores parameters needed for query
|
||||||
|
* @param msgId is set with msg ids which satisfy the gxs search
|
||||||
|
* @return error code
|
||||||
|
*/
|
||||||
|
virtual int searchMsgs(RsGxsSearch* search, std::list<RsMsgId>& msgId) = 0;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* allows for more complex queries specific to the associated service
|
||||||
|
* BLOBs type columns will not be searched
|
||||||
|
* @param search generally stores parameters needed for query
|
||||||
|
* @param msgId is set with msg ids which satisfy the gxs search
|
||||||
|
* @return error code
|
||||||
|
*/
|
||||||
|
virtual int searchGrps(RsGxsSearch* search, std::list<RsGroupId>& grpId) = 0;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @return the cache size set for this RsGeneralDataService
|
||||||
|
*/
|
||||||
|
virtual uint32_t cacheSize() const;
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Stores a list signed messages into data store
|
||||||
|
* @param msg list of signed messages to store
|
||||||
|
* @return error code
|
||||||
|
*/
|
||||||
|
virtual int storeMessage(std::set<RsGxsSignedMsg*> msg) = 0;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Stores a list of groups in data store
|
||||||
|
* @param msg list of messages
|
||||||
|
* @return error code
|
||||||
|
*/
|
||||||
|
virtual int storeGroup(std::set<RsGxsGroup*> grp) = 0;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Retrieves group ids
|
||||||
|
* @param grpIds
|
||||||
|
*/
|
||||||
|
virtual void retrieveGrpIds(std::list<std::string>& grpIds) = 0;
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Retrieves msg ids
|
||||||
|
*/
|
||||||
|
virtual void retrieveMsgIds(std::list<std::string>& msgIds) = 0;
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Retrieves signed message
|
* Retrieves signed message
|
||||||
* @param msgGrp this contains grp and the message to retrieve
|
* @param msgGrp this contains grp and the message to retrieve
|
||||||
* @return request code to be redeemed later
|
* @return request code to be redeemed later
|
||||||
*/
|
*/
|
||||||
virtual int request(const MsgGrpId& msgGrp) = 0;
|
virtual int retrieveMsgs(const std::list<RsGxsMsgId>& msgId, std::set<RsGxsMsg*> msg) = 0;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Retrieves a group item by grpId
|
* Retrieves a group item by grpId
|
||||||
* @param grpId the ID of the group to retrieve
|
* @param grpId the ID of the group to retrieve
|
||||||
* @return request code to be redeemed later
|
* @return request code to be redeemed later
|
||||||
*/
|
*/
|
||||||
virtual int request(const std::string grpId) = 0;
|
virtual int retrieveGrps(const std::list<RsGxsGrpId>& grpId, std::set<RsGxsGroup*> grp) = 0;
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* allows for more complex queries specific to the service
|
|
||||||
* Service should implement its own specific filter
|
|
||||||
* @param filter generally stores parameters needed for query
|
|
||||||
* @param cacheRequest set to true to cache the messages requested
|
|
||||||
* @return request code to be redeemed later
|
|
||||||
*/
|
|
||||||
virtual int request(RsGxsSearch* filter, bool cacheRequest) = 0;
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* stores signed message
|
|
||||||
* @param msgs signed messages to store
|
|
||||||
*/
|
|
||||||
virtual bool store(SignedMsgGrp& msgs) = 0;
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Gets group and any associated meta data
|
|
||||||
* @param grpIds set with group Ids available from storage
|
|
||||||
* @return request code to be redeemed later
|
|
||||||
*/
|
|
||||||
virtual int getGroups(const std::set<std::string>& grpIds) = 0;
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Gets list of message ids in storage
|
|
||||||
* @param msgIds gets message ids in storage
|
|
||||||
* @return request code to be redeemed later
|
|
||||||
*/
|
|
||||||
virtual int getMessageIds(std::set<std::string>& msgIds) = 0;
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* caches message for faster retrieval later
|
|
||||||
* @return false if caching failed, msg may not exist, false otherwise
|
|
||||||
*/
|
|
||||||
virtual bool cacheMsg(const std::string& grpId, const std::string& msgId) = 0;
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* caches all messages of this grpId for faster retrieval later
|
|
||||||
* @param grpId all message of this grpId are cached
|
|
||||||
* @return false if caching failed, msg may not exist, false otherwise
|
|
||||||
*/
|
|
||||||
bool cacheGrp(const std::string& grpId) = 0;
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* checks if msg is cached
|
|
||||||
* @param msgId message to check if cached
|
|
||||||
* @param grpId
|
|
||||||
* @return false if caching failed, msg may not exist, false otherwise
|
|
||||||
*/
|
|
||||||
bool msgCached(const std::string& grpId, const std::string& msgId) = 0;
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* check if messages of the grpId are cached
|
|
||||||
* @param grpId all message of this grpId are checked
|
|
||||||
* @return false if caching failed, msg may not exist, false otherwise
|
|
||||||
*/
|
|
||||||
bool grpCached(const std::string& grpId) = 0;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Might be better off simply sending request codes
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
class RsGxsSearch {
|
|
||||||
|
|
||||||
/*!
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
virtual int code() = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*!
|
|
||||||
*
|
|
||||||
* This is implemented by the concrete GXS class to represent and define how \n
|
|
||||||
* RsGxsSignedMessage is stored and retrieved from disk \n
|
|
||||||
* More complicated queries are enabled through the use of \n
|
|
||||||
* RequestFilter which through rtti store generic parameters used by the RsGeneralStorageService implementation \n
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* The main reason for layering RsGeneralDataService between this and RsGeneralExchangeService implementer \n
|
|
||||||
* is to avoid the overhead of storage access and while allowing a rich variety of implementations not having to \n
|
|
||||||
* worry about efficiency \n
|
|
||||||
*/
|
|
||||||
class RsGeneralStorageService {
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Retrieves signed messages from storage
|
|
||||||
* @param msgGrp this contains grp and the message to retrieve
|
|
||||||
*/
|
|
||||||
virtual void retrieve(const MsgGrpId& msgGrp, SignedMsgGrp& result, bool decrypted) = 0;
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* allows for more complex queries specific to the service
|
|
||||||
* Service should implement method taking case
|
|
||||||
* @param filter
|
|
||||||
*/
|
|
||||||
virtual void retrieve(RsGxsSearch* search, SignedMsgGrp& msgs) = 0;
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* stores signed message in internal storage
|
|
||||||
* @param msgs signed messages to store
|
|
||||||
*/
|
|
||||||
virtual void store(SignedMsgGrp& msgs) = 0;
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* retrieves the group ids from storage
|
|
||||||
* @param grpIds set with grpIds available from storage
|
|
||||||
*/
|
|
||||||
virtual void getGroups(std::set<std::string>& grpIds) = 0;
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* retrieve message in this stored in this storage
|
|
||||||
* @param msgIds gets message ids in storage
|
|
||||||
*/
|
|
||||||
virtual bool getMessageIds(std::set<std::string>& msgIds) = 0;
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Use this find out if Rss i/o status
|
|
||||||
* @return the io status
|
|
||||||
*/
|
|
||||||
virtual uint8_t getIoStat() = 0;
|
|
||||||
|
|
||||||
static uint8_t IOSTAT_READ_ONLY;
|
|
||||||
static uint8_t IOSTAT_READ_AND_WRITE;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // RSGDP_H
|
#endif // RSGDP_H
|
||||||
|
@ -96,15 +96,78 @@ class RsNetworktExchangeService : public p3Service
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
RsNetworkExchangeService(uint16_t subtype);
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Use this to set how far back synchronisation of messages should take place
|
* Use this to set how far back synchronisation of messages should take place
|
||||||
* @param range how far back from current time to synchronise with other peers
|
* @param range how far back from current time to synchronise with other peers
|
||||||
*/
|
*/
|
||||||
virtual void setTimeRange(uint64_t range) = 0;
|
virtual void setTimeRange(uint64_t range) = 0;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* requests all the groups contained by a peer
|
||||||
|
* @param peerId id of peer
|
||||||
|
*/
|
||||||
|
virtual void requestGroupsOfPeer(const std::string& peerId) = 0;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* get messages of a peer for a given group id, this circumvents the normal
|
||||||
|
* polling of peers for messages of given group id
|
||||||
|
* @param peerId Id of peer
|
||||||
|
* @param grpId id of group to request messages for
|
||||||
|
*/
|
||||||
|
virtual void requestMessagesOfPeer(const std::string& peerId, const RsGroupId& grpId);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* subscribes the associated service to this group. This RsNetworktExchangeService
|
||||||
|
* now regularly polls all peers for new messages of this group
|
||||||
|
* @param grpId the id of the group to subscribe to
|
||||||
|
* @param subscribe set to true to subscribe or false to unsubscribe
|
||||||
|
*/
|
||||||
|
virtual void subscribeToGroup(const RsGroupId& grpId, bool subscribe) = 0;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Initiates a search through the network
|
||||||
|
* This returns messages which contains the search terms set in RsGxsSearch
|
||||||
|
* @param search contains search terms of requested from service
|
||||||
|
* @param hops how far into friend tree for search
|
||||||
|
* @return search token that can be redeemed later, implementation should indicate how this should be used
|
||||||
|
*/
|
||||||
|
virtual int searchMsgs(RsGxsSearch* search, uint8_t hops = 1, bool retrieve = 0) = 0;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Initiates a search of groups through the network which goes
|
||||||
|
* a given number of hosp deep into your friend's network
|
||||||
|
* @param search contains search term requested from service
|
||||||
|
* @param hops number of hops deep into peer network
|
||||||
|
* @return search token that can be redeemed later
|
||||||
|
*/
|
||||||
|
virtual int searchGrps(RsGxsSearch* search, uint8_t hops = 1, bool retrieve = 0) = 0;
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* pauses synchronisation of subscribed groups and request for group id
|
||||||
|
* from peers
|
||||||
|
* @param enabled set to false to disable pause, and true otherwise
|
||||||
|
*/
|
||||||
|
virtual void pauseSynchronisation(bool enabled);
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Request for this message is sent through to peers on your network
|
||||||
|
* and how many hops from them you've indicated
|
||||||
|
* @param msgId the messages to retrieve
|
||||||
|
* @return request token to be redeemed
|
||||||
|
*/
|
||||||
|
virtual int requestMsg(const std::list<RsGxsMsgId>& msgId, uint8_t hops) = 0;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Request for this group is sent through to peers on your network
|
||||||
|
* and how many hops from them you've indicated
|
||||||
|
* @param enabled set to false to disable pause, and true otherwise
|
||||||
|
* @return request token to be redeemed
|
||||||
|
*/
|
||||||
|
virtual int requestGrp(const std::list<RsGxsGrpId>& grpId, uint8_t hops) = 0;
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // RSGNP_H
|
#endif // RSGNP_H
|
||||||
|
@ -87,15 +87,19 @@ class RsGxsSearchResult {
|
|||||||
|
|
||||||
class RsGxsMsg
|
class RsGxsMsg
|
||||||
{
|
{
|
||||||
|
|
||||||
RsGxsMsgId mId;
|
RsGxsMsgId mId;
|
||||||
|
|
||||||
std::string mMsgId;
|
std::string mMsgId;
|
||||||
std::string mOrigMsgId;
|
std::string mOrigMsgId;
|
||||||
|
|
||||||
RsGxsTime mTime;
|
RsGxsTime mTime;
|
||||||
std::list<std::string> mHashtags;
|
std::list<std::string> mHashtags;
|
||||||
std::list<RsGxsLink> mLinked;
|
std::list<RsGxsLink> mLinked;
|
||||||
std::set<uint32_t> versions;
|
std::set<uint32_t> mVersions;
|
||||||
RsGxsSignature mSignature;
|
RsGxsSignature mPersonalSignature;
|
||||||
|
RsGxsSignature mPublishSignature;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -142,13 +146,23 @@ public:
|
|||||||
|
|
||||||
/***************** Group request receive API ********************/
|
/***************** Group request receive API ********************/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Request group, not intialising version member of RsGxsGrpId
|
||||||
|
* results in the latest version of groups being returned
|
||||||
|
* @param grpIds the id/version of the group requested
|
||||||
|
* @return token for request
|
||||||
|
* @see receiveGrp()
|
||||||
|
*/
|
||||||
|
int requestGrp(std::list<RsGxsGrpId>& grpIds);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Request group, not intialising version member of RsGxsGrpId
|
* Request group, not intialising version member of RsGxsGrpId
|
||||||
* results in the latest version of group being returned
|
* results in the latest version of group being returned
|
||||||
* @param grpIds the id/version of the group requested
|
* @param grpIds the id/version of the group requested
|
||||||
* @return token for request
|
* @return token for request
|
||||||
|
* @see receiveGrpList()
|
||||||
*/
|
*/
|
||||||
int requestGrp(std::list<RsGxsGrpId>& grpIds);
|
int requestSubscribedGrpList();
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* pulls in all grps held by peer
|
* pulls in all grps held by peer
|
||||||
@ -160,24 +174,26 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* returns IDs of groups which are still in valid time range
|
* returns Ids of groups which are still in valid time range
|
||||||
* @return token for request
|
* @return token for request
|
||||||
*/
|
*/
|
||||||
int requestGrpList();
|
int requestGrpList();
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @param token the token to be redeemed
|
* @param token the token to be redeemed
|
||||||
|
* @param errCode error code, can be exchanged for error string
|
||||||
* @param grpList list of group ids associated to request token
|
* @param grpList list of group ids associated to request token
|
||||||
*/
|
*/
|
||||||
virtual void receiveGrpList(int token, std::list<RsGxsGrpId>& grpList) = 0;
|
virtual void receiveGrpList(int token, int errCode, std::list<RsGxsGrpId>& grpList) = 0;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Event call back from Gxs runner
|
* Event call back from Gxs runner
|
||||||
* after requested Grp(s) have been retrieved
|
* after requested Grp(s) have been retrieved
|
||||||
* @param token the token to be redeemed
|
* @param token the token to be redeemed
|
||||||
|
* @param errCode error code, can be exchanged for error string
|
||||||
* @param grps list of groups associated to request token
|
* @param grps list of groups associated to request token
|
||||||
*/
|
*/
|
||||||
virtual void receiveGrp(int token, std::set<RsGxsGroup*>& grps) = 0;
|
virtual void receiveGrp(int token, int errCode, std::set<RsGxsGroup*>& grps) = 0;
|
||||||
|
|
||||||
/*************** Start: Msg request receive API ********************/
|
/*************** Start: Msg request receive API ********************/
|
||||||
|
|
||||||
@ -213,7 +229,7 @@ public:
|
|||||||
* after request msg(s) have been received
|
* after request msg(s) have been received
|
||||||
* @param token token to be redeemed
|
* @param token token to be redeemed
|
||||||
*/
|
*/
|
||||||
virtual void receiveMsg(int token, std::set<RsGxsMsg*>& msgs) = 0;
|
virtual void receiveMsg(int token, int errCode, std::set<RsGxsMsg*>& msgs) = 0;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* request message ids for grp
|
* request message ids for grp
|
||||||
@ -226,16 +242,18 @@ public:
|
|||||||
/*!
|
/*!
|
||||||
*
|
*
|
||||||
* @param token to be redeemed
|
* @param token to be redeemed
|
||||||
|
* @param errCode error code, can be exchanged for error string
|
||||||
* @param the msgIdSet associated to request token
|
* @param the msgIdSet associated to request token
|
||||||
*/
|
*/
|
||||||
virtual void receiveMsgIdList(int token, std::list<RsGxsMsgId>& msgIdList) = 0;
|
virtual void receiveMsgIdList(int token, int errCode, std::list<RsGxsMsgId>& msgIdList) = 0;
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @param searchToken token to be redeemed
|
* @param searchToken token to be redeemed
|
||||||
|
* @param errCode error code, can be exchanged for error string
|
||||||
* @param result result set
|
* @param result result set
|
||||||
*/
|
*/
|
||||||
void receivedSearchResult(int searchToken, std::set<RsGxsSearchResult*> results);
|
void receivedSearchResult(int searchToken, int errCode, std::set<RsGxsSearchResult*> results);
|
||||||
|
|
||||||
|
|
||||||
/*************** End: Msg request receive API ********************/
|
/*************** End: Msg request receive API ********************/
|
||||||
@ -247,7 +265,17 @@ public:
|
|||||||
* Pushes a RsGxsItem for publication
|
* Pushes a RsGxsItem for publication
|
||||||
* @param msg set of messages to push onto service for publication
|
* @param msg set of messages to push onto service for publication
|
||||||
*/
|
*/
|
||||||
void pushMsg(std::set<RsGxsMsg*>& msg);
|
int pushMsg(std::set<RsGxsMsg*>& msg);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Updates an already published message
|
||||||
|
* on your network with this one
|
||||||
|
* Message must be associated to an identity on
|
||||||
|
* publication for this to work
|
||||||
|
* @param msg the message to update
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
int updateMsg(std::set<RsGxsMsg*>& msg);
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -259,15 +287,26 @@ public:
|
|||||||
int pushGrp(std::set<RsGxsGroup*>& grp, std::string& profileName);
|
int pushGrp(std::set<RsGxsGroup*>& grp, std::string& profileName);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Pushes a RsGxsGroup onto RsGxs network, associates it with an RsGixs profile to be
|
* Update an already published group with
|
||||||
|
* new information
|
||||||
|
* This increments the version number
|
||||||
|
* @param grp grp to update
|
||||||
|
* @return token to be redeemed
|
||||||
|
*/
|
||||||
|
int updateGrp(std::set<RsGxsGroup*>& grp);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Pushes a set of RsGxsGroups onto RsGxs network, associates it with an RsGixs profile to be
|
||||||
* created given the parameters below
|
* created given the parameters below
|
||||||
* @param grp set of messages to push onto service for publication
|
* @param grp set of messages to push onto service for publication
|
||||||
* @param type the type of identity to create
|
* @param type the type of identity to create
|
||||||
* @param peers peers to share this identity with
|
* @param peers peers to share this identity with
|
||||||
* @param pseudonym if type is pseudonym then uses this as the name of the pseudonym Identity
|
* @param pseudonym if type is pseudonym then uses this as the name of the pseudonym Identity
|
||||||
|
* @return token to be redeemed
|
||||||
|
* @see errorMsg
|
||||||
*/
|
*/
|
||||||
void pushGrp(std::set<RsGxsGroup*>& grp, RsIdentityExchangeService::IdentityType type, const std::set<std::string>& peers,
|
int pushGrp(std::set<RsGxsGroup*>& grp, RsIdentityExchangeService::IdentityType type, const std::set<std::string>& peers,
|
||||||
RsGxsGroup*& group, const std::string& pseudonymName = "");
|
const std::string& pseudonymName = "");
|
||||||
|
|
||||||
/*********** End: publication *****************/
|
/*********** End: publication *****************/
|
||||||
|
|
||||||
@ -287,10 +326,14 @@ public:
|
|||||||
|
|
||||||
/*!
|
/*!
|
||||||
*
|
*
|
||||||
* This sets an RsGroup to be able to share file between its members
|
* This says listed group can are only ones that can
|
||||||
|
* share grp/msgs between themselves for grpId
|
||||||
* Default behaviour on group sharing is share with between all peers
|
* Default behaviour on group sharing is share with between all peers
|
||||||
|
* @param rsGrpId list of group id sharing will be allowed
|
||||||
|
* @param grpId groupId that share behaviour is being set
|
||||||
|
* @return status token to be redeemed
|
||||||
*/
|
*/
|
||||||
void setShareGroup(const std::list<RsGroupId>&, const RsGxsGrpId& grpId);
|
int setShareGroup(const std::list<RsGroupId>& rsGrpId, const RsGxsGrpId& grpId);
|
||||||
|
|
||||||
/*********** End: Identity control and groups *****************/
|
/*********** End: Identity control and groups *****************/
|
||||||
|
|
||||||
@ -319,6 +362,11 @@ public:
|
|||||||
int flagGroupRead(const RsGxsGrpId& grpId, bool read);
|
int flagGroupRead(const RsGxsGrpId& grpId, bool read);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
* This marks a local message created by yourself to
|
||||||
|
* no longer distributed and removed
|
||||||
|
* Entry in db is discarded after expiration date has passed
|
||||||
|
* TODO: this may send a standard marker to user that message
|
||||||
|
* should be removed
|
||||||
* @param msgId
|
* @param msgId
|
||||||
*/
|
*/
|
||||||
int requestDeleteMsg(const RsGxsMsgId& msgId);
|
int requestDeleteMsg(const RsGxsMsgId& msgId);
|
||||||
@ -337,13 +385,15 @@ public:
|
|||||||
* How long to keep subscribed groups
|
* How long to keep subscribed groups
|
||||||
* @param length how long to keep group in seconds
|
* @param length how long to keep group in seconds
|
||||||
*/
|
*/
|
||||||
void setSubscirbedGroupDiscardAge(uint32_t length);
|
int setSubscribedGroupDiscardAge(uint32_t length);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* How long to keep unsubscribed groups
|
* How long to keep unsubscribed groups
|
||||||
* @param length how long to keep groups in seconds
|
* @param length how long to keep groups in seconds
|
||||||
|
* @return status token to be redeemed
|
||||||
|
* @see statusMsg()
|
||||||
*/
|
*/
|
||||||
void setUnsubscribedGrpDiscardAge(uint32_t length);
|
int setUnsubscribedGrpDiscardAge(uint32_t length);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* How long to keep messages, group discard age supercedes this \n
|
* How long to keep messages, group discard age supercedes this \n
|
||||||
@ -364,9 +414,17 @@ public:
|
|||||||
/*!
|
/*!
|
||||||
* This called by event runner on status of subscription
|
* This called by event runner on status of subscription
|
||||||
* @param token the token to be redeemed
|
* @param token the token to be redeemed
|
||||||
|
* @param errCode error code, can be exchanged for error string
|
||||||
* @param gxsStatus the status of subscription request
|
* @param gxsStatus the status of subscription request
|
||||||
*/
|
*/
|
||||||
virtual void receiveSubscribeToGrp(int token, int gxsStatus) = 0;
|
virtual void receiveSubscribeToGrp(int token, int errCode, int gxsStatus) = 0;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
*
|
||||||
|
* @param error_code
|
||||||
|
* @param errorMsg
|
||||||
|
*/
|
||||||
|
virtual void statusMsg(int error_code, const std::string& errorMsg);
|
||||||
|
|
||||||
/******************* End: Configuration *************************/
|
/******************* End: Configuration *************************/
|
||||||
|
|
||||||
@ -407,39 +465,56 @@ public:
|
|||||||
/*!
|
/*!
|
||||||
*
|
*
|
||||||
* @param term This contains the search term
|
* @param term This contains the search term
|
||||||
* @param hops how many hops to search up to
|
* @param hops how many hops from your immediate peer on the network for search
|
||||||
|
* @param delay lenght of time search should persist (if you are online search will be saved \n
|
||||||
|
* delay seconds, max is 2 days
|
||||||
* @return token to redeem search
|
* @return token to redeem search
|
||||||
*/
|
*/
|
||||||
int requestRemoteSearch(RsGxsSearch* term, uint32_t hops);
|
int requestRemoteSearchGrps(RsGxsSearch* term, uint32_t hops, uint32_t delay, bool immediate);
|
||||||
|
|
||||||
|
// Remote Search...(2 hops ?)
|
||||||
|
/*!
|
||||||
|
*
|
||||||
|
* @param term This contains the search term
|
||||||
|
* @param hops how many hops from your immediate peer on the network for search
|
||||||
|
* @param delay lenght of time search should persist (if you are online search will be saved \n
|
||||||
|
* delay seconds, max is 2 days
|
||||||
|
* @return token to redeem search
|
||||||
|
*/
|
||||||
|
int requestRemoteSearchMsgs(RsGxsSearch* term, uint32_t hops, uint32_t delay, bool immediate);
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
*
|
*
|
||||||
* @param token
|
* @param token
|
||||||
|
* @param errCode error code, can be exchanged for error string
|
||||||
* @param grpIds list of grp ids
|
* @param grpIds list of grp ids
|
||||||
*/
|
*/
|
||||||
virtual void receiveLocalSearchGrps(int token, std::list<RsGxsGrpId>& grpIds);
|
virtual void receiveLocalSearchGrps(int token, int errCode, std::list<RsGxsGrpId>& grpIds);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
*
|
*
|
||||||
* @param token the request token to be redeemed
|
* @param token the request token to be redeemed
|
||||||
|
* @param errCode error code, can be exchanged for error string
|
||||||
* @param msgIds the message ids that contain contain search term
|
* @param msgIds the message ids that contain contain search term
|
||||||
*/
|
*/
|
||||||
virtual void receiveLocalSearchMsgs(int token, std::list<RsGxsMsgId> &msgIds) = 0;
|
virtual void receiveLocalSearchMsgs(int token, int errCode, std::list<RsGxsMsgId> &msgIds) = 0;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
*
|
*
|
||||||
* @param token request token to be redeemed
|
* @param token request token to be redeemed
|
||||||
|
* @param errCode error code, can be exchanged for error string
|
||||||
* @param grps
|
* @param grps
|
||||||
*/
|
*/
|
||||||
virtual void receiveRemoteSearchGrps(int token, std::list<RsGxsGrpId>& grps) = 0;
|
virtual void receiveRemoteSearchGrps(int token, int errCode, std::list<RsGxsGrpId>& grps) = 0;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
*
|
*
|
||||||
* @param token the request token to be redeemed
|
* @param token the request token to be redeemed
|
||||||
|
* @param errCode error code, can be exchanged for error string
|
||||||
* @param msgIds
|
* @param msgIds
|
||||||
*/
|
*/
|
||||||
virtual void recieveRemoteSearchMsgs(int token, std::list<RsGxsMsgId>& msgs) = 0;
|
virtual void recieveRemoteSearchMsgs(int token, int errCode, std::list<RsGxsMsgId>& msgs) = 0;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Note if parent group is not present this will be requested \n
|
* Note if parent group is not present this will be requested \n
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -42,7 +42,7 @@ const int RetroDb::OPEN_READONLY = SQLITE_OPEN_READONLY;
|
|||||||
const int RetroDb::OPEN_READWRITE = SQLITE_OPEN_READWRITE;
|
const int RetroDb::OPEN_READWRITE = SQLITE_OPEN_READWRITE;
|
||||||
const int RetroDb::OPEN_READWRITE_CREATE = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
|
const int RetroDb::OPEN_READWRITE_CREATE = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
|
||||||
|
|
||||||
RetroDb::RetroDb(const std::string &dbPath, int flags) : mDb(NULL), mCurrStmt(NULL) {
|
RetroDb::RetroDb(const std::string &dbPath, int flags) : mDb(NULL) {
|
||||||
|
|
||||||
int rc = sqlite3_open_v2(dbPath.c_str(), &mDb, flags, NULL);
|
int rc = sqlite3_open_v2(dbPath.c_str(), &mDb, flags, NULL);
|
||||||
|
|
||||||
|
@ -141,11 +141,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
void vacuum();
|
void vacuum();
|
||||||
|
|
||||||
/*!
|
|
||||||
* TODO: remove, do not use; for testing
|
|
||||||
*/
|
|
||||||
sqlite3_stmt* getCurrStmt();
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static const int OPEN_READONLY;
|
static const int OPEN_READONLY;
|
||||||
@ -156,7 +151,6 @@ private:
|
|||||||
|
|
||||||
|
|
||||||
sqlite3* mDb;
|
sqlite3* mDb;
|
||||||
sqlite3_stmt* mCurrStmt; // TODO: remove
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user