persist user_data (following and DMs)

This commit is contained in:
Miguel Freitas 2013-10-08 22:37:29 -03:00
parent 3cce4ae313
commit 4c33706c40
3 changed files with 121 additions and 15 deletions

View File

@ -46,21 +46,6 @@ static map<std::string, torrent_handle> m_userTorrent;
static std::string m_preferredSpamLang = "[en]";
static std::string m_receivedSpamMsgStr;
static std::string m_receivedSpamUserStr;
// in-memory unencrypted DMs
struct StoredDirectMsg {
int64 m_utcTime;
std::string m_text;
bool m_fromMe;
};
// in-memory data per wallet user
struct UserData {
std::set<std::string> m_following;
// m_directmsg key is the other username
std::map<std::string, std::list<StoredDirectMsg> > m_directmsg;
};
static std::map<std::string,UserData> m_users;
sha1_hash dhtTargetHash(std::string const &username, std::string const &resource, std::string const &type)
@ -175,6 +160,20 @@ void ThreadWaitExtIP()
//settings.min_announce_interval = 60; // test
ses->set_settings(settings);
boost::filesystem::path userDataPath = GetDataDir() / "user_data";
loadUserData(userDataPath.string(), m_users);
printf("loaded user_data for %d users\n", m_users.size());
// now restart the user torrents (all m_following)
std::map<std::string,UserData>::const_iterator i;
for (i = m_users.begin(); i != m_users.end(); ++i) {
UserData const &data = i->second;
BOOST_FOREACH(string username, data.m_following) {
startTorrentUser(username);
}
}
printf("libtorrent + dht started\n");
}
@ -452,6 +451,13 @@ void stopSessionTorrent()
delete ses;
ses = NULL;
}
if( m_users.size() ) {
printf("saving user_data (followers and DMs)...\n");
boost::filesystem::path userDataPath = GetDataDir() / "user_data";
saveUserData(userDataPath.string(), m_users);
}
printf("libtorrent + dht stopped\n");
}

View File

@ -1,10 +1,14 @@
#include "twister_utils.h"
#include <libtorrent/session.hpp>
#include <libtorrent/bencode.hpp>
#include <boost/foreach.hpp>
#include <stdio.h>
using namespace std;
using namespace boost;
twister_utils::twister_utils()
{
@ -125,3 +129,80 @@ entry jsonToEntry(const Value &v)
}
int saveUserData(std::string const& filename, std::map<std::string,UserData> const &users)
{
entry userEntry;
std::map<std::string,UserData>::const_iterator i;
for (i = users.begin(); i != users.end(); ++i) {
UserData const &data = i->second;
entry &dataEntry = userEntry[i->first];
entry &followingEntry = dataEntry["following"];
BOOST_FOREACH( std::string const &n, data.m_following) {
followingEntry.list().push_back(n);
}
entry &dmEntry = dataEntry["dm"];
std::map<std::string, std::list<StoredDirectMsg> >::const_iterator j;
for (j = data.m_directmsg.begin(); j != data.m_directmsg.end(); ++j) {
std::list<StoredDirectMsg> const &stoDmList = j->second;
entry &stoDmLstEntry = dmEntry[j->first];
BOOST_FOREACH( StoredDirectMsg const &dm, stoDmList) {
entry stoDmEntry;
stoDmEntry["time"] = dm.m_utcTime;
stoDmEntry["text"] = dm.m_text;
stoDmEntry["fromMe"] = dm.m_fromMe;
stoDmLstEntry.list().push_back(stoDmEntry);
}
}
}
std::vector<char> buf;
bencode(std::back_inserter(buf), userEntry);
return save_file(filename, buf);
}
int loadUserData(std::string const& filename, std::map<std::string,UserData> &users)
{
std::vector<char> in;
if (load_file(filename, in) == 0) {
lazy_entry userEntry;
error_code ec;
if (lazy_bdecode(&in[0], &in[0] + in.size(), userEntry, ec) == 0) {
for( int i = 0; i < userEntry.dict_size(); i++) {
UserData data;
const lazy_entry *dataEntry = userEntry.dict_at(i).second;
const lazy_entry *followingEntry = dataEntry->dict_find("following");
for( int j = 0; j < followingEntry->list_size(); j++ ) {
data.m_following.insert( followingEntry->list_string_value_at(j) );
}
const lazy_entry *dmEntry = dataEntry->dict_find("dm");
for( int j = 0; j < dmEntry->dict_size(); j++ ) {
const lazy_entry *stoDmLstEntry = dmEntry->dict_at(j).second;
for( int k = 0; k < stoDmLstEntry->list_size(); k++ ) {
const lazy_entry *stoDmEntry = stoDmLstEntry->list_at(k);
StoredDirectMsg dm;
dm.m_text = stoDmEntry->dict_find_string_value("text");
dm.m_utcTime = stoDmEntry->dict_find_int_value("time");
dm.m_fromMe = stoDmEntry->dict_find_int_value("fromMe");
data.m_directmsg[dmEntry->dict_at(j).first].push_back(dm);
}
}
users[userEntry.dict_at(i).first] = data;
}
return 0;
}
}
return -1;
}

View File

@ -6,6 +6,22 @@
#include <string>
#include <vector>
#include <set>
// in-memory unencrypted DMs
struct StoredDirectMsg {
int64_t m_utcTime;
std::string m_text;
bool m_fromMe;
};
// in-memory data per wallet user
struct UserData {
std::set<std::string> m_following;
// m_directmsg key is the other username
std::map<std::string, std::list<StoredDirectMsg> > m_directmsg;
};
class twister_utils
{
@ -19,4 +35,7 @@ int save_file(std::string const& filename, std::vector<char>& v);
json_spirit::Value entryToJson(const libtorrent::entry &e);
libtorrent::entry jsonToEntry(const json_spirit::Value &v);
int saveUserData(std::string const& filename, std::map<std::string,UserData> const &users);
int loadUserData(std::string const& filename, std::map<std::string,UserData> &users);
#endif // TWISTER_UTILS_H