From d8bfc6d8b38d6052f0126bc9a3892f7d88924e56 Mon Sep 17 00:00:00 2001 From: chrisparker126 Date: Wed, 4 Jun 2008 10:59:24 +0000 Subject: [PATCH] Mostly connectivity code additions * implementation of p3config, cache functionality to p3Qblog * added peerid (pid) attribute to rsQblog item and its serialisation * TODO: logical updating for p3Qblog * TODO: implement tick() so can add to server * TODO: test p3Qblog after addition of tick with some peers git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@571 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/pqi/p3cfgmgr.h | 1 + libretroshare/src/rsiface/rsQblog.h | 11 +- libretroshare/src/rsserver/Makefile | 1 + libretroshare/src/rsserver/p3Blog.cc | 91 +++ libretroshare/src/rsserver/p3Blog.h | 66 ++ libretroshare/src/rsserver/p3face-server.cc | 5 + libretroshare/src/rsserver/p3face-startup.cc | 20 +- libretroshare/src/rsserver/p3face.h | 2 + libretroshare/src/scripts/config-linux.mk | 4 +- libretroshare/src/serialiser/rsmsgitems.cc | 2 +- libretroshare/src/serialiser/rsqblogitems.cc | 8 +- libretroshare/src/serialiser/rsqblogitems.h | 11 +- libretroshare/src/services/p3Qblog.cc | 674 ++++++++++++++++--- libretroshare/src/services/p3Qblog.h | 123 +++- libretroshare/src/upnp/upnputil.h | 6 +- 15 files changed, 886 insertions(+), 139 deletions(-) create mode 100644 libretroshare/src/rsserver/p3Blog.cc create mode 100644 libretroshare/src/rsserver/p3Blog.h diff --git a/libretroshare/src/pqi/p3cfgmgr.h b/libretroshare/src/pqi/p3cfgmgr.h index 666bcb0fd..68cc377bf 100644 --- a/libretroshare/src/pqi/p3cfgmgr.h +++ b/libretroshare/src/pqi/p3cfgmgr.h @@ -65,6 +65,7 @@ const uint32_t CONFIG_TYPE_MSGS = 0x0004; const uint32_t CONFIG_TYPE_CACHE = 0x0005; const uint32_t CONFIG_TYPE_RANK_LINK = 0x0011; +const uint32_t CONFIG_TYPE_QBLOG = 0x0012; class p3ConfigMgr; class p3AuthMgr; diff --git a/libretroshare/src/rsiface/rsQblog.h b/libretroshare/src/rsiface/rsQblog.h index 2b160d3b2..e5f21457e 100644 --- a/libretroshare/src/rsiface/rsQblog.h +++ b/libretroshare/src/rsiface/rsQblog.h @@ -6,7 +6,7 @@ * * RetroShare C++ Interface. * - * Copyright 2007-2008 by Chris Parker, Robert Fernie. + * Copyright 2007-2008 by Chris Evi-Parker, Robert Fernie. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -63,11 +63,6 @@ extern RsQblog *rsQblog; */ virtual bool setFilterSwitch(bool &filterSwitch) = 0; - /** - * get usrs friend list - * @ param usrList - */ - virtual bool getFriendList(std::list &friendList) =0; /** * retrieve usrs filterSwitch status @@ -92,9 +87,7 @@ extern RsQblog *rsQblog; * @param favSong puts ref for fav song here */ virtual bool getProfile(std::map &profile) = 0; - - - + /** * for now just fav song, TODO: must find way to link to rs profile */ diff --git a/libretroshare/src/rsserver/Makefile b/libretroshare/src/rsserver/Makefile index 4d6182c25..637375873 100644 --- a/libretroshare/src/rsserver/Makefile +++ b/libretroshare/src/rsserver/Makefile @@ -11,6 +11,7 @@ RSOBJ = p3peers.o \ p3rank.o \ p3photo.o \ p3msgs.o \ + p3Blog.o \ p3discovery.o \ p3face-file.o \ p3face-server.o \ diff --git a/libretroshare/src/rsserver/p3Blog.cc b/libretroshare/src/rsserver/p3Blog.cc new file mode 100644 index 000000000..df1961a9a --- /dev/null +++ b/libretroshare/src/rsserver/p3Blog.cc @@ -0,0 +1,91 @@ +/* + * libretroshare/src/rsserver: p3blog.cc + * + * RetroShare C++ Interface. + * + * Copyright 2007-2008 by Chris Evi-Parker. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#include "rsserver/p3Blog.h" + +RsQblog* rsQblog = NULL; + +p3Blog::p3Blog(p3Qblog* qblog) : +mQblog(qblog) +{ + return; +} + + +p3Blog::~p3Blog() +{ + return; +} + +bool p3Blog::addToFilter(std::string &usrId) +{ + return mQblog->addToFilter(usrId); +} + +bool p3Blog::getBlogs(std::map< std::string, std::multimap > &blogs) +{ + return mQblog->getBlogs(blogs); +} + +bool p3Blog::getFilterSwitch(void) +{ + return mQblog->getFilterSwitch(); +} + +bool p3Blog::getProfile(std::map &profile) +{ + return mQblog->getProfile(profile); +} + +bool p3Blog::getStatus(std::map &usrStatus) +{ + return mQblog->getStatus(usrStatus); +} + +bool p3Blog::sendBlog(const std::string &msg) +{ + return mQblog->sendBlog(msg); +} + +bool p3Blog::setFilterSwitch(bool &filterSwitch) +{ + return mQblog->setFilterSwitch(filterSwitch); +} + +bool p3Blog::setProfile(const std::string &favSong) +{ + return mQblog->setProfile(favSong); +} + +bool p3Blog::setStatus(const std::string &status) +{ + return mQblog->setStatus(status); +} + +bool p3Blog::removeFiltFriend(std::string &usrId) +{ + return mQblog->removeFiltFriend(usrId); +} + diff --git a/libretroshare/src/rsserver/p3Blog.h b/libretroshare/src/rsserver/p3Blog.h new file mode 100644 index 000000000..e0a92d703 --- /dev/null +++ b/libretroshare/src/rsserver/p3Blog.h @@ -0,0 +1,66 @@ + + + +#ifndef P3BLOG_H_ +#define P3BLOG_H_ + +/* + * libretroshare/src/rsserver: p3blog.h + * + * RetroShare C++ Interface. + * + * Copyright 2007-2008 by Chris Evi-Parker. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#include "rsiface/rsQblog.h" +#include "services/p3Qblog.h" + +/*! + * Interface class using composition (p3Qblog is an attribute) + * See derived class for documentation of derived functions + */ +class p3Blog : public RsQblog +{ + public: + + p3Blog(p3Qblog* qblog); + virtual ~p3Blog(); + + virtual bool setStatus(const std::string &status); + virtual bool getStatus(std::map &usrStatus); + virtual bool setFilterSwitch(bool &filterSwitch); + virtual bool getFilterSwitch(void); + virtual bool addToFilter(std::string &usrId); + virtual bool removeFiltFriend(std::string &usrId); + virtual bool getProfile(std::map &profile); + virtual bool setProfile(const std::string &favSong); + virtual bool sendBlog(const std::string &msg); + virtual bool getBlogs(std::map< std::string, std::multimap > &blogs); + + + + private: + + /// to make rsCore blog-service calls + p3Qblog* mQblog; +}; + + +#endif /*P3BLOG_H_*/ diff --git a/libretroshare/src/rsserver/p3face-server.cc b/libretroshare/src/rsserver/p3face-server.cc index 39cc4b58b..2f7c42b54 100644 --- a/libretroshare/src/rsserver/p3face-server.cc +++ b/libretroshare/src/rsserver/p3face-server.cc @@ -214,6 +214,11 @@ void RsServer::run() /* Tick slow services */ if (mRanking) mRanking->tick(); + + /* TODO need to implement tick function + if(mQblog) + mQblog->tick() + */ #if 0 diff --git a/libretroshare/src/rsserver/p3face-startup.cc b/libretroshare/src/rsserver/p3face-startup.cc index 13583764d..b80e76bce 100644 --- a/libretroshare/src/rsserver/p3face-startup.cc +++ b/libretroshare/src/rsserver/p3face-startup.cc @@ -66,8 +66,10 @@ #include "rsserver/p3msgs.h" #include "rsserver/p3discovery.h" #include "rsserver/p3photo.h" +#include "rsserver/p3Blog.h" #include "rsiface/rsgame.h" + #include "pqi/p3notify.h" // HACK - moved to pqi for compilation order. @@ -569,23 +571,32 @@ int RsServer::StartupRetroShare(RsInit *config) p3GameLauncher *gameLauncher = new p3GameLauncher(mConnMgr); pqih -> addService(gameLauncher); - mRanking = new p3Ranking(mConnMgr, RS_SERVICE_TYPE_RANK, + mRanking = new p3Ranking(mConnMgr, RS_SERVICE_TYPE_RANK, /* declaration of cache enable service rank */ mCacheStrapper, mCacheTransfer, localcachedir, remotecachedir, 3600 * 24 * 30); CachePair cp(mRanking, mRanking, CacheId(RS_SERVICE_TYPE_RANK, 0)); - mCacheStrapper -> addCachePair(cp); + mCacheStrapper -> addCachePair(cp); /* end of declaration */ - p3PhotoService *photoService = new p3PhotoService(RS_SERVICE_TYPE_PHOTO, + p3PhotoService *photoService = new p3PhotoService(RS_SERVICE_TYPE_PHOTO, /* .... for photo service */ mCacheStrapper, mCacheTransfer, localcachedir, remotecachedir); CachePair cp2(photoService, photoService, CacheId(RS_SERVICE_TYPE_PHOTO, 0)); mCacheStrapper -> addCachePair(cp2); + mQblog = new p3Qblog(mConnMgr, RS_SERVICE_TYPE_QBLOG, /* ...then for Qblog */ + mCacheStrapper, mCacheTransfer, + localcachedir, remotecachedir, 3600 * 24 * 30); + + CachePair cp3(mQblog, mQblog, CacheId(RS_SERVICE_TYPE_QBLOG, 0)); + mCacheStrapper -> addCachePair(cp3); + + #else mRanking = NULL; + mQBlog = NULL; #endif @@ -612,6 +623,7 @@ int RsServer::StartupRetroShare(RsInit *config) mConfigMgr->addConfiguration("cache.cfg", mCacheStrapper); #ifndef RS_RELEASE mConfigMgr->addConfiguration("ranklink.cfg", mRanking); + mConfigMgr->addConfiguration("qblog.cfg", mQblog); #endif /**************************************************************************/ @@ -741,7 +753,7 @@ int RsServer::StartupRetroShare(RsInit *config) rsRanks = new p3Rank(mRanking); rsForums = new p3Forums(); rsStatus = new p3Status(); - rsQblog = new p3Qblog(); + rsQblog = new p3Blog(mQblog); #else rsGameLauncher = NULL; diff --git a/libretroshare/src/rsserver/p3face.h b/libretroshare/src/rsserver/p3face.h index 984fb0b53..c75a59fbc 100644 --- a/libretroshare/src/rsserver/p3face.h +++ b/libretroshare/src/rsserver/p3face.h @@ -41,6 +41,7 @@ #include "services/p3msgservice.h" #include "services/p3chatservice.h" #include "services/p3ranking.h" +#include "services/p3Qblog.h" /* The Main Interface Class - for controlling the server */ @@ -286,6 +287,7 @@ int UpdateAllConfig(); /* caches (that need ticking) */ p3Ranking *mRanking; + p3Qblog *mQblog; /* Config */ p3ConfigMgr *mConfigMgr; diff --git a/libretroshare/src/scripts/config-linux.mk b/libretroshare/src/scripts/config-linux.mk index 909202b66..9e6b1aaa4 100644 --- a/libretroshare/src/scripts/config-linux.mk +++ b/libretroshare/src/scripts/config-linux.mk @@ -13,8 +13,8 @@ PQI_USE_XPGP = 1 #PQI_USE_CHANNELS = 1 #USE_FILELOOK = 1 -SSL_DIR=../../../../../src/openssl-0.9.7g-xpgp-0.1c -UPNPC_DIR=../../../../../src/miniupnpc-1.0 +SSL_DIR=/home/chris/retroshare-package-v0.4.04b/src/openssl-0.9.7g-xpgp-0.1c +UPNPC_DIR=/home/chris/retroshare-package-v0.4.04b/src/miniupnpc-1.0 include $(RS_TOP_DIR)/scripts/checks.mk diff --git a/libretroshare/src/serialiser/rsmsgitems.cc b/libretroshare/src/serialiser/rsmsgitems.cc index 2bf455d52..c01bf42b8 100644 --- a/libretroshare/src/serialiser/rsmsgitems.cc +++ b/libretroshare/src/serialiser/rsmsgitems.cc @@ -53,7 +53,7 @@ std::ostream &RsChatItem::print(std::ostream &out, uint16_t indent) printRsItemBase(out, "RsChatItem", indent); uint16_t int_Indent = indent + 2; printIndent(out, int_Indent); - out << "chatFlags: " << chatFlags << std::endl; + out << "QblogMs " << chatFlags << std::endl; printIndent(out, int_Indent); out << "sendTime: " << sendTime << std::endl; diff --git a/libretroshare/src/serialiser/rsqblogitems.cc b/libretroshare/src/serialiser/rsqblogitems.cc index c6ce4fe7d..61b6d731e 100644 --- a/libretroshare/src/serialiser/rsqblogitems.cc +++ b/libretroshare/src/serialiser/rsqblogitems.cc @@ -57,7 +57,8 @@ std::ostream &RsQblogItem::print(std::ostream &out, uint16_t indent) out << "blogMsg(message): " << blogMsg.second << std::endl; printIndent(out, int_Indent); out << "status " << status << std::endl; - + printIndent(out, int_Indent); + out << "pid " << pid << std::endl; printRsItemEnd(out, "RsQblogItem", indent); return out; } @@ -71,7 +72,8 @@ uint32_t RsQblogSerialiser::sizeItem(RsQblogItem *item) s += GetTlvStringSize(item->blogMsg.second); // string part of blog s += GetTlvStringSize(item->status); s += GetTlvStringSize(item->favSong); - + s += GetTlvStringSize(item->pid); + return s; } @@ -103,6 +105,7 @@ bool RsQblogSerialiser::serialiseItem(RsQblogItem* item, void* data, uint32_t *s ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_MSG, item->blogMsg.second); ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_MSG, item->status); ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_MSG, item->favSong); + ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_MSG, item->favSong); if (offset != tlvsize) { @@ -154,6 +157,7 @@ RsQblogItem* RsQblogSerialiser::deserialiseItem(void * data, uint32_t *size) ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_MSG, item->blogMsg.second); ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_MSG, item->status); ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_MSG, item->favSong); + ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_MSG, item->pid); if (offset != rssize) { diff --git a/libretroshare/src/serialiser/rsqblogitems.h b/libretroshare/src/serialiser/rsqblogitems.h index ab8b1e55a..b2cf83f76 100644 --- a/libretroshare/src/serialiser/rsqblogitems.h +++ b/libretroshare/src/serialiser/rsqblogitems.h @@ -55,9 +55,14 @@ std::ostream &print(std::ostream &out, uint16_t indent = 0); /* everything below is serialised */ -std::pair blogMsg; /// contain blog mesgs and their blogged times (client time) -std::string status; /// to be serialised: status of a requested user -std::string favSong; /// the users favorite song +/// contain blog mesgs and their blog time stamp (client time) +std::pair blogMsg; +/// to be serialised: status of a requested user +std::string status; +/// the users favorite song +std::string favSong; +/// peer id TODO: serialise this +std::string pid; }; /*! to serialise rsQblogItems: method names are self explanatory */ diff --git a/libretroshare/src/services/p3Qblog.cc b/libretroshare/src/services/p3Qblog.cc index f5d02300f..ce394ff34 100644 --- a/libretroshare/src/services/p3Qblog.cc +++ b/libretroshare/src/services/p3Qblog.cc @@ -23,19 +23,329 @@ * */ +#include "serialiser/rsqblogitems.h" #include "services/p3Qblog.h" #include #include +#include +#include "pqi/pqibin.h" +#include "pqi/p3authmgr.h" -RsQblog *rsQblog = NULL; +const uint32_t RANK_MAX_FWD_OFFSET = (60 * 60 * 24 * 2); /* 2 Days */ -p3Qblog::p3Qblog() -: FilterSwitch(false) +const uint32_t FRIEND_QBLOG_REPOST_PERIOD = 60; /* every minute for testing */ + +#define QBLOG_DEBUG 1 + +p3Qblog::p3Qblog(p3ConnectMgr *connMgr, + uint16_t type, CacheStrapper *cs, CacheTransfer *cft, + std::string sourcedir, std::string storedir, + uint32_t storePeriod) + :CacheSource(type, true, cs, sourcedir), + CacheStore(type, true, cs, cft, storedir), + p3Config(CONFIG_TYPE_QBLOG), mConnMgr(connMgr), mFilterSwitch(false), + mStorePeriod(storePeriod), mUpdated(true) { - loadDummy(); // load dummy data + { + RsStackMutex stack(mBlogMtx); + mOwnId = mConnMgr->getOwnId(); // get your own usr Id + //bool ok = mConnMgr->getFriendList(FriendList); + loadDummy(); // load dummy data + + #ifdef QBLOG_DEBUG + /*if(!ok) + std::cerr << "initialization failed: could not retrieve friend list"; */ + #endif + + } + return; } +bool p3Qblog::loadLocalCache(const CacheData &data) +{ + std::string filename = data.path + '/' + data.name; + std::string hash = data.hash; + std::string source = data.pid; + + #ifdef QBLOG_DEBUG + std::cerr << "p3Ranking::loadLocalCache()"; + std::cerr << std::endl; + std::cerr << "\tSource: " << source; + std::cerr << std::endl; + std::cerr << "\tFilename: " << filename; + std::cerr << std::endl; + std::cerr << "\tHash: " << hash; + std::cerr << std::endl; + std::cerr << "\tSize: " << data.size; + std::cerr << std::endl; + #endif + + loadBlogFile(filename, source); + + // TODO might need to add boolean saying cached blogs not posted + + if (data.size > 0) /* don't refresh zero sized caches */ + { + refreshCache(data); + } + + return true; +} + + +int p3Qblog::loadCache(const CacheData &data) +{ + std::string filename = data.path + '/' + data.name; + std::string hash = data.hash; + std::string source = data.pid; + + #ifdef QBLOG_DEBUG + std::cerr << "p3Qblog::loadCache()"; + std::cerr << std::endl; + std::cerr << "\tSource: " << source; + std::cerr << std::endl; + std::cerr << "\tFilename: " << filename; + std::cerr << std::endl; + std::cerr << "\tHash: " << hash; + std::cerr << std::endl; + std::cerr << "\tSize: " << data.size; + std::cerr << std::endl; + #endif + + loadBlogFile(filename, source); + + + CacheStore::lockData(); /***** LOCK ****/ + locked_storeCacheEntry(data); + CacheStore::unlockData(); /***** UNLOCK ****/ + + return 1; +} + +bool p3Qblog::loadBlogFile(std::string filename, std::string src) +{ + /* create the serialiser to load info */ + RsSerialiser *rsSerialiser = new RsSerialiser(); + rsSerialiser->addSerialType(new RsQblogSerialiser()); + + uint32_t bioflags = BIN_FLAGS_HASH_DATA | BIN_FLAGS_READABLE; + BinInterface *bio = new BinFileInterface(filename.c_str(), bioflags); + pqistreamer *stream = new pqistreamer(rsSerialiser, src, bio, 0); + + #ifdef QBLOG_DEBUG + + std::cerr << "p3Qblog::loadBlogFile()"; + std::cerr << std::endl; + std::cerr << "\tSource: " << src; + std::cerr << std::endl; + std::cerr << "\tFilename: " << filename; + std::cerr << std::endl; + + #endif + + /* will load file info to these items */ + RsItem *item; + RsQblogItem *newBlog; + + stream->tick(); // tick to read + + time_t now = time(NULL); + time_t min, max; + + { /********** STACK LOCKED MTX ******/ + RsStackMutex stack(mBlogMtx); + min = now - mStorePeriod; + max = now + RANK_MAX_FWD_OFFSET; + } /********** STACK LOCKED MTX ******/ + + while(NULL != (item = stream->GetItem())) + { + #ifdef QBLOG_DEBUG + std::cerr << "p3Qblog::loadBlogFile() Got Item:"; + std::cerr << std::endl; + item->print(std::cerr, 10); + std::cerr << std::endl; + #endif + + if (NULL == (newBlog = dynamic_cast(item))) + { + #ifdef QBLOG_DEBUG + std::cerr << "p3Qblog::loadBlogFile() Item not Blog (deleting):"; + std::cerr << std::endl; + #endif + + delete item; + } + /* check timestamp */ + else if (((time_t) newBlog->blogMsg.first < min) || + ((time_t) newBlog->blogMsg.first > max)) + { + #ifdef QBLOG_DEBUG + std::cerr << "p3Qblog::loadBlogFile() Outside TimeRange (deleting):"; + std::cerr << std::endl; + #endif + /* if outside time range remove */ + delete newBlog; + } + else + { + #ifdef QBLOG_DEBUG + std::cerr << "p3Qblog::loadBlogFile() Loading Item"; + std::cerr << std::endl; + #endif + + addBlog(newBlog); // add received blog to list + } + + stream->tick(); // tick to read + } + + delete stream; // stream finished with/return resource + return true; +} + +bool p3Qblog::addBlog(RsQblogItem *newBlog) +{ + { + RsStackMutex Stack(mBlogMtx); + + mPeerSongSet[newBlog->pid] = newBlog->favSong; + mPeerStatusSet[newBlog->pid] = newBlog->status; + mUsrBlogSet[newBlog->pid].insert(newBlog->blogMsg); + + #ifdef QBLOG_DEBUG + std::cerr << "p3Qblog::addBlog()"; + std::cerr << std::endl; + std::cerr << "pid" << newBlog->pid; + std::cerr << std::endl; + std::cerr << "\tmPeerSongset" << mPeerSongSet[newBlog->pid]; + std::cerr << std::endl; + std::cerr << "\tmPeerStatusSet" << mPeerStatusSet[newBlog->pid]; + std::cerr << std::endl; + std::cerr << "\tmUsrBlogSet: time" << newBlog->blogMsg.first; + std::cerr << std::endl; + std::cerr << "\tmUsrBlogSet: blog" << newBlog->blogMsg.second; + std::cerr << std::endl; + #endif + } + + return true; +} + +bool p3Qblog::postBlogs(void) +{ + + #ifdef QBLOG_DEBUG + std::cerr << "p3Qblog::postBlogs()"; + std::cerr << std::endl; + #endif + + std::string path = CacheSource::getCacheDir(); + std::ostringstream out; + uint16_t subid = 1; + + out << "qblogs-" << time(NULL) << ".rsqb"; // create blog file name based on time posted + + /* determine filename */ + std::string tmpname = out.str(); + std::string fname = path + "/" + tmpname; + + #ifdef RANK_DEBUG + std::cerr << "p3Ranking::publishMsgs() Storing to: " << fname; + std::cerr << std::endl; + #endif + + RsSerialiser *rsSerialiser = new RsSerialiser(); + rsSerialiser->addSerialType(new RsQblogSerialiser()); + + uint32_t bioflags = BIN_FLAGS_HASH_DATA | BIN_FLAGS_WRITEABLE; + BinInterface *bio = new BinFileInterface(fname.c_str(), bioflags); + pqistreamer *stream = new pqistreamer(rsSerialiser, mOwnId, bio, + BIN_FLAGS_NO_DELETE); + + { + RsStackMutex stack(mBlogMtx); /********** STACK LOCKED MTX ******/ + + /* iterate through list */ + std::list::iterator it; + + for(it = mBlogItems.begin(); it != mBlogItems.end(); it++) + { + /* only post own blogs */ + if(mOwnId == (*it)->pid) + { + /*write to serialiser*/ + RsItem *item = *it; + + #ifdef QBLOG_DEBUG + std::cerr << "p3Qblog::postBlogs() Storing Item:"; + std::cerr << std::endl; + item->print(std::cerr, 10); + std::cerr << std::endl; + #endif + + stream->SendItem(item); + stream->tick(); /* tick to write */ + } + else /* if blogs belong to a friend */ + { + #ifdef QBLOG_DEBUG + std::cerr << "p3Ranking::postBlogs() Skipping friend blog items:"; + std::cerr << std::endl; + #endif + + continue; + } + } + + } + + + stream->tick(); /* Tick for final write! */ + + /* flag as new info */ + CacheData data; + + { /********** STACK LOCKED MTX ******/ + RsStackMutex stack(mBlogMtx); + data.pid = mOwnId; + } /********** STACK LOCKED MTX ******/ + + data.cid = CacheId(CacheSource::getCacheType(), subid); + + data.path = path; + data.name = tmpname; + + data.hash = bio->gethash(); + data.size = bio->bytecount(); + data.recvd = time(NULL); + + #ifdef RANK_DEBUG + std::cerr << "p3Ranking::postBlogs() refreshing Cache"; + std::cerr << std::endl; + std::cerr << "\tCache Path: " << data.path; + std::cerr << std::endl; + std::cerr << "\tCache Name: " << data.name; + std::cerr << std::endl; + std::cerr << "\tCache Hash: " << data.hash; + std::cerr << std::endl; + std::cerr << "\tCache Size: " << data.size; + std::cerr << std::endl; + #endif + + if(data.size > 0) /* don't refresh zero sized caches */ + { + refreshCache(data); + } + + delete stream; + return true; +} + + + + p3Qblog::~p3Qblog() { return; @@ -44,36 +354,58 @@ p3Qblog::~p3Qblog() bool p3Qblog::setStatus(const std::string &status) { - FriendStatusSet[usr] = status; + { + RsStackMutex stack(mBlogMtx); + mPeerStatusSet[mOwnId] = status; + + #ifdef QBLOG_DEBUG + std::cerr << "p3Qblog::getStatus() mPeerStatus[mOwnId]" << mPeerStatusSet[mOwnId]; + std::cerr << std::endl; + #endif + } + return true; } bool p3Qblog::getFilterSwitch(void) { - return FilterSwitch; + { + RsStackMutex stack(mBlogMtx); // might be pointless + return mFilterSwitch; + } } bool p3Qblog::setFilterSwitch(bool &filterSwitch) { - FilterSwitch = filterSwitch; - return true; -} - -bool p3Qblog::getFriendList(std::list &friendList) -{ - if(FriendList.empty()) { - std::cerr << "FriendList empty!" << std::endl; - return false; - } - - friendList = FriendList; + RsStackMutex stack(mBlogMtx); + mFilterSwitch = filterSwitch; + + #ifdef QBLOG_DEBUG + std::cerr << "p3Qblog::setFilterSwitch() " << mFilterSwitch; + std::cerr << std::endl; + #endif + } return true; } bool p3Qblog::getStatus(std::map &usrStatus) { - usrStatus = FriendStatusSet; + { + RsStackMutex stack(mBlogMtx); + + #ifdef QBLOG_DEBUG + if(mPeerStatusSet.empty()) + { + std::cerr << "p3Qblog::getStatus() mPeerStatusSet empty! "; + std::cerr << std::endl; + return false; + } + #endif + + usrStatus = mPeerStatusSet; + } + return true; } @@ -81,128 +413,296 @@ bool p3Qblog::removeFiltFriend(std::string &usrId) { std::list::iterator it; - /* search through list to remove friend */ - for(it = FriendList.begin(); it != FriendList.end(); it++) { - if(it->compare(usrId)) + RsStackMutex stack(mBlogMtx); + + /* search through list to remove friend */ + for(it = mFilterList.begin(); it != mFilterList.end(); it++) { - FriendList.erase(it); // remove friend from list - return true; + if(it->compare(usrId)) + { + #ifdef QBLOG_DEBUG + std::cerr << "p3Qblog::removeFilterFriend() it " << *it; + std::cerr << std::endl; + #endif + mFilterList.erase(it); // remove friend from list + return true; + } } } + #ifdef QBLOG_DEBUG std::cerr << "usr could not be found!" << std::endl; + #endif + return false; // could not find friend } bool p3Qblog::addToFilter(std::string& usrId) { - std::list::iterator it; - - /* search through list to remove friend */ - for(it = FriendList.begin(); it != FriendList.end(); it++) { - if(it->compare(usrId)) + RsStackMutex stack(mBlogMtx); + std::list::iterator it; + + /* search through list in case friend already exist */ + for(it = mFilterList.begin(); it != mFilterList.end(); it++) { - std::cerr << "usr already in list!" << std::endl; - return false; // user already in list, not added + if(it->compare(usrId)) + { + #ifdef QBLOG_DEBUG + std::cerr << "usr already in list!" << *it; + std::cerr << std::endl; + #endif + + return false; // user already in list, not added + } } + + mFilterList.push_back(usrId); } - FilterList.push_back(usrId); return true; } bool p3Qblog::getBlogs(std::map< std::string, std::multimap > &blogs) { - if(UsrBlogSet.empty()) // return error blogs are empty - { - std::cerr << "usr blog set empty!" << std::endl; - return false; + { + RsStackMutex stack(mBlogMtx); + + if(mUsrBlogSet.empty()) // return error blogs are empty + { + std::cerr << "usr blog set empty!" << std::endl; + return false; + } + + blogs = mUsrBlogSet; + return true; + + #ifdef QBOG_DEBUG + std::cerr << "p3Qblog::getBlogs() number of blogs: " << mUsrBlogSet.size(); + std::cerr << std::endl; + #endif } - - blogs = UsrBlogSet; - return true; } bool p3Qblog::sendBlog(const std::string &msg) { - time_t msgCreatedTime; - UsrBlogSet["Usr1"].insert(std::make_pair(msgCreatedTime, msg)); + time_t blogTimeStamp; + + { + RsStackMutex stack(mBlogMtx); + mUsrBlogSet[mOwnId].insert(std::make_pair(blogTimeStamp, msg)); + + RsQblogItem *blogItem = new RsQblogItem(); + blogItem->clear(); + + blogItem->pid = mOwnId; + blogItem->blogMsg.first = blogTimeStamp; + blogItem->blogMsg.second = msg; + blogItem->favSong = mPeerSongSet[mOwnId]; + blogItem->status = mPeerStatusSet[mOwnId]; + + #ifdef QBLOG_DEBUG + std::cerr << "p3Qblog::sendBlogFile()"; + std::cerr << std::endl; + std::cerr << "\tblogItem->pid" << blogItem->blogMsg.first; + std::cerr << std::endl; + std::cerr << "\tblogItem->blogMsg.first" << blogItem->blogMsg.first; + std::cerr << std::endl; + std::cerr << "\tblogItem->blogMsg.second" << blogItem->blogMsg.second; + std::cerr << std::endl; + std::cerr << "\tblogItem->favSong" << blogItem->favSong; + std::cerr << std::endl; + std::cerr << "\tblogItem->status" << blogItem->status; + std::cerr << std::endl; + #endif + + mBlogItems.push_back(blogItem); + } return true; } bool p3Qblog::getProfile(std::map &profile) { - /* return error is set empty */ - if(FriendSongset.empty()) { - std::cerr << "friend song set empty!" << std::endl; - return false; - } + RsStackMutex stack(mBlogMtx); + + /* return error is set empty */ + if(mPeerSongSet.empty()) + { + std::cerr << "friend song set empty!" << std::endl; + return false; + } + + profile = mPeerSongSet; + } - profile = FriendSongset; return true; } bool p3Qblog::setProfile(const std::string &favSong) { - FriendSongset[usr] = favSong; + { + RsStackMutex stack(mBlogMtx); + mPeerSongSet[mOwnId] = favSong; + } + return true; } void p3Qblog::loadDummy(void) { - /* load usr list */ - FriendList.push_back("Usr1"); // home usr/server - FriendList.push_back("Mike2"); - FriendList.push_back("Mike3"); - FriendList.push_back("Mike4"); - FriendList.push_back("Mike5"); + std::list peers; - /* set usr status: need to create usr/status set or just add to profile object */ - //TODO + mConnMgr->getFriendList(peers); // retrieve peers list from core + if(peers.empty()) + { + for(int i = 0; i < 50; i++) + std::cerr << "nothing in peer list!!!" << std::endl; + } - /* set favsong: will be made part of profile */ - FavSong = "DeathOfAthousandSuns"; - /* load friend song set */ - FriendSongset.insert(std::make_pair("Usr1", FavSong)); // home usr/server - FriendSongset.insert(std::make_pair("Mike2", "yowsers")); - FriendSongset.insert(std::make_pair("Mike3", "destroyers")); - FriendSongset.insert(std::make_pair("Mike4", "revolvers")); - FriendSongset.insert(std::make_pair("Mike5", "pepolvers")); - - /* load usr blogs */ + srand(60); + long int now = time(NULL); // the present time + std::multimap emptySet; // time/blog map + std::string statusSet[5] = { "great", "rubbish", "ecstatic", "save me", "emo depression"}; + std::string songs[5] = { "broken spleen", "niobium", "ewe (a sheep)", "velvet stuff", "chun li kicks"}; + /* the usr dummy usr blogs */ - std::string usrBlog = "I think we should eat more cheese"; - std::string Blog2 = "today was so cool, i got attacked by fifty ninja while buying a loaf so i used my paper bag to suffocate each of them to death at hyper speed"; - std::string Blog3 = "Nuthins up"; - std::string Blog4 = "stop bothering me"; - std::string Blog5 = "I'm really a boring person and having nothin interesting to say"; - + std::string B1 = "I think we should eat more cheese"; + std::string B2 = "today was so cool, i got attacked by fifty ninja while buying a loaf so i used my paper bag to suffocate each of them to death at hyper speed"; + std::string B3 = "Nuthins up"; + std::string B4 = "stop bothering me"; + std::string B5 = "I'm really a boring person and having nothin interesting to say"; + std::string blogs[5] = {B1, B2, B3, B4, B5}; - time_t time1, time2, time3, time4, time5; // times of blogs + /* fill up maps: first usrblogset with empty blogs */ - /*** populate time/blog multimaps and usrBlog map ****/ - std::multimap timeBlog1, timeBlog2, timeBlog3, timeBlog4, timeBlog5; - timeBlog1.insert(std::make_pair(time1, usrBlog)); - timeBlog2.insert(std::make_pair(time2, Blog2)); - timeBlog3.insert(std::make_pair(time3, Blog3)); - timeBlog4.insert(std::make_pair(time4, Blog4)); - timeBlog5.insert(std::make_pair(time5, Blog5)); + std::list::iterator it; - UsrBlogSet.insert(std::make_pair("Usr1", timeBlog1)); - UsrBlogSet.insert(std::make_pair("Mike2", timeBlog2)); - UsrBlogSet.insert(std::make_pair("Mike3", timeBlog2)); - UsrBlogSet.insert(std::make_pair("Mike4", timeBlog2)); - UsrBlogSet.insert(std::make_pair("Mike5", timeBlog5)); + mUsrBlogSet.insert(std::make_pair(mOwnId, emptySet)); + mPeerSongSet.insert(std::make_pair(mOwnId, songs[rand() % 5])); + mPeerStatusSet.insert(std::make_pair(mOwnId, statusSet[rand() % 5])); + for(it = peers.begin(); it!=peers.end();it++) + { + mUsrBlogSet.insert(std::make_pair(*it, emptySet)); + mPeerSongSet.insert(std::make_pair(*it, songs[rand() % 5])); + mPeerStatusSet.insert(std::make_pair(*it, statusSet[rand() % 5])); + } + + /* now fill up blog map */ + + for(int i=0; i < 50 ; i++) + { + std::list::iterator it = peers.begin(); + long int timeStamp; + timeStamp = now + rand() % 2134223; + mUsrBlogSet[mOwnId].insert(std::make_pair(timeStamp, blogs[rand() % 5])); + + for(;it!=peers.end(); it++) + { + timeStamp = now + rand() % 2134223; // a random time for each blog + mUsrBlogSet[*it].insert(std::make_pair(timeStamp, blogs[rand() % 5])); + } + } + + return; } +RsSerialiser* p3Qblog::setupSerialiser() +{ + RsSerialiser *rss = new RsSerialiser(); + rss->addSerialType(new RsQblogSerialiser()); // add in the types we need! + return rss; +} - - +std::list p3Qblog::saveList(bool &cleanup) +{ + std::list saveData; + mBlogMtx.lock(); // LOCK + + cleanup = false; + + /* create save data */ + + std::list::iterator it; + + for(it = mBlogItems.begin(); it != mBlogItems.end() ; it++) + saveData.push_back(*it); + + /*save data created */ + return saveData; +} + +void p3Qblog::saveDone() +{ + mBlogMtx.unlock(); // UNLOCK + return; +} + +bool p3Qblog::loadList(std::list load) +{ + std::list::iterator it; + RsQblogItem *blog; + + #ifdef SERVER_DEBUG + std::cerr << "p3Qblog::loadList() Item Count: " << load.size(); + std::cerr << std::endl; + #endif + + time_t now = time(NULL); + time_t min, max; + + { RsStackMutex stack(mBlogMtx); /********** STACK LOCKED MTX ******/ + + min = now - mStorePeriod; + max = now + RANK_MAX_FWD_OFFSET; + + } /********** STACK LOCKED MTX ******/ + + for(it = load.begin(); it != load.end(); it++) + { + /* switch on type */ + if (NULL != (blog = dynamic_cast(*it))) + { + /* check date -> if old expire */ + if (((time_t) blog->blogMsg.first < min) || + ((time_t) blog->blogMsg.first > max)) + { + #ifdef QBLOG_DEBUG + std::cerr << "p3Blog::loadList() Outside TimeRange :"; + std::cerr << std::endl; + #endif + + /* if outside range -> remove */ + delete blog; + continue; + } + + #ifdef QBLOG_DEBUG + std::cerr << "p3Ranking::loadList() Anon TimeRange ok"; + std::cerr << std::endl; + #endif + + /* make a copy to add into standard map */ + addBlog(blog); + } + else + { + /* cleanup */ + delete (*it); + } + } + + return true; +} + +bool p3Qblog::sort(void) +{ + // TODO sorts blog maps in time order + return true; +} diff --git a/libretroshare/src/services/p3Qblog.h b/libretroshare/src/services/p3Qblog.h index 47088735c..71d8f103e 100644 --- a/libretroshare/src/services/p3Qblog.h +++ b/libretroshare/src/services/p3Qblog.h @@ -6,7 +6,7 @@ * * RetroShare Blog Service. * - * Copyright 2007-2008 by Chris Parker, Robert Fernie. + * Copyright 2007-2008 by Chris Evi-Parker, Robert Fernie. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -34,28 +34,47 @@ #include "rsiface/rsQblog.h" -#include "pqi/pqi.h" -#include "pqi/pqiindic.h" #include "dbase/cachestrapper.h" -#include "services/p3service.h" -#include "util/rsthreads.h" +#include "pqi/pqiservice.h" +#include "pqi/pqistreamer.h" +#include "pqi/p3connmgr.h" +#include "pqi/p3cfgmgr.h" +#include "serialiser/rsserial.h" + +class RsQblogItem; /* to populate maps of blogs */ /*! * contains definitions of the interface and blog information to be manipulated * See RsQblog class for virtual methods documentation */ - class p3Qblog : public RsQblog + class p3Qblog : public CacheSource, public CacheStore, public p3Config { public: - p3Qblog(); + p3Qblog(p3ConnectMgr *connMgr, + uint16_t type, CacheStrapper *cs, CacheTransfer *cft, + std::string sourcedir, std::string storedir, + uint32_t storePeriod); virtual ~p3Qblog (); + + public: + + /******************************* CACHE SOURCE / STORE Interface *********************/ + + /// overloaded functions from Cache Source + virtual bool loadLocalCache(const CacheData &data); + + /// overloaded functions from Cache Store + virtual int loadCache(const CacheData &data); + + /******************************* CACHE SOURCE / STORE Interface *********************/ + + public: virtual bool setStatus(const std::string &status); virtual bool getStatus(std::map &usrStatus); virtual bool setFilterSwitch(bool &filterSwitch); - virtual bool getFriendList(std::list &friendList); virtual bool getFilterSwitch(void); virtual bool addToFilter(std::string &usrId); virtual bool removeFiltFriend(std::string &usrId); @@ -63,30 +82,78 @@ virtual bool setProfile(const std::string &favSong); virtual bool sendBlog(const std::string &msg); virtual bool getBlogs(std::map< std::string, std::multimap > &blogs); + + /* + * to load and transform cache source to normal attribute format of a blog message + * @param filename ?? TODO + * @param source ?? TODO + */ + bool loadBlogFile(std::string filename, std::string src); + + /* + * add a blog item to maps + * @param newBlog a blog item from a peer or yourself + */ + bool addBlog(RsQblogItem *newBlog); + + /* + * post our blog to our friends, connectivity function + */ + bool postBlogs(void); + + /* + * sort blog maps in time order + */ + bool sort(void); + + // ?? + pqistreamer *createStreamer(std::string file, std::string src, bool reading); + + + protected: + + /// p3Config STUFF + virtual RsSerialiser *setupSerialiser(); + /// p3Config STUFF + virtual std::list saveList(bool &cleanup); + /// p3Config STUFF + virtual bool loadList(std::list load); + /// p3Config STUFF + virtual void saveDone(void); + private: - /// contains the list of ids usr only wants to see - std::list FilterList; - /// determines whether filter is activated or not - bool FilterSwitch; - /// the current usr - std::string usr; - /// favorite song of usr, consider sending pathfile to d/l - std::string FavSong; - /// list of friends - std::list FriendList; - /// usr and fav song - std::map FriendSongset; - /// usr and current status - std::map FriendStatusSet; - /// contain usr and their blogs - std::map< std::string, std::multimap > UsrBlogSet; - - /// loads dummy data for testing - void loadDummy(void); + /// handles connection to peers + p3ConnectMgr *mConnMgr; + /// for locking files provate members below + RsMutex mBlogMtx; + /// the current usr + std::string mOwnId; + + /// contains the list of ids usr only wants to see + std::list mFilterList; + /// determines whether filter is activated or not + bool mFilterSwitch; + /// usr and fav song + std::map mPeerSongSet; + /// usr and current status + std::map mPeerStatusSet; + /// contain usr and their blogs + std::map< std::string, std::multimap > mUsrBlogSet; + //fills up above sets + std::list mBlogItems; + //how long to keep posts + uint32_t mStorePeriod; + // to track updates + bool mUpdated; + + /* + * load dummy data + */ + void loadDummy(void); + }; - #endif /*P3QBLOG_H_*/ diff --git a/libretroshare/src/upnp/upnputil.h b/libretroshare/src/upnp/upnputil.h index 61d6332e2..df1e14db8 100644 --- a/libretroshare/src/upnp/upnputil.h +++ b/libretroshare/src/upnp/upnputil.h @@ -16,9 +16,9 @@ #include #define snprintf _snprintf #endif -#include "miniwget.h" -#include "miniupnpc.h" -#include "upnpcommands.h" +#include +#include +#include /* protofix() checks if protocol is "UDP" or "TCP" * returns NULL if not */