merged upstream/master

This commit is contained in:
csoler 2018-01-16 23:03:26 +01:00
commit 95e8fc4404
38 changed files with 785 additions and 340 deletions

View File

@ -236,8 +236,8 @@ public:
mForumHandler(ifaces.mGxsForums),
mServiceControlHandler(ifaces.mServiceControl),
mFileSearchHandler(sts, ifaces.mNotify, ifaces.mTurtle, ifaces.mFiles),
mFileSharingHandler(sts, ifaces.mFiles),
mTransfersHandler(sts, ifaces.mFiles, ifaces.mPeers),
mFileSharingHandler(sts, ifaces.mFiles, *ifaces.mNotify),
mTransfersHandler(sts, ifaces.mFiles, ifaces.mPeers, *ifaces.mNotify),
mChatHandler(sts, ifaces.mNotify, ifaces.mMsgs, ifaces.mPeers, ifaces.mIdentity, &mPeersHandler),
mApiPluginHandler(sts, ifaces),
mChannelsHandler(ifaces.mGxsChannels),

View File

@ -45,6 +45,7 @@ StreamBase& operator << (StreamBase& left, ChatHandler::Msg& m)
{
left << makeKeyValueReference("incoming", m.incoming)
<< makeKeyValueReference("was_send", m.was_send)
<< makeKeyValueReference("read", m.read)
<< makeKeyValueReference("author_id", m.author_id)
<< makeKeyValueReference("author_name", m.author_name)
<< makeKeyValueReference("msg", m.msg)
@ -112,6 +113,8 @@ StreamBase& operator << (StreamBase& left, ChatHandler::ChatInfo& info)
{
left << makeKeyValueReference("remote_author_id", info.remote_author_id)
<< makeKeyValueReference("remote_author_name", info.remote_author_name)
<< makeKeyValueReference("own_author_id", info.own_author_id)
<< makeKeyValueReference("own_author_name", info.own_author_name)
<< makeKeyValueReference("is_broadcast", info.is_broadcast)
<< makeKeyValueReference("is_distant_chat_id", info.is_distant_chat_id)
<< makeKeyValueReference("is_lobby", info.is_lobby)
@ -174,8 +177,13 @@ ChatHandler::ChatHandler(StateTokenServer *sts, RsNotify *notify, RsMsgs *msgs,
addResourceHandler("get_invitations_to_lobby", this, &ChatHandler::handleGetInvitationsToLobby);
addResourceHandler("answer_to_invitation", this, &ChatHandler::handleAnswerToInvitation);
addResourceHandler("lobby_participants", this, &ChatHandler::handleLobbyParticipants);
addResourceHandler("get_default_identity_for_chat_lobby", this, &ChatHandler::handleGetDefaultIdentityForChatLobby);
addResourceHandler("set_default_identity_for_chat_lobby", this, &ChatHandler::handleSetDefaultIdentityForChatLobby);
addResourceHandler("get_identity_for_chat_lobby", this, &ChatHandler::handleGetIdentityForChatLobby);
addResourceHandler("set_identity_for_chat_lobby", this, &ChatHandler::handleSetIdentityForChatLobby);
addResourceHandler("messages", this, &ChatHandler::handleMessages);
addResourceHandler("send_message", this, &ChatHandler::handleSendMessage);
addResourceHandler("send_message", this, &ChatHandler::handleSendMessage);
addResourceHandler("mark_message_as_read", this, &ChatHandler::handleMarkMessageAsRead);
addResourceHandler("mark_chat_as_read", this, &ChatHandler::handleMarkChatAsRead);
addResourceHandler("info", this, &ChatHandler::handleInfo);
addResourceHandler("receive_status", this, &ChatHandler::handleReceiveStatus);
@ -194,13 +202,13 @@ ChatHandler::~ChatHandler()
void ChatHandler::notifyChatMessage(const ChatMessage &msg)
{
RS_STACK_MUTEX(mMtx); /********** LOCKED **********/
RS_STACK_MUTEX(mMtx); // ********** LOCKED **********
mRawMsgs.push_back(msg);
}
void ChatHandler::notifyChatCleared(const ChatId &chat_id)
{
RS_STACK_MUTEX(mMtx); /********** LOCKED **********/
RS_STACK_MUTEX(mMtx); // ********** LOCKED **********
//Remove processed messages
std::list<Msg>& msgs = mMsgs[chat_id];
msgs.clear();
@ -219,14 +227,14 @@ void ChatHandler::notifyChatCleared(const ChatId &chat_id)
void ChatHandler::notifyChatStatus(const ChatId &chat_id, const std::string &status)
{
RS_STACK_MUTEX(mMtx); /********** LOCKED **********/
RS_STACK_MUTEX(mMtx); // ********** LOCKED **********
locked_storeTypingInfo(chat_id, status);
}
void ChatHandler::notifyChatLobbyEvent(uint64_t lobby_id, uint32_t event_type,
const RsGxsId &nickname, const std::string& any_string)
{
RS_STACK_MUTEX(mMtx); /********** LOCKED **********/
RS_STACK_MUTEX(mMtx); // ********** LOCKED **********
if(event_type == RS_CHAT_LOBBY_EVENT_PEER_STATUS)
{
locked_storeTypingInfo(ChatId(lobby_id), any_string, nickname);
@ -237,14 +245,14 @@ void ChatHandler::notifyListChange(int list, int /*type*/)
{
if(list == NOTIFY_LIST_CHAT_LOBBY_INVITATION)
{
RS_STACK_MUTEX(mMtx); /********** LOCKED **********/
RS_STACK_MUTEX(mMtx); // ********** LOCKED **********
mStateTokenServer->replaceToken(mInvitationsStateToken);
}
}
void ChatHandler::tick()
{
RS_STACK_MUTEX(mMtx); /********** LOCKED **********/
RS_STACK_MUTEX(mMtx); // ********** LOCKED **********
// first fetch lobbies
std::vector<Lobby> lobbies;
@ -429,16 +437,21 @@ void ChatHandler::tick()
}
else if(msg.chat_id.isDistantChatId())
{
RsIdentityDetails details;
RsIdentityDetails detailsRemoteIdentity;
RsIdentityDetails detailsOwnIdentity;
DistantChatPeerInfo dcpinfo;
if( !gxs_id_failed &&
rsMsgs->getDistantChatStatus(
msg.chat_id.toDistantChatId(), dcpinfo ) &&
mRsIdentity->getIdDetails(dcpinfo.to_id, details) )
msg.chat_id.toDistantChatId(), dcpinfo )
&& mRsIdentity->getIdDetails(dcpinfo.to_id, detailsRemoteIdentity)
&& mRsIdentity->getIdDetails(dcpinfo.own_id, detailsOwnIdentity))
{
info.remote_author_id = details.mId.toStdString();
info.remote_author_name = details.mNickname;
info.remote_author_id = detailsRemoteIdentity.mId.toStdString();
info.remote_author_name = detailsRemoteIdentity.mNickname;
info.own_author_id = detailsOwnIdentity.mId.toStdString();
info.own_author_name = detailsOwnIdentity.mNickname;
}
else
{
@ -862,7 +875,7 @@ void ChatHandler::locked_storeTypingInfo(const ChatId &chat_id, std::string stat
void ChatHandler::handleWildcard(Request &/*req*/, Response &resp)
{
RS_STACK_MUTEX(mMtx); /********** LOCKED **********/
RS_STACK_MUTEX(mMtx); // ********** LOCKED **********
resp.mDataStream.getStreamToMember();
for(std::map<ChatId, std::list<Msg> >::iterator mit = mMsgs.begin(); mit != mMsgs.end(); ++mit)
{
@ -876,7 +889,7 @@ void ChatHandler::handleLobbies(Request &/*req*/, Response &resp)
tick();
{
RS_STACK_MUTEX(mMtx); /********** LOCKED **********/
RS_STACK_MUTEX(mMtx); // ********** LOCKED **********
resp.mDataStream.getStreamToMember();
for(std::vector<Lobby>::iterator vit = mLobbies.begin(); vit != mLobbies.end(); ++vit)
{
@ -1015,7 +1028,7 @@ void ChatHandler::handleAnswerToInvitation(Request& req, Response& resp)
ResponseTask* ChatHandler::handleLobbyParticipants(Request &req, Response &resp)
{
RS_STACK_MUTEX(mMtx); /********** LOCKED **********/
RS_STACK_MUTEX(mMtx); // ********** LOCKED **********
ChatId id(req.mPath.top());
if(!id.isLobbyId())
@ -1032,6 +1045,82 @@ ResponseTask* ChatHandler::handleLobbyParticipants(Request &req, Response &resp)
return new SendLobbyParticipantsTask(mRsIdentity, mit->second);
}
void ChatHandler::handleGetDefaultIdentityForChatLobby(Request& req, Response& resp)
{
RsGxsId gxsId;
mRsMsgs->getDefaultIdentityForChatLobby(gxsId);
resp.mDataStream << makeKeyValue("gxs_id", gxsId.toStdString());
resp.setOk();
}
void ChatHandler::handleSetDefaultIdentityForChatLobby(Request& req, Response& resp)
{
std::string gxs_id;
req.mStream << makeKeyValueReference("gxs_id", gxs_id);
RsGxsId gxsId(gxs_id);
if(gxsId.isNull())
{
resp.setFail("Error: gxs_id must not be null");
return;
}
if(mRsMsgs->setDefaultIdentityForChatLobby(gxsId))
resp.setOk();
else
resp.setFail("Failure to change default identity for chat lobby");
}
void ChatHandler::handleGetIdentityForChatLobby(Request& req, Response& resp)
{
RsGxsId gxsId;
std::string chat_id;
req.mStream << makeKeyValueReference("chat_id", chat_id);
ChatId chatId(chat_id);
if(chatId.isNotSet())
{
resp.setFail("Error: chat_id must not be null");
return;
}
if(mRsMsgs->getIdentityForChatLobby(chatId.toLobbyId(), gxsId))
{
resp.mDataStream << makeKeyValue("gxs_id", gxsId.toStdString());
resp.setOk();
}
else
resp.setFail();
}
void ChatHandler::handleSetIdentityForChatLobby(Request& req, Response& resp)
{
std::string chat_id;
req.mStream << makeKeyValueReference("chat_id", chat_id);
ChatId chatId(chat_id);
if(chatId.isNotSet())
{
resp.setFail("Error: chat_id must not be null");
return;
}
std::string gxs_id;
req.mStream << makeKeyValueReference("gxs_id", gxs_id);
RsGxsId gxsId(gxs_id);
if(gxsId.isNull())
{
resp.setFail("Error: gxs_id must not be null");
return;
}
if(mRsMsgs->setIdentityForChatLobby(chatId.toLobbyId(), gxsId))
resp.setOk();
else
resp.setFail();
}
void ChatHandler::handleMessages(Request &req, Response &resp)
{
/* G10h4ck: Whithout this the request processing won't happen, copied from
@ -1040,7 +1129,7 @@ void ChatHandler::handleMessages(Request &req, Response &resp)
tick();
{
RS_STACK_MUTEX(mMtx); /********** LOCKED **********/
RS_STACK_MUTEX(mMtx); // ********** LOCKED **********
ChatId id(req.mPath.top());
// make response a list
@ -1082,9 +1171,47 @@ void ChatHandler::handleSendMessage(Request &req, Response &resp)
resp.setFail("failed to send message");
}
void ChatHandler::handleMarkMessageAsRead(Request &req, Response &resp)
{
std::string chat_id_string;
std::string msg_id;
req.mStream << makeKeyValueReference("chat_id", chat_id_string)
<< makeKeyValueReference("msg_id", msg_id);
ChatId chatId(chat_id_string);
if(chatId.isNotSet())
{
resp.setFail(chat_id_string + " is not a valid chat id");
return;
}
std::map<ChatId, std::list<Msg> >::iterator mit = mMsgs.find(chatId);
if(mit == mMsgs.end())
{
resp.setFail("chat not found. Maybe this chat does not have messages yet?");
return;
}
std::list<Msg>& msgs = mit->second;
for(std::list<Msg>::iterator lit = msgs.begin(); lit != msgs.end(); ++lit)
{
if(id((*lit)) == msg_id)
(*lit).read = true;
}
// lobby list contains unread msgs, so update it
if(chatId.isLobbyId())
mStateTokenServer->replaceToken(mLobbiesStateToken);
if(chatId.isPeerId() && mUnreadMsgNotify)
mUnreadMsgNotify->notifyUnreadMsgCountChanged(chatId.toPeerId(), 0);
mStateTokenServer->replaceToken(mMsgStateToken);
mStateTokenServer->replaceToken(mUnreadMsgsStateToken);
}
void ChatHandler::handleMarkChatAsRead(Request &req, Response &resp)
{
RS_STACK_MUTEX(mMtx); /********** LOCKED **********/
RS_STACK_MUTEX(mMtx); // ********** LOCKED **********
ChatId id(req.mPath.top());
if(id.isNotSet())
@ -1109,12 +1236,13 @@ void ChatHandler::handleMarkChatAsRead(Request &req, Response &resp)
if(id.isPeerId() && mUnreadMsgNotify)
mUnreadMsgNotify->notifyUnreadMsgCountChanged(id.toPeerId(), 0);
mStateTokenServer->replaceToken(mMsgStateToken);
mStateTokenServer->replaceToken(mUnreadMsgsStateToken);
}
void ChatHandler::handleInfo(Request &req, Response &resp)
{
RS_STACK_MUTEX(mMtx); /********** LOCKED **********/
RS_STACK_MUTEX(mMtx); // ********** LOCKED **********
ChatId id(req.mPath.top());
if(id.isNotSet())
{
@ -1150,7 +1278,8 @@ protected:
// lobby and distant require to fetch a gxs_id
if(mId.isLobbyId())
{
requestGxsId(mInfo.author_id);
if(!mInfo.author_id.isNull())
requestGxsId(mInfo.author_id);
}
else if(mId.isDistantChatId())
{
@ -1163,6 +1292,7 @@ protected:
else
{
std::string name = "BUG: case not handled in SendTypingLabelInfo";
RsGxsId author_id = mInfo.author_id;
if(mId.isPeerId())
{
name = mPeers->getPeerName(mId.toPeerId());
@ -1172,6 +1302,7 @@ protected:
DistantChatPeerInfo dcpinfo ;
rsMsgs->getDistantChatStatus(mId.toDistantChatId(), dcpinfo);
name = getName(dcpinfo.to_id);
author_id = dcpinfo.to_id;
}
else if(mId.isLobbyId())
{
@ -1183,6 +1314,7 @@ protected:
}
uint32_t ts = mInfo.timestamp;
resp.mDataStream << makeKeyValueReference("author_name", name)
<< makeKeyValue("author_id", author_id.toStdString())
<< makeKeyValueReference("timestamp", ts)
<< makeKeyValueReference("status_string", mInfo.status);
resp.mStateToken = mInfo.state_token;
@ -1194,7 +1326,7 @@ protected:
ResponseTask* ChatHandler::handleReceiveStatus(Request &req, Response &resp)
{
RS_STACK_MUTEX(mMtx); /********** LOCKED **********/
RS_STACK_MUTEX(mMtx); // ********** LOCKED **********
ChatId id(req.mPath.top());
if(id.isNotSet())
{
@ -1207,6 +1339,7 @@ ResponseTask* ChatHandler::handleReceiveStatus(Request &req, Response &resp)
locked_storeTypingInfo(id, "");
mit = mTypingLabelInfo.find(id);
}
return new SendTypingLabelInfo(mRsIdentity, mRsPeers, id, mit->second);
}
@ -1228,7 +1361,7 @@ void ChatHandler::handleSendStatus(Request &req, Response &resp)
void ChatHandler::handleUnreadMsgs(Request &/*req*/, Response &resp)
{
RS_STACK_MUTEX(mMtx); /********** LOCKED **********/
RS_STACK_MUTEX(mMtx); // ********** LOCKED **********
resp.mDataStream.getStreamToMember();
for( std::map<ChatId, std::list<Msg> >::const_iterator mit = mMsgs.begin();
@ -1309,10 +1442,12 @@ void ChatHandler::handleCloseDistantChatConnexion(Request& req, Response& resp)
{
std::string distant_chat_hex;
req.mStream << makeKeyValueReference("distant_chat_hex", distant_chat_hex);
ChatId chatId(distant_chat_hex);
DistantChatPeerId chat_id(distant_chat_hex);
if (mRsMsgs->closeDistantChatConnexion(chat_id)) resp.setOk();
else resp.setFail("Failed to close distant chat");
if (mRsMsgs->closeDistantChatConnexion(chatId.toDistantChatId()))
resp.setOk();
else
resp.setFail("Failed to close distant chat");
}
void ChatHandler::handleCreateLobby(Request& req, Response& resp)

View File

@ -104,6 +104,8 @@ public:
bool is_distant_chat_id;
bool is_lobby;
bool is_peer;
std::string own_author_id;
std::string own_author_name;
std::string remote_author_id;
std::string remote_author_name;
};
@ -129,8 +131,13 @@ private:
void handleAnswerToInvitation(Request& req, Response& resp);
void handleClearLobby(Request& req, Response& resp);
ResponseTask* handleLobbyParticipants(Request& req, Response& resp);
void handleGetDefaultIdentityForChatLobby(Request& req, Response& resp);
void handleSetDefaultIdentityForChatLobby(Request& req, Response& resp);
void handleGetIdentityForChatLobby(Request& req, Response& resp);
void handleSetIdentityForChatLobby(Request& req, Response& resp);
void handleMessages(Request& req, Response& resp);
void handleSendMessage(Request& req, Response& resp);
void handleSendMessage(Request& req, Response& resp);
void handleMarkMessageAsRead(Request& req, Response& resp);
void handleMarkChatAsRead(Request& req, Response& resp);
void handleInfo(Request& req, Response& resp);
ResponseTask *handleReceiveStatus(Request& req, Response& resp);

View File

@ -31,7 +31,7 @@ FileSearchHandler::~FileSearchHandler()
void FileSearchHandler::notifyTurtleSearchResult(uint32_t search_id, const std::list<TurtleFileInfo>& files)
{
RsStackMutex stackMtx(mMtx); // ********** STACK LOCKED MTX **********
RS_STACK_MUTEX(mMtx); // ********** LOCKED **********
std::map<uint32_t, Search>::iterator mit = mSearches.find(search_id);
if(mit == mSearches.end())
return;
@ -85,7 +85,7 @@ void FileSearchHandler::handleWildcard(Request &req, Response &resp)
}
{
RsStackMutex stackMtx(mMtx); // ********** STACK LOCKED MTX **********
RS_STACK_MUTEX(mMtx); // ********** LOCKED **********
std::map<uint32_t, Search>::iterator mit = mSearches.find(id);
if(mit == mSearches.end())
{
@ -115,7 +115,7 @@ void FileSearchHandler::handleWildcard(Request &req, Response &resp)
else
{
// list searches
RsStackMutex stackMtx(mMtx); // ********** STACK LOCKED MTX **********
RS_STACK_MUTEX(mMtx); // ********** LOCKED **********
resp.mDataStream.getStreamToMember();
for(std::map<uint32_t, Search>::iterator mit = mSearches.begin(); mit != mSearches.end(); ++mit)
{
@ -221,7 +221,7 @@ void FileSearchHandler::handleCreateSearch(Request &req, Response &resp)
}
{
RsStackMutex stackMtx(mMtx); // ********** STACK LOCKED MTX **********
RS_STACK_MUTEX(mMtx); // ********** LOCKED **********
Search& search = mSearches[search_id];
search.mStateToken = mStateTokenServer->getNewToken();
@ -262,7 +262,7 @@ void FileSearchHandler::handleGetSearchResult(Request& req, Response& resp)
}
{
RsStackMutex stackMtx(mMtx); // ********** STACK LOCKED MTX **********
RS_STACK_MUTEX(mMtx); // ********** LOCKED **********
std::map<uint32_t, Search>::iterator mit = mSearches.find(id);
if(mit == mSearches.end())
{

View File

@ -21,8 +21,10 @@
namespace resource_api
{
FileSharingHandler::FileSharingHandler(StateTokenServer *sts, RsFiles *files):
mStateTokenServer(sts), mRsFiles(files)
FileSharingHandler::FileSharingHandler(StateTokenServer *sts, RsFiles *files,
RsNotify& notify):
mStateTokenServer(sts), mRsFiles(files), mNotify(notify),
mMtx("FileSharingHandler Mtx")
{
addResourceHandler("*", this, &FileSharingHandler::handleWildcard);
addResourceHandler("force_check", this, &FileSharingHandler::handleForceCheck);
@ -40,7 +42,30 @@ FileSharingHandler::FileSharingHandler(StateTokenServer *sts, RsFiles *files):
addResourceHandler("download", this, &FileSharingHandler::handleDownload);
mStateToken = mStateTokenServer->getNewToken();
mLocalDirStateToken = mStateTokenServer->getNewToken();
mRemoteDirStateToken = mStateTokenServer->getNewToken();
mNotify.registerNotifyClient(this);
}
FileSharingHandler::~FileSharingHandler()
{
mNotify.unregisterNotifyClient(this);
}
void FileSharingHandler::notifyListChange(int list, int /* type */)
{
if(list == NOTIFY_LIST_DIRLIST_LOCAL)
{
RS_STACK_MUTEX(mMtx);
mStateTokenServer->discardToken(mLocalDirStateToken);
mLocalDirStateToken = mStateTokenServer->getNewToken();
}
else if(list == NOTIFY_LIST_DIRLIST_FRIENDS)
{
RS_STACK_MUTEX(mMtx);
mStateTokenServer->discardToken(mRemoteDirStateToken);
mRemoteDirStateToken = mStateTokenServer->getNewToken();
}
}
void FileSharingHandler::handleWildcard(Request & /*req*/, Response & /*resp*/)
@ -104,6 +129,7 @@ void FileSharingHandler::handleGetSharedDir(Request& req, Response& resp)
<< makeKeyValue("name", dirDetails.name)
<< makeKeyValue("path", dirDetails.path)
<< makeKeyValue("hash", dirDetails.hash.toStdString())
<< makeKeyValue("peer_id", dirDetails.id.toStdString())
<< makeKeyValue("parent_reference", *reinterpret_cast<int*>(&dirDetails.parent))
<< makeKeyValue("reference", *reinterpret_cast<int*>(&dirDetails.ref))
<< makeKeyValue("count", static_cast<int>(dirDetails.count))
@ -140,6 +166,8 @@ void FileSharingHandler::handleGetSharedDir(Request& req, Response& resp)
<< makeKeyValueReference("contain_folders", contain_folders);
}
}
resp.mStateToken = mLocalDirStateToken;
}
void FileSharingHandler::handleSetSharedDir(Request& req, Response& resp)
@ -231,10 +259,16 @@ void FileSharingHandler::handleGetDirectoryParent(Request& req, Response& resp)
FileSearchFlags flags;
if(remote)
{
flags |= RS_FILE_HINTS_REMOTE;
resp.mStateToken = mRemoteDirStateToken;
}
if(local)
{
flags |= RS_FILE_HINTS_LOCAL;
resp.mStateToken = mLocalDirStateToken;
}
DirDetails dirDetails;
mRsFiles->RequestDirDetails(ref, dirDetails, flags);
@ -282,6 +316,7 @@ void FileSharingHandler::handleGetDirectoryParent(Request& req, Response& resp)
<< makeKeyValue("name", dirDetails.name)
<< makeKeyValue("path", dirDetails.path)
<< makeKeyValue("hash", dirDetails.hash.toStdString())
<< makeKeyValue("peer_id", dirDetails.id.toStdString())
<< makeKeyValue("parent_reference", *reinterpret_cast<int*>(&dirDetails.parent))
<< makeKeyValue("reference", *reinterpret_cast<int*>(&dirDetails.ref))
<< makeKeyValue("count", static_cast<int>(dirDetails.count))
@ -334,10 +369,16 @@ void FileSharingHandler::handleGetDirectoryChilds(Request& req, Response& resp)
FileSearchFlags flags;
if(remote)
{
flags |= RS_FILE_HINTS_REMOTE;
resp.mStateToken = mRemoteDirStateToken;
}
if(local)
{
flags |= RS_FILE_HINTS_LOCAL;
resp.mStateToken = mLocalDirStateToken;
}
DirDetails dirDetails;
mRsFiles->RequestDirDetails(ref, dirDetails, flags);
@ -385,6 +426,7 @@ void FileSharingHandler::handleGetDirectoryChilds(Request& req, Response& resp)
<< makeKeyValue("name", dirDetails.name)
<< makeKeyValue("path", dirDetails.path)
<< makeKeyValue("hash", dirDetails.hash.toStdString())
<< makeKeyValue("peer_id", dirDetails.id.toStdString())
<< makeKeyValue("parent_reference", *reinterpret_cast<int*>(&dirDetails.parent))
<< makeKeyValue("reference", *reinterpret_cast<int*>(&dirDetails.ref))
<< makeKeyValue("count", static_cast<int>(dirDetails.count))

View File

@ -22,14 +22,23 @@
#include "StateTokenServer.h"
#include <retroshare/rsfiles.h>
#include <retroshare/rsnotify.h>
#include <util/rsthreads.h>
namespace resource_api
{
class FileSharingHandler: public ResourceRouter
class FileSharingHandler: public ResourceRouter, NotifyClient
{
public:
FileSharingHandler(StateTokenServer* sts, RsFiles* files);
FileSharingHandler(StateTokenServer* sts, RsFiles* files, RsNotify& notify);
~FileSharingHandler();
/**
Derived from NotifyClient
This function may be called from foreign thread
*/
virtual void notifyListChange(int list, int type);
private:
void handleWildcard(Request& req, Response& resp);
@ -48,10 +57,22 @@ private:
void handleDownload(Request& req, Response& resp);
StateToken mStateToken;
/// Token indicating change in local shared files
StateToken mLocalDirStateToken;
/// Token indicating change in remote (friends') shared files
StateToken mRemoteDirStateToken;
StateTokenServer* mStateTokenServer;
/**
Protects mLocalDirStateToken and mRemoteDirStateToken that may be changed in foreign thread
@see FileSharingHandler::notifyListChange(...)
*/
RsMutex mMtx;
RsFiles* mRsFiles;
RsNotify& mNotify;
};
} // namespace resource_api

View File

@ -374,7 +374,7 @@ void IdentityHandler::handleAddContact(Request& req, Response& resp)
mRsIdentity->setAsRegularContact(RsGxsId(gxs_id), true);
{
RsStackMutex stack(mMtx); /********** STACK LOCKED MTX ******/
RS_STACK_MUTEX(mMtx); // ********** LOCKED **********
mStateTokenServer->replaceToken(mStateToken);
}
@ -389,7 +389,7 @@ void IdentityHandler::handleRemoveContact(Request& req, Response& resp)
mRsIdentity->setAsRegularContact(RsGxsId(gxs_id), false);
{
RsStackMutex stack(mMtx); /********** STACK LOCKED MTX ******/
RS_STACK_MUTEX(mMtx); // ********** LOCKED **********
mStateTokenServer->replaceToken(mStateToken);
}

View File

@ -250,6 +250,7 @@ PeersHandler::PeersHandler( StateTokenServer* sts, RsNotify* notify,
addResourceHandler("set_network_options", this, &PeersHandler::handleSetNetworkOptions);
addResourceHandler("get_pgp_options", this, &PeersHandler::handleGetPGPOptions);
addResourceHandler("set_pgp_options", this, &PeersHandler::handleSetPGPOptions);
addResourceHandler("get_node_name", this, &PeersHandler::handleGetNodeName);
addResourceHandler("get_node_options", this, &PeersHandler::handleGetNodeOptions);
addResourceHandler("set_node_options", this, &PeersHandler::handleSetNodeOptions);
addResourceHandler("examine_cert", this, &PeersHandler::handleExamineCert);
@ -266,9 +267,9 @@ PeersHandler::~PeersHandler()
void PeersHandler::notifyListChange(int list, int /* type */)
{
RsStackMutex stack(mMtx); /********** STACK LOCKED MTX ******/
if(list == NOTIFY_LIST_FRIENDS)
{
RS_STACK_MUTEX(mMtx); // ********** LOCKED **********
mStateTokenServer->discardToken(mStateToken);
mStateToken = mStateTokenServer->getNewToken();
}
@ -276,13 +277,13 @@ void PeersHandler::notifyListChange(int list, int /* type */)
void PeersHandler::notifyPeerStatusChanged(const std::string& /*peer_id*/, uint32_t /*state*/)
{
RsStackMutex stack(mMtx); /********** STACK LOCKED MTX ******/
RS_STACK_MUTEX(mMtx); // ********** LOCKED **********
mStateTokenServer->replaceToken(mStateToken);
}
void PeersHandler::notifyPeerHasNewAvatar(std::string /*peer_id*/)
{
RsStackMutex stack(mMtx); /********** STACK LOCKED MTX ******/
RS_STACK_MUTEX(mMtx); // ********** LOCKED **********
mStateTokenServer->replaceToken(mStateToken);
}
@ -294,7 +295,7 @@ void PeersHandler::tick()
{
mOnlinePeers = online;
RsStackMutex stack(mMtx); /********** STACK LOCKED MTX ******/
RS_STACK_MUTEX(mMtx); // ********** LOCKED **********
mStateTokenServer->discardToken(mStateToken);
mStateToken = mStateTokenServer->getNewToken();
}
@ -305,7 +306,7 @@ void PeersHandler::tick()
{
status = statusInfo.status;
RsStackMutex stack(mMtx); /********** STACK LOCKED MTX ******/
RS_STACK_MUTEX(mMtx); // ********** LOCKED **********
mStateTokenServer->discardToken(mStringStateToken);
mStringStateToken = mStateTokenServer->getNewToken();
}
@ -315,7 +316,7 @@ void PeersHandler::tick()
{
custom_state_string = custom_state;
RsStackMutex stack(mMtx); /********** STACK LOCKED MTX ******/
RS_STACK_MUTEX(mMtx); // ********** LOCKED **********
mStateTokenServer->discardToken(mCustomStateToken);
mCustomStateToken = mStateTokenServer->getNewToken();
}
@ -323,7 +324,7 @@ void PeersHandler::tick()
void PeersHandler::notifyUnreadMsgCountChanged(const RsPeerId &peer, uint32_t count)
{
RsStackMutex stack(mMtx); /********** STACK LOCKED MTX ******/
RS_STACK_MUTEX(mMtx); // ********** LOCKED **********
mUnreadMsgsCounts[peer] = count;
mStateTokenServer->replaceToken(mStateToken);
}
@ -459,7 +460,7 @@ void PeersHandler::handleWildcard(Request &req, Response &resp)
{
std::map<RsPeerId, uint32_t> unread_msgs;
{
RsStackMutex stack(mMtx); /********** STACK LOCKED MTX ******/
RS_STACK_MUTEX(mMtx); // ********** LOCKED **********
unread_msgs = mUnreadMsgsCounts;
}
std::list<StatusInfo> statusInfo;
@ -1139,6 +1140,28 @@ void PeersHandler::handleSetPGPOptions(Request& req, Response& resp)
resp.setOk();
}
void PeersHandler::handleGetNodeName(Request& req, Response& resp)
{
std::string peer_id;
req.mStream << makeKeyValueReference("peer_id", peer_id);
RsPeerId peerId(peer_id);
RsPeerDetails detail;
if(!mRsPeers->getPeerDetails(peerId, detail))
{
resp.setFail();
return;
}
resp.mDataStream << makeKeyValue("peer_id", detail.id.toStdString());
resp.mDataStream << makeKeyValue("name", detail.name);
resp.mDataStream << makeKeyValue("location", detail.location);
resp.mDataStream << makeKeyValue("pgp_id", detail.gpg_id.toStdString());
resp.mDataStream << makeKeyValue("last_contact", detail.lastConnect);
resp.setOk();
}
void PeersHandler::handleGetNodeOptions(Request& req, Response& resp)
{
std::string peer_id;
@ -1258,7 +1281,7 @@ void PeersHandler::handleSetNodeOptions(Request& req, Response& resp)
StateToken PeersHandler::getCurrentStateToken()
{
RsStackMutex stack(mMtx); /********** STACK LOCKED MTX ******/
RS_STACK_MUTEX(mMtx); // ********** LOCKED **********
if(mStateToken.isNull())
mStateToken = mStateTokenServer->getNewToken();
return mStateToken;

View File

@ -70,6 +70,7 @@ private:
void handleGetPGPOptions(Request& req, Response& resp);
void handleSetPGPOptions(Request& req, Response& resp);
void handleGetNodeName(Request& req, Response& resp);
void handleGetNodeOptions(Request& req, Response& resp);
void handleSetNodeOptions(Request& req, Response& resp);

View File

@ -57,7 +57,7 @@ RsControlModule::~RsControlModule()
bool RsControlModule::processShouldExit()
{
RsStackMutex stack(mExitFlagMtx);
RS_STACK_MUTEX(mExitFlagMtx); // ********** LOCKED **********
return mProcessShouldExit;
}
@ -158,7 +158,7 @@ void RsControlModule::run()
std::cerr << "RsControlModule::run() reseting passwd." << std::endl;
#endif
{
RsStackMutex stack(mDataMtx); // ********** LOCKED **********
RS_STACK_MUTEX(mDataMtx); // ********** LOCKED **********
mPassword = "";
}
@ -182,7 +182,7 @@ void RsControlModule::run()
std::cerr << "RsControlModule::run() while(wait_for_account_select) mLoadPeerId=" << mLoadPeerId << std::endl;
#endif
usleep(500*1000);
RsStackMutex stack(mDataMtx); // ********** LOCKED **********
RS_STACK_MUTEX(mDataMtx); // ********** LOCKED **********
if(!mLoadPeerId.isNull())
{
@ -238,7 +238,7 @@ void RsControlModule::run()
#endif
{
RsStackMutex stack(mDataMtx); // ********** LOCKED **********
RS_STACK_MUTEX(mDataMtx); // ********** LOCKED **********
mLoadPeerId.clear();
}
}
@ -247,7 +247,7 @@ void RsControlModule::run()
#endif
{
RsStackMutex stack(mDataMtx); // ********** LOCKED **********
RS_STACK_MUTEX(mDataMtx); // ********** LOCKED **********
mFixedPassword = mPassword;
std::cerr << "***Reseting mPasswd " << std::endl;
@ -279,7 +279,7 @@ void RsControlModule::run()
void RsControlModule::handleRunState(Request &, Response &resp)
{
RsStackMutex stack(mDataMtx); // ********** LOCKED **********
RS_STACK_MUTEX(mDataMtx); // ********** LOCKED **********
std::string state;
switch(mRunState)
{
@ -311,7 +311,7 @@ void RsControlModule::handleRunState(Request &, Response &resp)
void RsControlModule::handleIdentities(Request &, Response &resp)
{
RsStackMutex stack(mDataMtx); // ********** LOCKED **********
RS_STACK_MUTEX(mDataMtx); // ********** LOCKED **********
if(mRunState == WAITING_INIT || mRunState == FATAL_ERROR)
{
resp.setFail("Retroshare is not initialised. Operation not possible.");
@ -337,7 +337,7 @@ void RsControlModule::handleIdentities(Request &, Response &resp)
void RsControlModule::handleLocations(Request &, Response &resp)
{
RsStackMutex stack(mDataMtx); // ********** LOCKED **********
RS_STACK_MUTEX(mDataMtx); // ********** LOCKED **********
if(mRunState == WAITING_INIT || mRunState == FATAL_ERROR)
{
resp.setFail("Retroshare is not initialised. Operation not possible.");
@ -370,7 +370,7 @@ void RsControlModule::handleLocations(Request &, Response &resp)
void RsControlModule::handlePassword(Request &req, Response &resp)
{
RsStackMutex stack(mDataMtx); // ********** LOCKED **********
RS_STACK_MUTEX(mDataMtx); // ********** LOCKED **********
std::string passwd;
req.mStream << makeKeyValueReference("password", passwd);
if(passwd != "")// && mWantPassword)
@ -398,7 +398,7 @@ void RsControlModule::handlePassword(Request &req, Response &resp)
void RsControlModule::handleLogin(Request &req, Response &resp)
{
RsStackMutex stack(mDataMtx); // ********** LOCKED **********
RS_STACK_MUTEX(mDataMtx); // ********** LOCKED **********
if(mRunState != WAITING_ACCOUNT_SELECT)
{
resp.setFail("Operation not allowed in this runstate. Login is only allowed rigth after initialisation.");
@ -411,7 +411,7 @@ void RsControlModule::handleLogin(Request &req, Response &resp)
void RsControlModule::handleShutdown(Request &, Response &resp)
{
RsStackMutex stack(mExitFlagMtx); // ********** LOCKED **********
RS_STACK_MUTEX(mExitFlagMtx); // ********** LOCKED **********
mProcessShouldExit = true;
resp.setOk();
}
@ -514,7 +514,7 @@ void RsControlModule::handleCreateLocation(Request &req, Response &resp)
std::string err_string;
// give the password to the password callback
{
RsStackMutex stack(mDataMtx); // ********** LOCKED **********
RS_STACK_MUTEX(mDataMtx); // ********** LOCKED **********
mPassword = pgp_password;
mFixedPassword = pgp_password;
}
@ -522,7 +522,7 @@ void RsControlModule::handleCreateLocation(Request &req, Response &resp)
// clear fixed password to restore normal password operation
// {
// RsStackMutex stack(mDataMtx); // ********** LOCKED **********
// RS_STACK_MUTEX(mDataMtx); // ********** LOCKED **********
// mFixedPassword = "";
// }
@ -532,7 +532,7 @@ void RsControlModule::handleCreateLocation(Request &req, Response &resp)
RsInit::LoadPassword(ssl_password);
// trigger login in init thread
{
RsStackMutex stack(mDataMtx); // ********** LOCKED **********
RS_STACK_MUTEX(mDataMtx); // ********** LOCKED **********
mLoadPeerId = ssl_id;
}
resp.mDataStream << makeKeyValueReference("pgp_id", pgp_id)
@ -561,7 +561,7 @@ bool RsControlModule::askForDeferredSelfSignature(const void *data, const uint32
void RsControlModule::setRunState(RunState s, std::string errstr)
{
RsStackMutex stack(mDataMtx); // ********** LOCKED **********
RS_STACK_MUTEX(mDataMtx); // ********** LOCKED **********
mRunState = s;
mLastErrorString = errstr;
mStateTokenServer->replaceToken(mStateToken);

View File

@ -64,19 +64,19 @@ StateTokenServer::StateTokenServer():
StateToken StateTokenServer::getNewToken()
{
RsStackMutex stack(mMtx); /********** STACK LOCKED MTX ******/
RS_STACK_MUTEX(mMtx); // ********** LOCKED **********
return locked_getNewToken();
}
void StateTokenServer::discardToken(StateToken token)
{
RsStackMutex stack(mMtx); /********** STACK LOCKED MTX ******/
RS_STACK_MUTEX(mMtx); // ********** LOCKED **********
locked_discardToken(token);
}
void StateTokenServer::replaceToken(StateToken &token)
{
RsStackMutex stack(mMtx); /********** STACK LOCKED MTX ******/
RS_STACK_MUTEX(mMtx); // ********** LOCKED **********
locked_discardToken(token);
token = locked_getNewToken();
}
@ -89,13 +89,13 @@ void StateTokenServer::registerTickClient(Tickable *c)
// avoid double registration
unregisterTickClient(c);
RsStackMutex stack(mClientsMtx); /********** STACK LOCKED MTX ***********/
RS_STACK_MUTEX(mClientsMtx); // ********** LOCKED **********
mTickClients.push_back(c);
}
void StateTokenServer::unregisterTickClient(Tickable *c)
{
RsStackMutex stack(mClientsMtx); /********** STACK LOCKED MTX ***********/
RS_STACK_MUTEX(mClientsMtx); // ********** LOCKED **********
std::vector<Tickable*>::iterator vit = std::find(mTickClients.begin(), mTickClients.end(), c);
if(vit != mTickClients.end())
mTickClients.erase(vit);
@ -104,14 +104,14 @@ void StateTokenServer::unregisterTickClient(Tickable *c)
void StateTokenServer::handleWildcard(Request &req, Response &resp)
{
{
RsStackMutex stack(mClientsMtx); /********** STACK LOCKED MTX ***********/
RS_STACK_MUTEX(mClientsMtx); // ********** LOCKED **********
for(std::vector<Tickable*>::iterator vit = mTickClients.begin(); vit != mTickClients.end(); ++vit)
{
(*vit)->tick();
}
}
RsStackMutex stack(mMtx); /********** STACK LOCKED MTX ******/
RS_STACK_MUTEX(mMtx); // ********** LOCKED **********
// want to lookpup many tokens at once, return a list of invalid tokens
// TODO: make generic list serialiser/deserialiser
resp.mDataStream.getStreamToMember();

View File

@ -6,8 +6,10 @@
namespace resource_api
{
TransfersHandler::TransfersHandler(StateTokenServer *sts, RsFiles *files, RsPeers *peers):
mStateTokenServer(sts), mFiles(files), mRsPeers(peers), mLastUpdateTS(0)
TransfersHandler::TransfersHandler(StateTokenServer *sts, RsFiles *files, RsPeers *peers,
RsNotify& notify):
mStateTokenServer(sts), mFiles(files), mRsPeers(peers), mLastUpdateTS(0), mNotify(notify),
mMtx("TransfersHandler")
{
addResourceHandler("*", this, &TransfersHandler::handleWildcard);
addResourceHandler("downloads", this, &TransfersHandler::handleDownloads);
@ -15,11 +17,23 @@ TransfersHandler::TransfersHandler(StateTokenServer *sts, RsFiles *files, RsPeer
addResourceHandler("control_download", this, &TransfersHandler::handleControlDownload);
mStateToken = mStateTokenServer->getNewToken();
mStateTokenServer->registerTickClient(this);
mNotify.registerNotifyClient(this);
}
TransfersHandler::~TransfersHandler()
{
mStateTokenServer->unregisterTickClient(this);
mNotify.unregisterNotifyClient(this);
}
void TransfersHandler::notifyListChange(int list, int /* type */)
{
if(list == NOTIFY_LIST_TRANSFERLIST)
{
RS_STACK_MUTEX(mMtx); // ********** LOCKED **********
mStateTokenServer->discardToken(mStateToken);
mStateToken = mStateTokenServer->getNewToken();
}
}
const int UPDATE_PERIOD_SECONDS = 5;

View File

@ -5,18 +5,26 @@
#include <retroshare/rsfiles.h>
#include <retroshare/rspeers.h>
#include <retroshare/rsnotify.h>
namespace resource_api
{
class TransfersHandler: public ResourceRouter, Tickable
class TransfersHandler: public ResourceRouter, Tickable, NotifyClient
{
public:
TransfersHandler(StateTokenServer* sts, RsFiles* files, RsPeers *peers);
TransfersHandler(StateTokenServer* sts, RsFiles* files, RsPeers *peers, RsNotify& notify);
virtual ~TransfersHandler();
/**
Derived from NotifyClient
This function may be called from foreign thread
*/
virtual void notifyListChange(int list, int type);
// from Tickable
virtual void tick();
private:
void handleWildcard(Request& req, Response& resp);
void handleControlDownload(Request& req, Response& resp);
@ -26,6 +34,13 @@ private:
StateTokenServer* mStateTokenServer;
RsFiles* mFiles;
RsPeers* mRsPeers;
RsNotify& mNotify;
/**
Protects mStateToken that may be changed in foreign thread
@see TransfersHandler::notifyListChange(...)
*/
RsMutex mMtx;
StateToken mStateToken;
time_t mLastUpdateTS;

View File

@ -113,6 +113,8 @@ const std::string RsGeneralDataService::MSG_META_STATUS = KEY_MSG_STATUS;
const uint32_t RsGeneralDataService::GXS_MAX_ITEM_SIZE = 1572864; // 1.5 Mbytes
static const uint32_t CACHE_ENTRY_GRACE_PERIOD = 600 ; // 10 minutes
static int addColumn(std::list<std::string> &list, const std::string &attribute)
{
list.push_back(attribute);
@ -486,15 +488,13 @@ bool RsDataService::finishReleaseUpdate(int release, bool result)
return result;
}
RsGxsGrpMetaData* RsDataService::locked_getGrpMeta(RetroCursor &c, int colOffset)
RsGxsGrpMetaData* RsDataService::locked_getGrpMeta(RetroCursor &c, int colOffset,bool use_cache)
{
#ifdef RS_DATA_SERVICE_DEBUG
std::cerr << "RsDataService::locked_getGrpMeta()";
std::cerr << std::endl;
#endif
RsGxsGrpMetaData* grpMeta = new RsGxsGrpMetaData();
bool ok = true;
// for extracting raw data
@ -505,6 +505,25 @@ RsGxsGrpMetaData* RsDataService::locked_getGrpMeta(RetroCursor &c, int colOffset
// grpId
std::string tempId;
c.getString(mColGrpMeta_GrpId + colOffset, tempId);
RsGxsGrpMetaData* grpMeta ;
RsGxsGroupId grpId(tempId) ;
if(use_cache)
{
auto it = mGrpMetaDataCache.find(grpId) ;
if(it != mGrpMetaDataCache.end())
grpMeta = it->second ;
else
{
grpMeta = new RsGxsGrpMetaData();
mGrpMetaDataCache[grpId] = grpMeta ;
}
}
else
grpMeta = new RsGxsGrpMetaData();
grpMeta->mGroupId = RsGxsGroupId(tempId);
c.getString(mColGrpMeta_NxsIdentity + colOffset, tempId);
grpMeta->mAuthorId = RsGxsId(tempId);
@ -556,9 +575,11 @@ RsGxsGrpMetaData* RsDataService::locked_getGrpMeta(RetroCursor &c, int colOffset
if(ok)
return grpMeta;
else
delete grpMeta;
return NULL;
{
if(!use_cache)
delete grpMeta;
return NULL;
}
}
RsNxsGrp* RsDataService::locked_getGroup(RetroCursor &c)
@ -876,7 +897,7 @@ int RsDataService::storeGroup(const std::list<RsNxsGrp*>& grp)
cv.put(KEY_GRP_STATUS, (int32_t)grpMetaPtr->mGroupStatus);
cv.put(KEY_GRP_LAST_POST, (int32_t)grpMetaPtr->mLastPost);
locked_clearGrpMetaCache(grpMetaPtr->mGroupId);
locked_updateGrpMetaCache(*grpMetaPtr);
if (!mDb->sqlInsert(GRP_TABLE_NAME, "", cv))
{
@ -892,10 +913,46 @@ int RsDataService::storeGroup(const std::list<RsNxsGrp*>& grp)
return ret;
}
void RsDataService::locked_updateGrpMetaCache(const RsGxsGrpMetaData& meta)
{
auto it = mGrpMetaDataCache.find(meta.mGroupId) ;
if(it != mGrpMetaDataCache.end())
*(it->second) = meta ;
}
void RsDataService::locked_clearGrpMetaCache(const RsGxsGroupId& gid)
{
mGrpMetaDataCache.erase(gid) ; // cleans existing cache entry
mGrpMetaDataCache_ContainsAllDatabase = false;
time_t now = time(NULL) ;
auto it = mGrpMetaDataCache.find(gid) ;
// We dont actually delete the item, because it might be used by a calling client.
// In this case, the memory will not be used for long, so we keep it into a list for a safe amount
// of time and delete it later. Using smart pointers here would be more elegant, but that would need
// to be implemented thread safe, which is difficult in this case.
if(it != mGrpMetaDataCache.end())
{
std::cerr << "(II) moving database cache entry " << (void*)(*it).second << " to dead list." << std::endl;
mOldCachedItems.push_back(std::make_pair(now,it->second)) ;
mGrpMetaDataCache.erase(it) ;
mGrpMetaDataCache_ContainsAllDatabase = false;
}
// We also take that opportunity to delete old entries.
auto it2(mOldCachedItems.begin());
while(it2!=mOldCachedItems.end() && (*it2).first + CACHE_ENTRY_GRACE_PERIOD < now)
{
std::cerr << "(II) deleting old GXS database cache entry " << (void*)(*it2).second << ", " << now - (*it2).first << " seconds old." << std::endl;
delete (*it2).second ;
it2 = mOldCachedItems.erase(it2) ;
}
}
int RsDataService::updateGroup(const std::list<RsNxsGrp *> &grp)
@ -966,7 +1023,7 @@ int RsDataService::updateGroup(const std::list<RsNxsGrp *> &grp)
mDb->sqlUpdate(GRP_TABLE_NAME, "grpId='" + grpPtr->grpId.toStdString() + "'", cv);
locked_clearGrpMetaCache(grpMetaPtr->mGroupId);
locked_updateGrpMetaCache(*grpMetaPtr);
}
// finish transaction
bool ret = mDb->commitTransaction();
@ -1097,7 +1154,7 @@ void RsDataService::locked_retrieveGroups(RetroCursor* c, std::vector<RsNxsGrp*>
if(g)
{
if (metaOffset) {
g->metaData = locked_getGrpMeta(*c, metaOffset);
g->metaData = locked_getGrpMeta(*c, metaOffset,false);
}
grps.push_back(g);
}
@ -1274,7 +1331,7 @@ void RsDataService::locked_retrieveMsgMeta(RetroCursor *c, std::vector<RsGxsMsgM
}
}
int RsDataService::retrieveGxsGrpMetaData(std::map<RsGxsGroupId, RsGxsGrpMetaData *>& grp)
int RsDataService::retrieveGxsGrpMetaData(RsGxsGrpMetaTemporaryMap& grp)
{
#ifdef RS_DATA_SERVICE_DEBUG
std::cerr << "RsDataService::retrieveGxsGrpMetaData()";
@ -1297,100 +1354,101 @@ int RsDataService::retrieveGxsGrpMetaData(std::map<RsGxsGroupId, RsGxsGrpMetaDat
std::cerr << (void*)this << ": RsDataService::retrieveGxsGrpMetaData() retrieving all from cache!" << std::endl;
#endif
for(std::map<RsGxsGroupId,RsGxsGrpMetaData>::const_iterator it(mGrpMetaDataCache.begin());it!=mGrpMetaDataCache.end();++it)
grp[it->first] = new RsGxsGrpMetaData(it->second);
grp = mGrpMetaDataCache ;
}
else
{
{
#ifdef RS_DATA_SERVICE_DEBUG
std::cerr << "RsDataService::retrieveGxsGrpMetaData() retrieving all" << std::endl;
std::cerr << "RsDataService::retrieveGxsGrpMetaData() retrieving all" << std::endl;
#endif
// clear the cache
RetroCursor* c = mDb->sqlQuery(GRP_TABLE_NAME, mGrpMetaColumns, "", "");
RetroCursor* c = mDb->sqlQuery(GRP_TABLE_NAME, mGrpMetaColumns, "", "");
if(c)
{
bool valid = c->moveToFirst();
if(c)
{
bool valid = c->moveToFirst();
while(valid)
{
RsGxsGrpMetaData* g = locked_getGrpMeta(*c, 0);
if(g)
{
grp[g->mGroupId] = g;
mGrpMetaDataCache[g->mGroupId] = *g ;
while(valid)
{
RsGxsGrpMetaData* g = locked_getGrpMeta(*c, 0,true);
if(g)
{
grp[g->mGroupId] = g;
#ifdef RS_DATA_SERVICE_DEBUG_CACHE
std::cerr << (void *)this << ": Retrieving (all) Grp metadata grpId=" << g->mGroupId << std::endl;
std::cerr << (void *)this << ": Retrieving (all) Grp metadata grpId=" << g->mGroupId << std::endl;
#endif
}
valid = c->moveToNext();
}
valid = c->moveToNext();
#ifdef RS_DATA_SERVICE_DEBUG_TIME
++resultCount;
++resultCount;
#endif
}
delete c;
}
}
delete c;
}
mGrpMetaDataCache_ContainsAllDatabase = true ;
}
mGrpMetaDataCache_ContainsAllDatabase = true ;
}
}else
else
{
std::map<RsGxsGroupId, RsGxsGrpMetaData *>::iterator mit = grp.begin();
std::map<RsGxsGroupId, RsGxsGrpMetaData *>::iterator mit = grp.begin();
for(; mit != grp.end(); ++mit)
{
std::map<RsGxsGroupId, RsGxsGrpMetaData>::const_iterator itt = mGrpMetaDataCache.find(mit->first) ;
std::map<RsGxsGroupId, RsGxsGrpMetaData*>::const_iterator itt = mGrpMetaDataCache.find(mit->first) ;
if(itt != mGrpMetaDataCache.end())
{
#ifdef RS_DATA_SERVICE_DEBUG_CACHE
std::cerr << "Retrieving Grp metadata grpId=" << mit->first << " from cache!" << std::endl;
#endif
grp[mit->first] = new RsGxsGrpMetaData(itt->second) ;
grp[mit->first] = itt->second ;
}
else
{
{
#ifdef RS_DATA_SERVICE_DEBUG_CACHE
std::cerr << "Retrieving Grp metadata grpId=" << mit->first ;
std::cerr << "Retrieving Grp metadata grpId=" << mit->first ;
#endif
const RsGxsGroupId& grpId = mit->first;
RetroCursor* c = mDb->sqlQuery(GRP_TABLE_NAME, mGrpMetaColumns, "grpId='" + grpId.toStdString() + "'", "");
const RsGxsGroupId& grpId = mit->first;
RetroCursor* c = mDb->sqlQuery(GRP_TABLE_NAME, mGrpMetaColumns, "grpId='" + grpId.toStdString() + "'", "");
if(c)
{
bool valid = c->moveToFirst();
if(c)
{
bool valid = c->moveToFirst();
#ifdef RS_DATA_SERVICE_DEBUG_CACHE
if(!valid)
std::cerr << " Empty query! GrpId " << grpId << " is not in database" << std::endl;
if(!valid)
std::cerr << " Empty query! GrpId " << grpId << " is not in database" << std::endl;
#endif
while(valid)
{
RsGxsGrpMetaData* g = locked_getGrpMeta(*c, 0);
while(valid)
{
RsGxsGrpMetaData* g = locked_getGrpMeta(*c, 0,true);
if(g)
{
grp[g->mGroupId] = g;
mGrpMetaDataCache[g->mGroupId] = *g ;
if(g)
{
grp[g->mGroupId] = g;
#ifdef RS_DATA_SERVICE_DEBUG_CACHE
std::cerr << ". Got it. Updating cache." << std::endl;
std::cerr << ". Got it. Updating cache." << std::endl;
#endif
}
valid = c->moveToNext();
}
valid = c->moveToNext();
#ifdef RS_DATA_SERVICE_DEBUG_TIME
++resultCount;
++resultCount;
#endif
}
delete c;
}
}
delete c;
}
#ifdef RS_DATA_SERVICE_DEBUG_CACHE
else
std::cerr << ". not found!" << std::endl;
else
std::cerr << ". not found!" << std::endl;
#endif
}
}
}
}
@ -1607,7 +1665,7 @@ bool RsDataService::locked_removeGroupEntries(const std::vector<RsGxsGroupId>& g
mDb->sqlDelete(GRP_TABLE_NAME, KEY_GRP_ID+ "='" + grpId.toStdString() + "'", "");
// also remove the group meta from cache.
mGrpMetaDataCache.erase(*vit) ;
locked_clearGrpMetaCache(*vit) ;
}
ret &= mDb->commitTransaction();

View File

@ -71,7 +71,7 @@ public:
* @param cache whether to store retrieval in mem for faster later retrieval
* @return error code
*/
int retrieveGxsGrpMetaData(std::map<RsGxsGroupId, RsGxsGrpMetaData*>& grp);
int retrieveGxsGrpMetaData(RsGxsGrpMetaTemporaryMap& grp);
/*!
* Retrieves meta data of all groups stored (most current versions only)
@ -208,7 +208,7 @@ private:
* extracts a grp meta item from a cursor at its
* current position
*/
RsGxsGrpMetaData* locked_getGrpMeta(RetroCursor& c, int colOffset);
RsGxsGrpMetaData* locked_getGrpMeta(RetroCursor& c, int colOffset, bool use_cache);
/*!
* extracts a msg item from a cursor at its
@ -346,8 +346,11 @@ private:
// the entre list of grp metadata is requested (which happens quite often)
void locked_clearGrpMetaCache(const RsGxsGroupId& gid);
void locked_updateGrpMetaCache(const RsGxsGrpMetaData& meta);
std::map<RsGxsGroupId,RsGxsGrpMetaData*> mGrpMetaDataCache ;
std::list<std::pair<time_t,RsGxsGrpMetaData*> > mOldCachedItems ;
std::map<RsGxsGroupId,RsGxsGrpMetaData> mGrpMetaDataCache ;
bool mGrpMetaDataCache_ContainsAllDatabase ;
};

View File

@ -36,9 +36,9 @@
#include "rsitems/rsnxsitems.h"
#include "gxs/rsgxsdata.h"
#include "rsgxs.h"
#include "rsgxsutil.h"
#include "util/contentvalue.h"
class RsGxsSearchModule {
public:
@ -61,6 +61,8 @@ public:
ContentValue val;
};
typedef std::map<RsGxsGroupId,RsGxsGrpMetaData*> RsGxsGrpMetaTemporaryMap;
/*!
* This allows modification of local
* meta data items of a group
@ -168,7 +170,7 @@ public:
* , if grpId is failed to be retrieved it will be erased from map
* @return error code
*/
virtual int retrieveGxsGrpMetaData(std::map<RsGxsGroupId, RsGxsGrpMetaData*>& grp) = 0;
virtual int retrieveGxsGrpMetaData(RsGxsGrpMetaTemporaryMap& grp) = 0;
/*!
* Retrieves meta data of all groups stored (most current versions only)

View File

@ -533,7 +533,7 @@ int RsGenExchange::createGroupSignatures(RsTlvKeySignatureSet& signSet, RsTlvBin
}
int RsGenExchange::createMsgSignatures(RsTlvKeySignatureSet& signSet, RsTlvBinaryData& msgData,
const RsGxsMsgMetaData& msgMeta, RsGxsGrpMetaData& grpMeta)
const RsGxsMsgMetaData& msgMeta, const RsGxsGrpMetaData& grpMeta)
{
bool needPublishSign = false, needIdentitySign = false;
uint32_t grpFlag = grpMeta.mGroupFlags;
@ -714,8 +714,7 @@ int RsGenExchange::createMessage(RsNxsMsg* msg)
#ifdef GEN_EXCH_DEBUG
std::cerr << "RsGenExchange::createMessage() " << std::endl;
#endif
std::map<RsGxsGroupId, RsGxsGrpMetaData*> metaMap;
RsGxsGrpMetaTemporaryMap metaMap ;
metaMap.insert(std::make_pair(id, (RsGxsGrpMetaData*)(NULL)));
mDataStore->retrieveGxsGrpMetaData(metaMap);
@ -730,7 +729,7 @@ int RsGenExchange::createMessage(RsNxsMsg* msg)
else
{
// get publish key
RsGxsGrpMetaData* grpMeta = metaMap[id];
const RsGxsGrpMetaData* grpMeta = metaMap[id];
uint32_t metaDataLen = meta.serial_size();
uint32_t allMsgDataLen = metaDataLen + msg->msg.bin_len;
@ -763,8 +762,6 @@ int RsGenExchange::createMessage(RsNxsMsg* msg)
delete[] metaData;
delete[] allMsgData;
delete grpMeta;
}
if(ret_val == SIGN_FAIL)
@ -1196,14 +1193,14 @@ bool RsGenExchange::getMsgRelatedList(const uint32_t &token, MsgRelatedIdResult
bool RsGenExchange::getGroupMeta(const uint32_t &token, std::list<RsGroupMetaData> &groupInfo)
{
std::list<RsGxsGrpMetaData*> metaL;
std::list<const RsGxsGrpMetaData*> metaL;
bool ok = mDataAccess->getGroupSummary(token, metaL);
RsGroupMetaData m;
for( std::list<RsGxsGrpMetaData*>::iterator lit = metaL.begin(); lit != metaL.end(); ++lit)
for( auto lit = metaL.begin(); lit != metaL.end(); ++lit)
{
RsGxsGrpMetaData& gMeta = *(*lit);
const RsGxsGrpMetaData& gMeta = *(*lit);
m = gMeta;
RsGroupNetworkStats sts ;
@ -1223,7 +1220,6 @@ bool RsGenExchange::getGroupMeta(const uint32_t &token, std::list<RsGroupMetaDat
}
groupInfo.push_back(m);
delete (*lit);
}
return ok;
@ -2080,10 +2076,10 @@ bool RsGenExchange::processGrpMask(const RsGxsGroupId& grpId, ContentValue &grpC
// first find out which mask is involved
int32_t value, mask, currValue;
std::string key;
RsGxsGrpMetaData* grpMeta = NULL;
const RsGxsGrpMetaData* grpMeta = NULL;
bool ok = false;
std::map<RsGxsGroupId, RsGxsGrpMetaData* > grpMetaMap;
RsGxsGrpMetaTemporaryMap grpMetaMap;
std::map<RsGxsGroupId, RsGxsGrpMetaData* >::iterator mit;
grpMetaMap.insert(std::make_pair(grpId, (RsGxsGrpMetaData*)(NULL)));
@ -2092,6 +2088,7 @@ bool RsGenExchange::processGrpMask(const RsGxsGroupId& grpId, ContentValue &grpC
if((mit = grpMetaMap.find(grpId)) != grpMetaMap.end())
{
grpMeta = mit->second;
if (!grpMeta)
{
#ifdef GEN_EXCH_DEBUG
@ -2112,12 +2109,9 @@ bool RsGenExchange::processGrpMask(const RsGxsGroupId& grpId, ContentValue &grpC
{
key = RsGeneralDataService::GRP_META_SUBSCRIBE_FLAG;
currValue = grpMeta->mSubscribeFlags;
}else
{
if(grpMeta)
delete grpMeta;
return !(grpCv.empty());
}
else
return !(grpCv.empty());
ok &= grpCv.getAsInt32(key+GXS_MASK, mask);
@ -2129,9 +2123,6 @@ bool RsGenExchange::processGrpMask(const RsGxsGroupId& grpId, ContentValue &grpC
grpCv.put(key, value);
if(grpMeta)
delete grpMeta;
return ok;
}
@ -2350,7 +2341,7 @@ void RsGenExchange::processGroupUpdatePublish()
// get keys for group update publish
// first build meta request map for groups to be updated
std::map<RsGxsGroupId, RsGxsGrpMetaData*> grpMeta;
RsGxsGrpMetaTemporaryMap grpMeta;
std::vector<GroupUpdatePublish>::iterator vit = mGroupUpdatePublish.begin();
for(; vit != mGroupUpdatePublish.end(); ++vit)
@ -2360,8 +2351,8 @@ void RsGenExchange::processGroupUpdatePublish()
grpMeta.insert(std::make_pair(groupId, (RsGxsGrpMetaData*)(NULL)));
}
if(grpMeta.empty())
return;
if(grpMeta.empty())
return;
mDataStore->retrieveGxsGrpMetaData(grpMeta);
@ -2373,18 +2364,16 @@ void RsGenExchange::processGroupUpdatePublish()
const RsGxsGroupId& groupId = gup.grpItem->meta.mGroupId;
std::map<RsGxsGroupId, RsGxsGrpMetaData*>::iterator mit = grpMeta.find(groupId);
RsGxsGrpMetaData* meta = NULL;
const RsGxsGrpMetaData* meta = NULL;
if(mit == grpMeta.end() || mit->second == NULL)
{
std::cerr << "Error! could not find meta of old group to update!" << std::endl;
mDataAccess->updatePublicRequestStatus(gup.mToken, RsTokenService::GXS_REQUEST_V2_STATUS_FAILED);
delete gup.grpItem;
continue;
}else
{
meta = mit->second;
}
else
meta = mit->second;
//gup.grpItem->meta = *meta;
GxsGrpPendingSign ggps(gup.grpItem, gup.mToken);
@ -2402,14 +2391,13 @@ void RsGenExchange::processGroupUpdatePublish()
ggps.mToken = gup.mToken;
mGrpsToPublish.push_back(ggps);
}
else
else
{
std::cerr << "(EE) publish group fails because RS cannot find the private publish and author keys" << std::endl;
delete gup.grpItem;
mDataAccess->updatePublicRequestStatus(gup.mToken, RsTokenService::GXS_REQUEST_V2_STATUS_FAILED);
}
delete meta;
}
mGroupUpdatePublish.clear();
@ -2814,23 +2802,20 @@ bool RsGenExchange::getGroupKeys(const RsGxsGroupId &grpId, RsTlvSecurityKeySet
RS_STACK_MUTEX(mGenMtx) ;
std::map<RsGxsGroupId, RsGxsGrpMetaData*> grpMeta;
RsGxsGrpMetaTemporaryMap grpMeta;
grpMeta[grpId] = NULL;
mDataStore->retrieveGxsGrpMetaData(grpMeta);
if(grpMeta.empty())
return false;
RsGxsGrpMetaData* meta = grpMeta[grpId];
const RsGxsGrpMetaData* meta = grpMeta[grpId];
if(meta == NULL)
return false;
keySet = meta->keys;
GxsSecurity::createPublicKeysFromPrivateKeys(keySet) ;
for(std::map<RsGxsGroupId, RsGxsGrpMetaData*>::iterator it=grpMeta.begin();it!=grpMeta.end();++it)
delete it->second ;
GxsSecurity::createPublicKeysFromPrivateKeys(keySet) ;
return true;
}
@ -2958,11 +2943,12 @@ void RsGenExchange::processRecvdMessages()
continue ;
}
RsGxsGrpMetaData *grpMeta = mit->second;
const RsGxsGrpMetaData *grpMeta = mit->second;
RsTlvSecurityKeySet keys = grpMeta->keys ;
GxsSecurity::createPublicKeysFromPrivateKeys(grpMeta->keys); // make sure we have the public keys that correspond to the private ones, as it happens. Most of the time this call does nothing.
GxsSecurity::createPublicKeysFromPrivateKeys(keys); // make sure we have the public keys that correspond to the private ones, as it happens. Most of the time this call does nothing.
int validateReturn = validateMsg(msg, grpMeta->mGroupFlags, grpMeta->mSignFlags, grpMeta->keys);
int validateReturn = validateMsg(msg, grpMeta->mGroupFlags, grpMeta->mSignFlags, keys);
#ifdef GEN_EXCH_DEBUG
std::cerr << " grpMeta.mSignFlags: " << std::hex << grpMeta->mSignFlags << std::dec << std::endl;
@ -3176,7 +3162,7 @@ void RsGenExchange::processRecvdGroups()
void RsGenExchange::performUpdateValidation()
{
RS_STACK_MUTEX(mGenMtx) ;
RS_STACK_MUTEX(mGenMtx) ;
if(mGroupUpdates.empty())
return;
@ -3185,7 +3171,7 @@ void RsGenExchange::performUpdateValidation()
std::cerr << "RsGenExchange::performUpdateValidation() " << std::endl;
#endif
std::map<RsGxsGroupId, RsGxsGrpMetaData*> grpMetas;
RsGxsGrpMetaTemporaryMap grpMetas;
std::vector<GroupUpdate>::iterator vit = mGroupUpdates.begin();
for(; vit != mGroupUpdates.end(); ++vit)
@ -3200,8 +3186,7 @@ void RsGenExchange::performUpdateValidation()
for(; vit != mGroupUpdates.end(); ++vit)
{
GroupUpdate& gu = *vit;
std::map<RsGxsGroupId, RsGxsGrpMetaData*>::iterator mit =
grpMetas.find(gu.newGrp->grpId);
std::map<RsGxsGroupId, RsGxsGrpMetaData*>::iterator mit = grpMetas.find(gu.newGrp->grpId);
gu.oldGrpMeta = mit->second;
gu.validUpdate = updateValid(*(gu.oldGrpMeta), *(gu.newGrp));
}
@ -3223,51 +3208,50 @@ void RsGenExchange::performUpdateValidation()
if(gu.newGrp->metaData->mCircleType == GXS_CIRCLE_TYPE_YOUR_FRIENDS_ONLY)
gu.newGrp->metaData->mOriginator = gu.newGrp->PeerId();
// Keep subscriptionflag to what it was. This avoids clearing off the flag when updates to group meta information
// is received.
// Keep subscriptionflag to what it was. This avoids clearing off the flag when updates to group meta information
// is received.
gu.newGrp->metaData->mSubscribeFlags = gu.oldGrpMeta->mSubscribeFlags ;
gu.newGrp->metaData->mSubscribeFlags = gu.oldGrpMeta->mSubscribeFlags ;
grps.push_back(gu.newGrp);
}
else
{
delete gu.newGrp;
gu.newGrp = NULL ;
gu.newGrp = NULL ;
}
delete gu.oldGrpMeta;
gu.oldGrpMeta = NULL ;
gu.oldGrpMeta = NULL ;
}
// notify the client
// notify the client
RsGxsGroupChange* c = new RsGxsGroupChange(RsGxsNotify::TYPE_RECEIVE, true);
RsGxsGroupChange* c = new RsGxsGroupChange(RsGxsNotify::TYPE_RECEIVE, true);
for(uint32_t i=0;i<mGroupUpdates.size();++i)
if(mGroupUpdates[i].newGrp != NULL)
{
c->mGrpIdList.push_back(mGroupUpdates[i].newGrp->grpId) ;
for(uint32_t i=0;i<mGroupUpdates.size();++i)
if(mGroupUpdates[i].newGrp != NULL)
{
c->mGrpIdList.push_back(mGroupUpdates[i].newGrp->grpId) ;
#ifdef GEN_EXCH_DEBUG
std::cerr << " " << mGroupUpdates[i].newGrp->grpId << std::endl;
std::cerr << " " << mGroupUpdates[i].newGrp->grpId << std::endl;
#endif
}
}
mNotifications.push_back(c);
mNotifications.push_back(c);
// Warning: updateGroup will destroy the objects in grps. Dont use it afterwards!
// Warning: updateGroup will destroy the objects in grps. Dont use it afterwards!
mDataStore->updateGroup(grps);
#ifdef GEN_EXCH_DEBUG
std::cerr << " adding the following grp ids to notification: " << std::endl;
std::cerr << " adding the following grp ids to notification: " << std::endl;
#endif
// cleanup
// cleanup
mGroupUpdates.clear();
}
bool RsGenExchange::updateValid(RsGxsGrpMetaData& oldGrpMeta, RsNxsGrp& newGrp) const
bool RsGenExchange::updateValid(const RsGxsGrpMetaData& oldGrpMeta, RsNxsGrp& newGrp) const
{
std::map<SignType, RsTlvKeySignature>& signSet = newGrp.metaData->signSet.keySignSet;
std::map<SignType, RsTlvKeySignature>::iterator mit = signSet.find(INDEX_AUTHEN_ADMIN);
@ -3283,10 +3267,11 @@ bool RsGenExchange::updateValid(RsGxsGrpMetaData& oldGrpMeta, RsNxsGrp& newGrp)
}
RsTlvKeySignature adminSign = mit->second;
RsTlvSecurityKeySet old_keys = oldGrpMeta.keys ;
GxsSecurity::createPublicKeysFromPrivateKeys(oldGrpMeta.keys); // make sure we have the public keys that correspond to the private ones, as it happens. Most of the time this call does nothing.
GxsSecurity::createPublicKeysFromPrivateKeys(old_keys); // make sure we have the public keys that correspond to the private ones, as it happens. Most of the time this call does nothing.
std::map<RsGxsId, RsTlvPublicRSAKey>& keys = oldGrpMeta.keys.public_keys;
std::map<RsGxsId, RsTlvPublicRSAKey>& keys = old_keys.public_keys;
std::map<RsGxsId, RsTlvPublicRSAKey>::iterator keyMit = keys.find(RsGxsId(oldGrpMeta.mGroupId));
if(keyMit == keys.end())

View File

@ -223,7 +223,7 @@ public:
* @param groupInfo
* @return false if could not redeem token
*/
bool getGroupMeta(const uint32_t &token, std::list<RsGroupMetaData> &groupInfo);
bool getGroupMeta(const uint32_t &token, std::list<RsGroupMetaData>& groupInfo);
/*!
* retrieves message meta data associated to a request token
@ -765,7 +765,7 @@ private:
* SIGN_FAIL_TRY_LATER for Id sign key not avail (but requested), try later
*/
int createMsgSignatures(RsTlvKeySignatureSet& signSet, RsTlvBinaryData& msgData,
const RsGxsMsgMetaData& msgMeta, RsGxsGrpMetaData& grpMeta);
const RsGxsMsgMetaData& msgMeta, const RsGxsGrpMetaData& grpMeta);
/*!
* convenience function to create sign for groups
@ -835,7 +835,7 @@ private:
* @param newGrp the new group that updates the old group (must have meta data member initialised)
* @return
*/
bool updateValid(RsGxsGrpMetaData& oldGrp, RsNxsGrp& newGrp) const;
bool updateValid(const RsGxsGrpMetaData& oldGrp, RsNxsGrp& newGrp) const;
/*!
* convenience function for checking private publish and admin keys are present

View File

@ -33,7 +33,7 @@ RsGxsGrpMetaData::RsGxsGrpMetaData()
clear();
}
uint32_t RsGxsGrpMetaData::serial_size(uint32_t api_version)
uint32_t RsGxsGrpMetaData::serial_size(uint32_t api_version) const
{
uint32_t s = 8; // header size

View File

@ -51,7 +51,7 @@ public:
RsGxsGrpMetaData();
bool deserialise(void *data, uint32_t &pktsize);
bool serialise(void* data, uint32_t &pktsize, uint32_t api_version);
uint32_t serial_size(uint32_t api_version);
uint32_t serial_size(uint32_t api_version) const;
void clear();
void operator =(const RsGroupMetaData& rMeta);

View File

@ -25,6 +25,7 @@
#include <time.h>
#include "rsgxsutil.h"
#include "rsgxsdataaccess.h"
#include "retroshare/rsgxsflags.h"
@ -377,7 +378,7 @@ bool RsGxsDataAccess::clearRequest(const uint32_t& token)
return true;
}
bool RsGxsDataAccess::getGroupSummary(const uint32_t& token, std::list<RsGxsGrpMetaData*>& groupInfo)
bool RsGxsDataAccess::getGroupSummary(const uint32_t& token, std::list<const RsGxsGrpMetaData*>& groupInfo)
{
RS_STACK_MUTEX(mDataMutex);
@ -1000,18 +1001,17 @@ bool RsGxsDataAccess::getGroupData(GroupDataReq* req)
bool RsGxsDataAccess::getGroupSummary(GroupMetaReq* req)
{
std::map<RsGxsGroupId, RsGxsGrpMetaData*> grpMeta;
RsGxsGrpMetaTemporaryMap grpMeta;
std::list<RsGxsGroupId> grpIdsOut;
std::list<RsGxsGroupId> grpIdsOut;
getGroupList(req->mGroupIds, req->Options, grpIdsOut);
getGroupList(req->mGroupIds, req->Options, grpIdsOut);
if(grpIdsOut.empty())
return true;
if(grpIdsOut.empty())
return true;
std::list<RsGxsGroupId>::const_iterator lit = grpIdsOut.begin();
std::list<RsGxsGroupId>::const_iterator lit = grpIdsOut.begin();
for(; lit != grpIdsOut.end(); ++lit)
for(; lit != grpIdsOut.end(); ++lit)
grpMeta[*lit] = NULL;
mDataStore->retrieveGxsGrpMetaData(grpMeta);
@ -1033,29 +1033,18 @@ bool RsGxsDataAccess::getGroupList(GroupIdReq* req)
bool RsGxsDataAccess::getGroupList(const std::list<RsGxsGroupId>& grpIdsIn, const RsTokReqOptions& opts, std::list<RsGxsGroupId>& grpIdsOut)
{
std::map<RsGxsGroupId, RsGxsGrpMetaData*> grpMeta;
RsGxsGrpMetaTemporaryMap grpMeta;
std::list<RsGxsGroupId>::const_iterator lit = grpIdsIn.begin();
for(; lit != grpIdsIn.end(); ++lit)
grpMeta[*lit] = NULL;
for(auto lit = grpIdsIn.begin(); lit != grpIdsIn.end(); ++lit)
grpMeta[*lit] = NULL;
mDataStore->retrieveGxsGrpMetaData(grpMeta);
std::map<RsGxsGroupId, RsGxsGrpMetaData*>::iterator mit = grpMeta.begin();
for(; mit != grpMeta.end(); ++mit)
{
grpIdsOut.push_back(mit->first);
}
for(auto mit = grpMeta.begin() ; mit != grpMeta.end(); ++mit)
grpIdsOut.push_back(mit->first);
filterGrpList(grpIdsOut, opts, grpMeta);
for(mit = grpMeta.begin(); mit != grpMeta.end(); ++mit)
{
delete mit->second; // so wasteful!!
}
return true;
}
@ -1622,12 +1611,10 @@ bool RsGxsDataAccess::getGroupStatistic(GroupStatisticRequest *req)
// potentially very expensive!
bool RsGxsDataAccess::getServiceStatistic(ServiceStatisticRequest *req)
{
std::map<RsGxsGroupId, RsGxsGrpMetaData*> grpMeta;
RsGxsGrpMetaTemporaryMap grpMeta ;
mDataStore->retrieveGxsGrpMetaData(grpMeta);
std::map<RsGxsGroupId, RsGxsGrpMetaData*>::iterator mit = grpMeta.begin();
req->mServiceStatistic.mNumGrps = grpMeta.size();
req->mServiceStatistic.mNumMsgs = 0;
req->mServiceStatistic.mSizeOfGrps = 0;
@ -1638,9 +1625,9 @@ bool RsGxsDataAccess::getServiceStatistic(ServiceStatisticRequest *req)
req->mServiceStatistic.mNumChildMsgsNew = 0;
req->mServiceStatistic.mNumChildMsgsUnread = 0;
for(; mit != grpMeta.end(); ++mit)
for(auto mit = grpMeta.begin(); mit != grpMeta.end(); ++mit)
{
RsGxsGrpMetaData* m = mit->second;
const RsGxsGrpMetaData* m = mit->second;
req->mServiceStatistic.mSizeOfGrps += m->mGrpSize + m->serial_size(RS_GXS_GRP_META_DATA_CURRENT_API_VERSION);
if (IS_GROUP_SUBSCRIBED(m->mSubscribeFlags))
@ -1658,8 +1645,6 @@ bool RsGxsDataAccess::getServiceStatistic(ServiceStatisticRequest *req)
req->mServiceStatistic.mNumChildMsgsNew += gr.mGroupStatistic.mNumChildMsgsNew;
req->mServiceStatistic.mNumChildMsgsUnread += gr.mGroupStatistic.mNumChildMsgsUnread;
}
delete m;
}
req->mServiceStatistic.mSizeStore = req->mServiceStatistic.mSizeOfGrps + req->mServiceStatistic.mSizeOfMsgs;

View File

@ -209,7 +209,7 @@ public:
* @param token request token to be redeemed
* @param groupInfo
*/
bool getGroupSummary(const uint32_t &token, std::list<RsGxsGrpMetaData*> &groupInfo);
bool getGroupSummary(const uint32_t &token, std::list<const RsGxsGrpMetaData*>& groupInfo);
/*!
*

View File

@ -689,7 +689,7 @@ void RsGxsNetService::syncGrpStatistics()
time_t now = time(NULL) ;
for(std::map<RsGxsGroupId,RsGxsGrpMetaData*>::const_iterator it(grpMeta.begin());it!=grpMeta.end();++it)
for(auto it(grpMeta.begin());it!=grpMeta.end();++it)
{
const RsGxsGrpConfig& rec = locked_getGrpConfig(it->first) ;
@ -755,7 +755,7 @@ void RsGxsNetService::handleRecvSyncGrpStatistics(RsNxsSyncGrpStatsItem *grs)
mDataStore->retrieveGxsGrpMetaData(grpMetas);
RsGxsGrpMetaData* grpMeta = grpMetas[grs->grpId];
const RsGxsGrpMetaData* grpMeta = grpMetas[grs->grpId];
if(grpMeta == NULL)
{
@ -1951,7 +1951,7 @@ void RsGxsNetService::updateServerSyncTS()
// finally, update timestamps.
bool change = false;
for(std::map<RsGxsGroupId, RsGxsGrpMetaData*>::const_iterator mit = gxsMap.begin();mit != gxsMap.end(); ++mit)
for(auto mit = gxsMap.begin();mit != gxsMap.end(); ++mit)
{
// Check if the group is subscribed and restricted to a circle. If the circle has changed, update the
// global TS to reflect that change to clients who may be able to see/subscribe to that particular group.
@ -2722,7 +2722,7 @@ void RsGxsNetService::locked_genReqMsgTransaction(NxsTransaction* tr)
grpMetaMap[grpId] = NULL;
mDataStore->retrieveGxsGrpMetaData(grpMetaMap);
RsGxsGrpMetaData* grpMeta = grpMetaMap[grpId];
const RsGxsGrpMetaData* grpMeta = grpMetaMap[grpId];
if(grpMeta == NULL) // this should not happen, but just in case...
{
@ -3825,9 +3825,9 @@ void RsGxsNetService::handleRecvSyncGroup(RsNxsSyncGrpReqItem *item)
GXSNETDEBUG_P_(peer) << " Group list beings being sent: " << std::endl;
#endif
for(std::map<RsGxsGroupId, RsGxsGrpMetaData*>::iterator mit = grp.begin(); mit != grp.end(); ++mit)
for(auto mit = grp.begin(); mit != grp.end(); ++mit)
{
RsGxsGrpMetaData* grpMeta = mit->second;
const RsGxsGrpMetaData* grpMeta = mit->second;
// Only send info about subscribed groups.
@ -3899,7 +3899,7 @@ void RsGxsNetService::handleRecvSyncGroup(RsNxsSyncGrpReqItem *item)
bool RsGxsNetService::canSendGrpId(const RsPeerId& sslId, RsGxsGrpMetaData& grpMeta, std::vector<GrpIdCircleVet>& /* toVet */, bool& should_encrypt)
bool RsGxsNetService::canSendGrpId(const RsPeerId& sslId, const RsGxsGrpMetaData& grpMeta, std::vector<GrpIdCircleVet>& /* toVet */, bool& should_encrypt)
{
#ifdef NXS_NET_DEBUG_4
GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << "RsGxsNetService::canSendGrpId()"<< std::endl;
@ -4092,7 +4092,7 @@ void RsGxsNetService::handleRecvSyncMessage(RsNxsSyncMsgReqItem *item,bool item_
grpMetas[item->grpId] = NULL;
mDataStore->retrieveGxsGrpMetaData(grpMetas);
RsGxsGrpMetaData* grpMeta = grpMetas[item->grpId];
const RsGxsGrpMetaData* grpMeta = grpMetas[item->grpId];
if(grpMeta == NULL)
{
@ -4633,7 +4633,7 @@ void RsGxsNetService::sharePublishKeysPending()
// Find the publish keys in the retrieved info
RsGxsGrpMetaData *grpMeta = grpMetaMap[mit->first] ;
const RsGxsGrpMetaData *grpMeta = grpMetaMap[mit->first] ;
if(grpMeta == NULL)
{
@ -4718,7 +4718,7 @@ void RsGxsNetService::handleRecvPublishKeys(RsNxsGroupPublishKeyItem *item)
// update the publish keys in this group meta info
RsGxsGrpMetaData *grpMeta = grpMetaMap[item->grpId] ;
const RsGxsGrpMetaData *grpMeta = grpMetaMap[item->grpId] ;
if (!grpMeta) {
std::cerr << "(EE) RsGxsNetService::handleRecvPublishKeys() grpMeta not found." << std::endl;
return ;
@ -4760,9 +4760,10 @@ void RsGxsNetService::handleRecvPublishKeys(RsNxsGroupPublishKeyItem *item)
// Store/update the info.
grpMeta->keys.private_keys[item->private_key.keyId] = item->private_key ;
RsTlvSecurityKeySet keys = grpMeta->keys ;
keys.private_keys[item->private_key.keyId] = item->private_key ;
bool ret = mDataStore->updateGroupKeys(item->grpId,grpMeta->keys, grpMeta->mSubscribeFlags | GXS_SERV::GROUP_SUBSCRIBE_PUBLISH) ;
bool ret = mDataStore->updateGroupKeys(item->grpId,keys, grpMeta->mSubscribeFlags | GXS_SERV::GROUP_SUBSCRIBE_PUBLISH) ;
if(ret)
{

View File

@ -370,7 +370,7 @@ private:
* @param toVet groupid/peer to vet are stored here if their circle id is not cached
* @return false, if you cannot send to this peer, true otherwise
*/
bool canSendGrpId(const RsPeerId& sslId, RsGxsGrpMetaData& grpMeta, std::vector<GrpIdCircleVet>& toVet, bool &should_encrypt);
bool canSendGrpId(const RsPeerId& sslId, const RsGxsGrpMetaData& grpMeta, std::vector<GrpIdCircleVet>& toVet, bool &should_encrypt);
bool canSendMsgIds(std::vector<RsGxsMsgMetaData*>& msgMetas, const RsGxsGrpMetaData&, const RsPeerId& sslId, RsGxsCircleId &should_encrypt_id);
/*!

View File

@ -28,7 +28,8 @@
GroupMetaReq::~GroupMetaReq()
{
rsstd::delete_all(mGroupMetaData.begin(), mGroupMetaData.end());
//rsstd::delete_all(mGroupMetaData.begin(), mGroupMetaData.end()); // now memory ownership is kept by the cache.
mGroupMetaData.clear();
}
GroupDataReq::~GroupDataReq()

View File

@ -52,7 +52,7 @@ public:
public:
std::list<RsGxsGroupId> mGroupIds;
std::list<RsGxsGrpMetaData*> mGroupMetaData;
std::list<const RsGxsGrpMetaData*> mGroupMetaData;
};
class GroupIdReq : public GxsRequest

View File

@ -42,13 +42,10 @@ static const uint32_t MAX_GXS_IDS_REQUESTS_NET = 10 ; // max number of reques
RsGxsMessageCleanUp::RsGxsMessageCleanUp(RsGeneralDataService* const dataService, RsGenExchange *genex, uint32_t chunkSize)
: mDs(dataService), mGenExchangeClient(genex), CHUNK_SIZE(chunkSize)
{
std::map<RsGxsGroupId, RsGxsGrpMetaData*> grpMeta;
RsGxsGrpMetaTemporaryMap grpMeta;
mDs->retrieveGxsGrpMetaData(grpMeta);
std::map<RsGxsGroupId, RsGxsGrpMetaData*>::iterator cit = grpMeta.begin();
for(;cit != grpMeta.end(); ++cit)
for(auto cit=grpMeta.begin();cit != grpMeta.end(); ++cit)
mGrpMeta.push_back(cit->second);
}
@ -64,7 +61,7 @@ bool RsGxsMessageCleanUp::clean()
#endif
while(!mGrpMeta.empty())
{
RsGxsGrpMetaData* grpMeta = mGrpMeta.back();
const RsGxsGrpMetaData* grpMeta = mGrpMeta.back();
const RsGxsGroupId& grpId = grpMeta->mGroupId;
mGrpMeta.pop_back();
GxsMsgReq req;
@ -137,8 +134,6 @@ bool RsGxsMessageCleanUp::clean()
mDs->removeMsgs(req);
delete grpMeta;
i++;
if(i > CHUNK_SIZE) break;
}

View File

@ -32,6 +32,7 @@
class RsGixs ;
class RsGenExchange ;
class RsGeneralDataService ;
// temporary holds a map of pointers to class T, and destroys all pointers on delete.
@ -104,7 +105,7 @@ public:
}
};
typedef t_RsGxsGenericDataTemporaryMap<RsGxsGroupId,RsGxsGrpMetaData> RsGxsGrpMetaTemporaryMap;
typedef std::map<RsGxsGroupId,RsGxsGrpMetaData*> RsGxsGrpMetaTemporaryMap;
typedef t_RsGxsGenericDataTemporaryMap<RsGxsGroupId,RsNxsGrp> RsNxsGrpDataTemporaryMap;
typedef t_RsGxsGenericDataTemporaryMapVector<RsGxsMsgMetaData> RsGxsMsgMetaTemporaryMap ;
@ -178,7 +179,7 @@ private:
RsGeneralDataService* const mDs;
RsGenExchange *mGenExchangeClient;
uint32_t CHUNK_SIZE;
std::vector<RsGxsGrpMetaData*> mGrpMeta;
std::vector<const RsGxsGrpMetaData*> mGrpMeta;
};
/*!
@ -226,7 +227,7 @@ class GroupUpdate
public:
GroupUpdate() : oldGrpMeta(NULL), newGrp(NULL), validUpdate(false)
{}
RsGxsGrpMetaData* oldGrpMeta;
const RsGxsGrpMetaData* oldGrpMeta;
RsNxsGrp* newGrp;
bool validUpdate;
};

View File

@ -1658,9 +1658,8 @@ bool p3IdService::getGroupData(const uint32_t &token, std::vector<RsGxsIdGroup>
group.mPgpKnown = false;
group.mPgpId.clear();
std::cerr << "p3IdService::getGroupData() Failed to decode ServiceString \""
<< group.mMeta.mServiceString << "\"" ;
std::cerr << std::endl;
if(!group.mMeta.mServiceString.empty())
std::cerr << "p3IdService::getGroupData() " << group.mMeta.mGroupId << " (" << group.mMeta.mGroupName << ") : Failed to decode, or no ServiceString \"" << group.mMeta.mServiceString << "\"" << std::endl;
}
group.mIsAContact = (mContacts.find(RsGxsId(group.mMeta.mGroupId)) != mContacts.end());
@ -2252,7 +2251,7 @@ void RsGxsIdCache::updateServiceString(std::string serviceString)
#ifdef DEBUG_RECOGN
std::cerr << "RsGxsIdCache::updateServiceString() updating recogntags";
std::cerr << std::endl;
#endif // DEBUG_RECOGN
#endif
if (ssdata.recogntags.publishTs == mPublishTs)
{
std::list<RsRecognTag>::iterator it;
@ -2264,7 +2263,7 @@ void RsGxsIdCache::updateServiceString(std::string serviceString)
#ifdef DEBUG_RECOGN
std::cerr << "RsGxsIdCache::updateServiceString() Valid Tag: " << it->tag_class << ":" << it->tag_type;
std::cerr << std::endl;
#endif // DEBUG_RECOGN
#endif
details.mRecognTags.push_back(*it);
}
else
@ -2272,7 +2271,7 @@ void RsGxsIdCache::updateServiceString(std::string serviceString)
#ifdef DEBUG_RECOGN
std::cerr << "RsGxsIdCache::updateServiceString() Invalid Tag: " << it->tag_class << ":" << it->tag_type;
std::cerr << std::endl;
#endif // DEBUG_RECOGN
#endif
}
}
}
@ -2281,7 +2280,7 @@ void RsGxsIdCache::updateServiceString(std::string serviceString)
#ifdef DEBUG_RECOGN
std::cerr << "RsGxsIdCache::updateServiceString() recogntags old publishTs";
std::cerr << std::endl;
#endif // DEBUG_RECOGN
#endif
}
}
@ -2290,7 +2289,7 @@ void RsGxsIdCache::updateServiceString(std::string serviceString)
#ifdef DEBUG_RECOGN
std::cerr << "RsGxsIdCache::updateServiceString() recogntags unprocessed";
std::cerr << std::endl;
#endif // DEBUG_RECOGN
#endif
}
// copy over Reputation scores.

View File

@ -1,28 +1,33 @@
#include <QTreeWidget>
#include <QTextBrowser>
#include <QTimer>
#include <QMenu>
#include <QMessageBox>
#include <time.h>
#include <algorithm>
#include "ChatLobbyWidget.h"
#include "chat/CreateLobbyDialog.h"
#include "chat/ChatTabWidget.h"
#include "common/RSTreeWidgetItem.h"
#include "notifyqt.h"
#include "chat/ChatLobbyDialog.h"
#include "chat/ChatLobbyUserNotify.h"
#include "util/HandleRichText.h"
#include "util/QtVersion.h"
#include "gui/settings/rsharesettings.h"
#include "chat/ChatTabWidget.h"
#include "chat/CreateLobbyDialog.h"
#include "common/RSTreeWidgetItem.h"
#include "gui/gxs/GxsIdDetails.h"
#include "gui/Identity/IdEditDialog.h"
#include "gui/settings/rsharesettings.h"
#include "util/HandleRichText.h"
#include "util/QtVersion.h"
#include "retroshare/rsmsgs.h"
#include "retroshare/rspeers.h"
#include "retroshare/rsnotify.h"
#include "retroshare/rsidentity.h"
#include <QGridLayout>
#include <QMenu>
#include <QMessageBox>
#include <QTextBrowser>
#include <QTimer>
#include <QTreeWidget>
#include <algorithm>
#include <time.h>
//#define CHAT_LOBBY_GUI_DEBUG 1
#define COLUMN_NAME 0
@ -61,6 +66,8 @@ ChatLobbyWidget::ChatLobbyWidget(QWidget *parent, Qt::WindowFlags flags)
m_bProcessSettings = false;
myChatLobbyUserNotify = NULL;
myInviteYesButton = NULL;
myInviteIdChooser = NULL;
QObject::connect( NotifyQt::getInstance(), SIGNAL(lobbyListChanged()), SLOT(lobbyChanged()));
QObject::connect( NotifyQt::getInstance(), SIGNAL(chatLobbyEvent(qulonglong,int,const RsGxsId&,const QString&)), this, SLOT(displayChatLobbyEvent(qulonglong,int,const RsGxsId&,const QString&)));
@ -1081,8 +1088,8 @@ void ChatLobbyWidget::readChatLobbyInvites()
std::list<ChatLobbyId> subscribed_lobbies ;
rsMsgs->getChatLobbyList(subscribed_lobbies) ;
for(std::list<ChatLobbyInvite>::const_iterator it(invites.begin());it!=invites.end();++it)
{
for(std::list<ChatLobbyInvite>::const_iterator it(invites.begin());it!=invites.end();++it)
{
// first check if the lobby is already subscribed. If so, just ignore the request.
bool found = false ;
@ -1097,8 +1104,8 @@ void ChatLobbyWidget::readChatLobbyInvites()
QMessageBox::Question, QMessageBox::Yes,QMessageBox::No, 0);
QLabel *label ;
GxsIdChooser *idchooser = new GxsIdChooser ;
QLabel *label;
GxsIdChooser *idchooser = new GxsIdChooser;
if( (*it).lobby_flags & RS_CHAT_LOBBY_FLAGS_PGP_SIGNED )
{
@ -1110,18 +1117,24 @@ void ChatLobbyWidget::readChatLobbyInvites()
idchooser->loadIds(IDCHOOSER_ID_REQUIRED,default_id) ;
label = new QLabel(tr("Choose an identity for this chat room:"));
}
myInviteYesButton = mb.button(QMessageBox::Yes);
myInviteIdChooser = idchooser;
connect(idchooser, SIGNAL(currentIndexChanged(int)), this, SLOT(idChooserCurrentIndexChanged(int)));
idChooserCurrentIndexChanged(0);
QGridLayout* layout = qobject_cast<QGridLayout*>(mb.layout());
if (layout) {
layout->addWidget(label, layout->rowCount(), 0, 1, layout->columnCount(), Qt::AlignHCenter ) ;
layout->addWidget(idchooser, layout->rowCount(), 0, 1, layout->columnCount(), Qt::AlignRight ) ;
} else {
//Not QGridLayout so add at end
mb.layout()->addWidget(label) ;
mb.layout()->addWidget(idchooser) ;
}
QGridLayout* layout = qobject_cast<QGridLayout*>(mb.layout());
if (layout) {
layout->addWidget(label, layout->rowCount(), 0, 1, layout->columnCount(), Qt::AlignHCenter ) ;
layout->addWidget(idchooser, layout->rowCount(), 0, 1, layout->columnCount(), Qt::AlignRight ) ;
} else {
//Not QGridLayout so add at end
mb.layout()->addWidget(label) ;
mb.layout()->addWidget(idchooser) ;
}
int res = mb.exec() ;
int res = mb.exec();
myInviteYesButton = NULL;
myInviteIdChooser = NULL;
if (res == QMessageBox::No)
{
@ -1144,6 +1157,28 @@ void ChatLobbyWidget::readChatLobbyInvites()
std::cerr << "Can't join chat room with id 0x" << std::hex << (*it).lobby_id << std::dec << std::endl;
}
myInviteYesButton = NULL;
myInviteIdChooser = NULL;
}
void ChatLobbyWidget::idChooserCurrentIndexChanged(int /*index*/)
{
if (myInviteYesButton && myInviteIdChooser)
{
RsGxsId chosen_id;
switch (myInviteIdChooser->getChosenId(chosen_id))
{
case GxsIdChooser::KnowId:
case GxsIdChooser::UnKnowId:
myInviteYesButton->setEnabled(true);
break;
case GxsIdChooser::NoId:
case GxsIdChooser::None:
default: ;
myInviteYesButton->setEnabled(false);
}
}
}
void ChatLobbyWidget::filterColumnChanged(int)

View File

@ -1,10 +1,16 @@
#pragma once
#include <QTreeWidget>
#include <retroshare/rsmsgs.h>
#include "ui_ChatLobbyWidget.h"
#include "RsAutoUpdatePage.h"
#include "chat/ChatLobbyUserNotify.h"
#include "gui/gxs/GxsIdChooser.h"
#include <retroshare/rsmsgs.h>
#include <QAbstractButton>
#include <QTreeWidget>
#define IMAGE_CHATLOBBY ":/icons/png/chat-lobbies.png"
@ -82,6 +88,7 @@ private slots:
void setShowSubscribeColumn(bool show);
void updateNotify(ChatLobbyId id, unsigned int count) ;
void idChooserCurrentIndexChanged(int index);
private:
void autoSubscribeLobby(QTreeWidgetItem *item);
@ -114,6 +121,9 @@ private:
ChatLobbyUserNotify* myChatLobbyUserNotify;
QAbstractButton* myInviteYesButton;
GxsIdChooser* myInviteIdChooser;
/* UI - from Designer */
Ui::ChatLobbyWidget ui;
};

View File

@ -966,7 +966,7 @@ int TransfersDialog::addDLItem(int row, const FileInfo &fileInfo)
QString fileName = QString::fromUtf8(fileInfo.fname.c_str());
DLListModel->setData(DLListModel->index(row, COLUMN_NAME), fileName);
DLListModel->setData(DLListModel->index(row, COLUMN_NAME), FilesDefs::getIconFromFilename(fileName), Qt::DecorationRole);
DLListModel->setData(DLListModel->index(row, COLUMN_NAME), icon_cache.get_icon(fileName), Qt::DecorationRole);
DLListModel->setData(DLListModel->index(row, COLUMN_COMPLETED), QVariant((qlonglong)completed));
DLListModel->setData(DLListModel->index(row, COLUMN_DLSPEED), QVariant((double)fileDlspeed));
@ -1166,7 +1166,7 @@ int TransfersDialog::addULItem(int row, const FileInfo &fileInfo)
//ULListModel->setItem(row, COLUMN_UPROGRESS, new ProgressItem(NULL));
ULListModel->setData(ULListModel->index(row, COLUMN_UNAME), fileName);
ULListModel->setData(ULListModel->index(row, COLUMN_UNAME), FilesDefs::getIconFromFilename(fileName), Qt::DecorationRole);
ULListModel->setData(ULListModel->index(row, COLUMN_UNAME), icon_cache.get_icon((fileName)), Qt::DecorationRole);
ULListModel->setData(ULListModel->index(row, COLUMN_UHASH), fileHash);
ULListModel->setData(ULListModel->index(row, COLUMN_UHASH), fileHash, Qt::UserRole);
}
@ -2288,3 +2288,65 @@ void TransfersDialog::filterChanged(const QString& /*text*/)
DLLFilterModel->setFilterKeyColumn(filterColumn);
DLLFilterModel->setFilterRegExp(text);
}
//shitcode begin
TransfersDialog_dirty_icon_cache::TransfersDialog_dirty_icon_cache() :
FileTypePicture(":/images/FileTypePicture.png"), FileTypeVideo(":/images/FileTypeVideo.png"), FileTypeAudio(":/images/FileTypeAudio.png"),
FileTypeArchive(":/images/FileTypeArchive.png"), FileTypeProgram(":/images/FileTypeProgram.png"), FileTypeCDImage(":/images/FileTypeCDImage.png"),
FileTypeDocument(":/images/FileTypeDocument.png"), pdf(":/images/mimetypes/pdf.png"), rscollection_16(":/images/mimetypes/rscollection-16.png"),
FileTypeAny(":/images/FileTypeAny.png"), patch(":/images/mimetypes/patch.png"), source_cpp(":/images/mimetypes/source_cpp.png"),
source_h(":/images/mimetypes/source_h.png"), source_c(":/images/mimetypes/source_c.png")
{
}
QIcon& TransfersDialog_dirty_icon_cache::get_icon(const QString& filename)
{
//mostly copypaste from static QString getInfoFromFilename(const QString& filename, bool anyForUnknown, bool image)
QString ext = QFileInfo(filename).suffix().toLower();
if (ext == "jpg" || ext == "jpeg" || ext == "tif" || ext == "tiff" || ext == "png" || ext == "gif" || ext == "bmp" || ext == "ico" || ext == "svg") {
return FileTypePicture;
} else if (ext == "avi" || ext == "mpg" || ext == "mpeg" || ext == "wmv" || ext == "divx" || ext == "ts" ||
ext == "mkv" || ext == "mp4" || ext == "flv" || ext == "mov" || ext == "asf" || ext == "xvid" ||
ext == "vob" || ext == "qt" || ext == "rm" || ext == "3gp" || ext == "ogm") {
return FileTypeVideo;
} else if (ext == "ogg" || ext == "mp3" || ext == "mp1" || ext == "mp2" || ext == "wav" || ext == "wma" || ext == "m4a" || ext == "flac" ||ext == "xpm") {
return FileTypeAudio;
} else if (ext == "tar" || ext == "bz2" || ext == "zip" || ext == "gz" || ext == "7z" || ext == "msi" ||
ext == "rar" || ext == "rpm" || ext == "ace" || ext == "jar" || ext == "tgz" || ext == "lha" ||
ext == "cab" || ext == "cbz"|| ext == "cbr" || ext == "alz" || ext == "sit" || ext == "arj" || ext == "deb") {
return FileTypeArchive;
} else if (ext == "app" || ext == "bat" || ext == "cgi" || ext == "com" ||
ext == "exe" || ext == "js" || ext == "pif" ||
ext == "py" || ext == "pl" || ext == "sh" || ext == "vb" || ext == "ws") {
return FileTypeProgram;
} else if (ext == "iso" || ext == "nrg" || ext == "mdf" || ext == "img" || ext == "dmg" || ext == "bin" || ext == "uif") {
return FileTypeCDImage;
} else if (ext == "txt" || ext == "ui" ||
ext == "doc" || ext == "rtf" || ext == "sxw" || ext == "xls" || ext == "pps" || ext == "xml" || ext == "nfo" ||
ext == "reg" || ext == "sxc" || ext == "odt" || ext == "ods" || ext == "dot" || ext == "ppt" || ext == "css" || ext == "crt" ||
ext == "html" || ext == "htm" || ext == "php") {
return FileTypeDocument;
} else if (ext == "pdf") {
return pdf;
} else if (ext == RsCollection::ExtensionString) {
return rscollection_16;
} else if (ext == "sub" || ext == "srt") {
return FileTypeAny;
} else if (ext == "nds") {
return FileTypeAny;
} else if (ext == "patch" || ext == "diff") {
return patch;
} else if (ext == "cpp") {
return source_cpp;
} else if (ext == "h") {
return source_h;
} else if (ext == "c") {
return source_c;
}
return FileTypeAny;
}
//shitcode end

View File

@ -45,6 +45,20 @@ class SearchDialog;
class LocalSharedFilesDialog;
class RemoteSharedFilesDialog;
//shitcode begin
class TransfersDialog_dirty_icon_cache
{
public:
TransfersDialog_dirty_icon_cache();
QIcon& get_icon(const QString& filename);
private:
QIcon FileTypePicture, FileTypeVideo, FileTypeAudio, FileTypeArchive, FileTypeProgram, FileTypeCDImage, FileTypeDocument, \
pdf, rscollection_16, FileTypeAny, patch, source_cpp, source_h, source_c;
};
//shitcode end
class TransfersDialog : public RsAutoUpdatePage
{
Q_OBJECT
@ -247,6 +261,8 @@ private:
QTreeView *downloadList;
TransfersDialog_dirty_icon_cache icon_cache;
/** Adds a new action to the toolbar. */
void addAction(QAction *action, const char *slot = 0);

View File

@ -731,15 +731,6 @@ bool ChatWidget::eventFilter(QObject *obj, QEvent *event)
}
}
} else {
if (event->type() == QEvent::WindowActivate) {
if (isVisible() && (window() == NULL || window()->isActiveWindow())) {
newMessages = false;
emit infoChanged(this);
focusDialog();
ChatUserNotify::clearWaitingChat(chatId);
}
}
}
// pass the event on to the parent class
return QWidget::eventFilter(obj, event);
@ -889,7 +880,17 @@ void ChatWidget::showEvent(QShowEvent */*event*/)
{
newMessages = false;
emit infoChanged(this);
focusDialog();
// if user waded through the jungle of history just let him on
// own decide whether to continue the journey or start typing
QScrollBar *scrollbar = ui->textBrowser->verticalScrollBar();
bool is_scrollbar_at_end = scrollbar->value() == scrollbar->maximum();
bool is_chat_text_edit_empty = ui->chatTextEdit->toPlainText().isEmpty();
if (is_scrollbar_at_end || !is_chat_text_edit_empty) {
focusDialog();
} else {
// otherwise focus will be get even not chat itself
ui->textBrowser->setFocus();
}
ChatUserNotify::clearWaitingChat(chatId);
if (firstShow) {

View File

@ -25,13 +25,14 @@
#include "GxsIdDetails.h"
#include "RsGxsUpdateBroadcastBase.h"
#include "gui/Identity/IdEditDialog.h"
#include "util/misc.h"
#include <retroshare/rspeers.h>
#include <QSortFilterProxyModel>
#include <QStandardItemModel>
#include <algorithm>
#include <retroshare/rspeers.h>
#include <iostream>
#define ROLE_SORT Qt::UserRole + 1 // Qt::UserRole is reserved for data
@ -247,7 +248,10 @@ uint32_t GxsIdChooser::countEnabledEntries() const
void GxsIdChooser::loadPrivateIds()
{
if (mFirstLoad) {
//whileBlocking doesn't work here.
bool prev = this->blockSignals(true);
clear();
this->blockSignals(prev);
}
std::list<RsGxsId> ids;

View File

@ -74,6 +74,15 @@ QWidget:item:selected
stop: 0 #78879b, stop: 1 #78879b);
}
QTableWidget::item {
color: #C0C0C0;
background-color: #201F1F;
}
QTableWidget::item:selected {
color: black;
}
ForumsDialog, GxsForumThreadWidget
{
qproperty-textColorRead: darkgray;
@ -824,6 +833,14 @@ QDockWidget::close-button:pressed, QDockWidget::float-button:pressed {
background: rgba(255, 255, 255, 10);
}
FriendList {
qproperty-textColorStatusAway: lightgray;
qproperty-textColorStatusBusy: lightgray;
qproperty-textColorStatusOnline: green;
qproperty-textColorStatusInactive: lightgray;
qproperty-textColorStatusOffline: gray;
}
QTreeView, QListView
{
border: 1px solid #78879b;
@ -834,10 +851,22 @@ QTreeView::item {
background-color: #201F1F;
}
QTreeView::item:!selected {
QTreeView::item:selected {
color: black;
}
RSTreeWidget#idTreeWidget::item:!selected {
color: #C0C0C0;
}
NetworkDialog {
qproperty-backgroundColorSelf: darkred;
qproperty-backgroundColorOwnSign: darkred;
qproperty-backgroundColorAcceptConnection: black;
qproperty-backgroundColorHasSignedMe: darkred;
qproperty-backgroundColorDenied: #201F1F;
}
QTreeView:branch:selected, QTreeView:branch:hover
{
background: url(qdarkstyle/transparent.png);

View File

@ -98,7 +98,7 @@ void test_groupStoreAndRetrieve(){
}
RsGxsGrpMetaData *l_Meta = (*mit)->metaData,
*r_Meta = grpMetaR[grpId];
*r_Meta = const_cast<RsGxsGrpMetaData*>(grpMetaR[grpId]);
// assign signSet and mGrpSize
// to right as these values are not stored in db

View File

@ -334,8 +334,8 @@ void GenExchangeTest::init(RsGroupMetaData& grpMetaData) const
randString(SHORT_STR, grpMetaData.mServiceString);
grpMetaData.mGroupFlags = randNum() & (0x00000007);//See GXS_SERV::FLAG_PRIVACY_XXX values /libretroshare/src/retroshare/rsgxsflags.h:21
if (grpMetaData.mGroupFlags == 0) grpMetaData.mGroupFlags = GXS_SERV::FLAG_PRIVACY_PRIVATE;
grpMetaData.mGroupFlags = GXS_SERV::FLAG_PRIVACY_PUBLIC; //randNum() & (0x00000007);//See GXS_SERV::FLAG_PRIVACY_XXX values /libretroshare/src/retroshare/rsgxsflags.h:21
grpMetaData.mLastPost = randNum();
grpMetaData.mGroupStatus = randNum();
grpMetaData.mVisibleMsgCount = randNum();