summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Pösel <robyer@seznam.cz>2014-07-15 15:35:50 +0000
committerRobert Pösel <robyer@seznam.cz>2014-07-15 15:35:50 +0000
commit31576722f7a8fd5c9719852242a2b4e9749830d9 (patch)
treee190a4e42b6b5cbe51d2f9407d4fe79962ee58a5
parentaf9f7df6d22903be7f7a7c8a93d77355bbd7f958 (diff)
Facebook: First phase of chat refactoring
- It loads list of users, their "roles" (myself, friend, user) with friend's names - Fixed some memory leak git-svn-id: http://svn.miranda-ng.org/main/trunk@9809 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
-rw-r--r--protocols/FacebookRM/src/chat.cpp57
-rw-r--r--protocols/FacebookRM/src/client.h3
-rw-r--r--protocols/FacebookRM/src/communication.cpp9
-rw-r--r--protocols/FacebookRM/src/connection.cpp1
-rw-r--r--protocols/FacebookRM/src/contacts.cpp106
-rw-r--r--protocols/FacebookRM/src/entities.h4
-rw-r--r--protocols/FacebookRM/src/json.cpp130
-rw-r--r--protocols/FacebookRM/src/json.h1
-rw-r--r--protocols/FacebookRM/src/process.cpp66
-rw-r--r--protocols/FacebookRM/src/proto.h4
10 files changed, 274 insertions, 107 deletions
diff --git a/protocols/FacebookRM/src/chat.cpp b/protocols/FacebookRM/src/chat.cpp
index 323c36428d..2293592aa4 100644
--- a/protocols/FacebookRM/src/chat.cpp
+++ b/protocols/FacebookRM/src/chat.cpp
@@ -41,8 +41,9 @@ void FacebookProto::UpdateChat(const TCHAR *tchat_id, const char *id, const char
gce.ptszUID = tid;
CallServiceSync(MS_GC_EVENT,0,reinterpret_cast<LPARAM>(&gce));
- std::map<std::tstring, facebook_chatroom>::iterator chatroom = facy.chat_rooms.find(tchat_id);
- chatroom->second.message_readers = "";
+ // TODO: keep it here or move it somewhere else?
+ std::map<std::tstring, facebook_chatroom*>::iterator chatroom = facy.chat_rooms.find(tchat_id);
+ chatroom->second->message_readers = "";
}
void FacebookProto::RenameChat(const char *chat_id, const char *name)
@@ -152,37 +153,36 @@ void FacebookProto::AddChatContact(const TCHAR *tchat_id, const char *id, const
gce.time = ::time(NULL);
gce.bIsMe = !strcmp(id, facy.self_.user_id.c_str());
- if (gce.bIsMe)
- gce.ptszStatus = _T("Admin");
- else
- gce.ptszStatus = _T("Normal");
-
- std::map<std::tstring, facebook_chatroom>::iterator room = facy.chat_rooms.find(tchat_id);
- if(room != facy.chat_rooms.end())
- room->second.participants.insert(std::make_pair(id, name));
+ if (gce.bIsMe) {
+ gce.ptszStatus = _T("Myself");
+ } else {
+ MCONTACT hContact = ContactIDToHContact(id);
+ if (hContact == NULL || getByte(hContact, FACEBOOK_KEY_CONTACT_TYPE, CONTACT_NONE) != CONTACT_FRIEND)
+ gce.ptszStatus = _T("User");
+ else {
+ gce.ptszStatus = _T("Friend");
+ }
+ }
- CallServiceSync(MS_GC_EVENT,0,reinterpret_cast<LPARAM>(&gce));
+ CallServiceSync(MS_GC_EVENT, 0, reinterpret_cast<LPARAM>(&gce));
}
-
-void FacebookProto::RemoveChatContact(const TCHAR *tchat_id, const char *id)
+void FacebookProto::RemoveChatContact(const TCHAR *tchat_id, const char *id, const char *name)
{
// We dont want to remove our self-contact from chat. Ever.
if (!strcmp(id, facy.self_.user_id.c_str()))
return;
+ ptrT tnick(mir_a2t_cp(name, CP_UTF8));
ptrT tid( mir_a2t(id));
GCDEST gcd = { m_szModuleName, tchat_id, GC_EVENT_PART };
GCEVENT gce = { sizeof(gce), &gcd };
gce.dwFlags = GCEF_ADDTOLOG;
- gce.ptszUID = gce.ptszNick = tid;
+ gce.ptszNick = tnick;
+ gce.ptszUID = tid;
gce.time = ::time(NULL);
- gce.bIsMe = false;//!strcmp(id, facy.self_.user_id.c_str());
-
- std::map<std::tstring, facebook_chatroom>::iterator room = facy.chat_rooms.find(tchat_id);
- if (room != facy.chat_rooms.end())
- room->second.participants.erase(id);
+ gce.bIsMe = false;
CallServiceSync(MS_GC_EVENT,0,reinterpret_cast<LPARAM>(&gce));
}
@@ -223,9 +223,11 @@ void FacebookProto::AddChat(const TCHAR *tid, const TCHAR *tname)
GCEVENT gce = { sizeof(gce), &gcd };
// Create a user statuses
- gce.ptszStatus = _T("Admin");
+ gce.ptszStatus = _T("User");
+ CallServiceSync(MS_GC_EVENT, NULL, reinterpret_cast<LPARAM>(&gce));
+ gce.ptszStatus = _T("Friend");
CallServiceSync(MS_GC_EVENT, NULL, reinterpret_cast<LPARAM>(&gce));
- gce.ptszStatus = _T("Normal");
+ gce.ptszStatus = _T("Myself");
CallServiceSync(MS_GC_EVENT, NULL, reinterpret_cast<LPARAM>(&gce));
// Finish initialization
@@ -233,12 +235,8 @@ void FacebookProto::AddChat(const TCHAR *tid, const TCHAR *tname)
gce.time = ::time(NULL);
gce.pDest = &gcd;
- facebook_chatroom chatroom;
- chatroom.chat_name = tname;
- facy.chat_rooms.insert(std::make_pair(tid, chatroom));
-
// Add self contact
- AddChatContact(tid, facy.self_.user_id.c_str(), facy.self_.real_name.c_str());
+ ////AddChatContact(tid, facy.self_.user_id.c_str(), facy.self_.real_name.c_str());
CallServiceSync(MS_GC_EVENT,SESSION_INITDONE,reinterpret_cast<LPARAM>(&gce));
CallServiceSync(MS_GC_EVENT,SESSION_ONLINE, reinterpret_cast<LPARAM>(&gce));
}
@@ -268,10 +266,11 @@ INT_PTR FacebookProto::OnJoinChat(WPARAM hContact, LPARAM suppress)
// Create a group
GCDEST gcd = { m_szModuleName, m_tszUserName, GC_EVENT_ADDGROUP };
GCEVENT gce = { sizeof(gce), &gcd };
- gce.ptszStatus = _T("Admin");
+ gce.ptszStatus = _T("Myself");
CallServiceSync(MS_GC_EVENT, NULL, reinterpret_cast<LPARAM>(&gce));
-
- gce.ptszStatus = _T("Normal");
+ gce.ptszStatus = _T("Friend");
+ CallServiceSync(MS_GC_EVENT, NULL, reinterpret_cast<LPARAM>(&gce));
+ gce.ptszStatus = _T("User");
CallServiceSync(MS_GC_EVENT, NULL, reinterpret_cast<LPARAM>(&gce));
SetTopic("Omegle is a great way of meeting new friends!");
diff --git a/protocols/FacebookRM/src/client.h b/protocols/FacebookRM/src/client.h
index 29b2ba0f95..4b3d23f112 100644
--- a/protocols/FacebookRM/src/client.h
+++ b/protocols/FacebookRM/src/client.h
@@ -97,7 +97,7 @@ public:
std::map<std::string, std::string> cookies;
std::map<std::string, std::string> pages;
- std::map<std::tstring, facebook_chatroom> chat_rooms;
+ std::map<std::tstring, facebook_chatroom*> chat_rooms;
std::map<std::string, facebook_notification*> notifications;
std::string get_newsfeed_type();
@@ -112,6 +112,7 @@ public:
void store_headers(http::response* resp, NETLIBHTTPHEADER* headers, int headers_count);
void clear_cookies();
void clear_notifications();
+ void clear_chatrooms();
////////////////////////////////////////////////////////////
diff --git a/protocols/FacebookRM/src/communication.cpp b/protocols/FacebookRM/src/communication.cpp
index 3faf8da535..8c72bd9be6 100644
--- a/protocols/FacebookRM/src/communication.cpp
+++ b/protocols/FacebookRM/src/communication.cpp
@@ -705,6 +705,15 @@ void facebook_client::clear_notifications()
notifications.clear();
}
+void facebook_client::clear_chatrooms()
+{
+ for (std::map<std::tstring, facebook_chatroom*>::iterator it = chat_rooms.begin(); it != chat_rooms.end();) {
+ delete it->second;
+ it = chat_rooms.erase(it);
+ }
+ chat_rooms.clear();
+}
+
void loginError(FacebookProto *proto, std::string error_str) {
error_str = utils::text::trim(
utils::text::special_expressions_decode(
diff --git a/protocols/FacebookRM/src/connection.cpp b/protocols/FacebookRM/src/connection.cpp
index 56673fe6df..b234928fc4 100644
--- a/protocols/FacebookRM/src/connection.cpp
+++ b/protocols/FacebookRM/src/connection.cpp
@@ -52,6 +52,7 @@ void FacebookProto::ChangeStatus(void*)
facy.clear_cookies();
facy.clear_notifications();
+ facy.clear_chatrooms();
facy.buddies.clear();
facy.messages_ignore.clear();
facy.pages.clear();
diff --git a/protocols/FacebookRM/src/contacts.cpp b/protocols/FacebookRM/src/contacts.cpp
index a4834d6237..ec84cbabb4 100644
--- a/protocols/FacebookRM/src/contacts.cpp
+++ b/protocols/FacebookRM/src/contacts.cpp
@@ -165,16 +165,118 @@ void FacebookProto::LoadContactInfo(facebook_user* fbu)
p->parse_user_info(&resp.data, fbu);
delete p;
- debugLogA("***** Thread info processed");
+ debugLogA("***** Contact thread info processed");
CODE_BLOCK_CATCH
- debugLogA("***** Error processing thread info: %s", e.what());
+ debugLogA("***** Error processing contact thread info: %s", e.what());
CODE_BLOCK_END
}
}
+void FacebookProto::LoadParticipantsNames(facebook_chatroom *fbc)
+{
+ for (std::map<std::string, std::string>::iterator it = fbc->participants.begin(); it != fbc->participants.end(); ++it) {
+ if (it->second.empty()) {
+ if (!strcmp(it->first.c_str(), facy.self_.user_id.c_str()))
+ it->second = facy.self_.real_name;
+ else {
+ MCONTACT hContact = ContactIDToHContact(it->first.c_str());
+ if (hContact != NULL) {
+ DBVARIANT dbv;
+ if (!getStringUtf(hContact, FACEBOOK_KEY_NICK, &dbv)) {
+ it->second = dbv.pszVal;
+ db_free(&dbv);
+ }
+ // TODO: set correct role (friend/user) for this contact here - need rework participants map to <id, participant>
+ }
+
+ // TODO: load unknown contact's names from server
+ if (it->second.empty())
+ it->second = it->first;
+ }
+ }
+ }
+}
+
+void FacebookProto::LoadChatInfo(facebook_chatroom *fbc)
+{
+ std::string data = "client=mercury";
+ data += "&__user=" + facy.self_.user_id;
+ data += "&fb_dtsg=" + (!facy.dtsg_.empty() ? facy.dtsg_ : "0");
+ data += "&__a=1&__dyn=&__req=&ttstamp=0";
+
+ std::string thread_id = utils::url::encode(std::string(_T2A(fbc->thread_id.c_str())));
+
+ // request info about thread
+ data += "&threads[thread_ids][0]=" + thread_id;
+
+ http::response resp = facy.flap(REQUEST_THREAD_INFO, &data);
+
+ if (resp.code == HTTP_CODE_OK) {
+
+ CODE_BLOCK_TRY
+
+ facebook_json_parser* p = new facebook_json_parser(this);
+ p->parse_chat_info(&resp.data, fbc);
+ delete p;
+
+ // Load missing participants names
+ LoadParticipantsNames(fbc);
+
+ // If chat has no name, create name from participants list
+ if (fbc->chat_name.empty()) {
+ unsigned int namesCount = 3; // how many names should be in room name; max. 5
+
+ for (std::map<std::string, std::string>::iterator it = fbc->participants.begin(); it != fbc->participants.end(); ++it) {
+ if (it->second.empty())
+ continue;
+
+ if (!fbc->chat_name.empty())
+ fbc->chat_name += _T(", ");
+
+ std::string name;
+ std::string::size_type pos;
+ if ((pos = it->second.find(" ")) != std::string::npos) {
+ name = it->second.substr(0, pos);
+ }
+ else {
+ name = it->second;
+ }
+
+ fbc->chat_name += _A2T(name.c_str());
+ }
+
+ if (fbc->participants.size() > namesCount) {
+ TCHAR more[200];
+ mir_sntprintf(more, SIZEOF(more), TranslateT("%s and more (%d)"), fbc->chat_name.c_str(), fbc->participants.size() - namesCount);
+ fbc->chat_name = more;
+ }
+
+ // If there are no participants to create a name from, use just thread_id
+ if (fbc->chat_name.empty())
+ fbc->chat_name = fbc->thread_id; // TODO: is this needed? Isn't it showed automatically as id if there is no name?
+ }
+
+ //ReceiveMessages(messages, local_timestamp, true); // don't let it fall into infinite cycle, solve it somehow...
+
+ debugLogA("***** Chat thread info processed");
+
+ CODE_BLOCK_CATCH
+
+ debugLogA("***** Error processing chat thread info: %s", e.what());
+
+ CODE_BLOCK_END
+
+ facy.handle_success("LoadChatInfo");
+ }
+ else {
+ facy.handle_error("LoadChatInfo");
+ }
+
+}
+
MCONTACT FacebookProto::AddToContactList(facebook_user* fbu, ContactType type, bool force_add)
{
// First, check if this contact exists (and if does, just return it)
diff --git a/protocols/FacebookRM/src/entities.h b/protocols/FacebookRM/src/entities.h
index 977b9b635d..0be3d2d396 100644
--- a/protocols/FacebookRM/src/entities.h
+++ b/protocols/FacebookRM/src/entities.h
@@ -88,8 +88,10 @@ struct facebook_user
struct facebook_chatroom
{
- std::tstring chat_name;
+ facebook_chatroom(std::tstring thread_id) : thread_id(thread_id) {}
+
std::tstring thread_id;
+ std::tstring chat_name;
std::map<std::string, std::string> participants;
std::string message_readers;
diff --git a/protocols/FacebookRM/src/json.cpp b/protocols/FacebookRM/src/json.cpp
index 7e2993e5e8..b12fe32378 100644
--- a/protocols/FacebookRM/src/json.cpp
+++ b/protocols/FacebookRM/src/json.cpp
@@ -429,24 +429,25 @@ int facebook_json_parser::parse_messages(void* data, std::vector< facebook_messa
std::tstring tid = json_as_string(threadid);
std::string reader_id = json_as_pstring(reader);
- std::map<std::tstring, facebook_chatroom>::iterator chatroom = proto->facy.chat_rooms.find(tid);
+ std::map<std::tstring, facebook_chatroom*>::iterator chatroom = proto->facy.chat_rooms.find(tid);
if (chatroom != proto->facy.chat_rooms.end()) {
- std::map<std::string, std::string>::const_iterator participant = chatroom->second.participants.find(reader_id);
- if (participant == chatroom->second.participants.end()) {
+ std::map<std::string, std::string>::const_iterator participant = chatroom->second->participants.find(reader_id);
+ if (participant == chatroom->second->participants.end()) {
// TODO: load name of this participant
std::string name = reader_id;
+ chatroom->second->participants.insert(std::make_pair(reader_id, name));
proto->AddChatContact(tid.c_str(), reader_id.c_str(), name.c_str());
}
- participant = chatroom->second.participants.find(reader_id);
- if (participant != chatroom->second.participants.end()) {
+ participant = chatroom->second->participants.find(reader_id);
+ if (participant != chatroom->second->participants.end()) {
MCONTACT hChatContact = proto->ChatIDToHContact(tid);
- if (!chatroom->second.message_readers.empty())
- chatroom->second.message_readers += ", ";
- chatroom->second.message_readers += participant->second;
+ if (!chatroom->second->message_readers.empty())
+ chatroom->second->message_readers += ", ";
+ chatroom->second->message_readers += participant->second;
- ptrT readers(mir_utf8decodeT(chatroom->second.message_readers.c_str()));
+ ptrT readers(mir_utf8decodeT(chatroom->second->message_readers.c_str()));
StatusTextData st = { 0 };
st.cbSize = sizeof(st);
@@ -594,17 +595,17 @@ int facebook_json_parser::parse_messages(void* data, std::vector< facebook_messa
std::tstring tid = json_as_string(thread_);
std::string from_id = json_as_pstring(from_);
- std::map<std::tstring, facebook_chatroom>::iterator chatroom = proto->facy.chat_rooms.find(tid);
+ std::map<std::tstring, facebook_chatroom*>::iterator chatroom = proto->facy.chat_rooms.find(tid);
if (chatroom != proto->facy.chat_rooms.end()) {
- std::map<std::string, std::string>::const_iterator participant = chatroom->second.participants.find(from_id);
- if (participant == chatroom->second.participants.end()) {
+ std::map<std::string, std::string>::const_iterator participant = chatroom->second->participants.find(from_id);
+ if (participant == chatroom->second->participants.end()) {
// TODO: load name of this participant
std::string name = from_id;
proto->AddChatContact(tid.c_str(), from_id.c_str(), name.c_str());
}
- participant = chatroom->second.participants.find(from_id);
- if (participant != chatroom->second.participants.end()) {
+ participant = chatroom->second->participants.find(from_id);
+ if (participant != chatroom->second->participants.end()) {
MCONTACT hChatContact = proto->ChatIDToHContact(tid);
ptrT name(mir_utf8decodeT(participant->second.c_str()));
@@ -779,9 +780,7 @@ int facebook_json_parser::parse_thread_messages(void* data, std::vector< faceboo
// Ignore "wrong" (duplicit) identifiers - these that doesn't begin with "id."
if (id.substr(0, 3) == _T("id.")) {
- facebook_chatroom *room = new facebook_chatroom();
- room->thread_id = id;
-
+ facebook_chatroom *room = new facebook_chatroom(id);
chatrooms->insert(std::make_pair((char*)_T2A(room->thread_id.c_str()), room));
}
}
@@ -987,61 +986,74 @@ int facebook_json_parser::parse_user_info(void* data, facebook_user* fbu)
return EXIT_SUCCESS;
}
-/* TODO: implement this somehow
-int facebook_json_parser::parse_chat_info(void* data, facebook_chat* fbu) {
- // This is a recent 5 person listing of participants.
- JSONNODE *participants_ids = json_get(gthreadinfo, "participant_ids");
- JSONNODE *participants_names = json_get(gthreadinfo, "participant_names");
+int facebook_json_parser::parse_chat_info(void* data, facebook_chatroom* fbc)
+{
+ std::string jsonData = static_cast< std::string* >(data)->substr(9);
- JSONNODE *thread_name_ = json_get(gthreadinfo, "name");
- std::tstring name = json_as_string(thread_name_);
+ JSONNODE *root = json_parse(jsonData.c_str());
+ if (root == NULL)
+ return EXIT_FAILURE;
- // if there is no name for this room, set own name
- if (name.empty()) {
- unsigned int namesCount = 3; // how many names should be in room name; max. 5
+ JSONNODE *payload = json_get(root, "payload");
+ if (payload == NULL) {
+ json_delete(root);
+ return EXIT_FAILURE;
+ }
+
+ //JSONNODE *actions = json_get(payload, "actions");
+ JSONNODE *threads = json_get(payload, "threads");
+ if (/*actions == NULL || */threads == NULL) {
+ json_delete(root);
+ return EXIT_FAILURE;
+ }
- for (unsigned int n = 0; n < json_size(participants_names) && n < namesCount; n++) {
- JSONNODE *nameItr = json_at(participants_names, n);
+ /*JSONNODE *roger = json_get(payload, "roger");
+ if (roger != NULL) {
+ for (unsigned int i = 0; i < json_size(roger); i++) {
+ JSONNODE *it = json_at(roger, i);
+ std::tstring id = _A2T(json_name(it));
- if (!name.empty())
- name += _T(", ");
+ // Ignore "wrong" (duplicit) identifiers - these that doesn't begin with "id."
+ if (id.substr(0, 3) == _T("id.")) {
+ facebook_chatroom *room = new facebook_chatroom();
+ room->thread_id = id;
- name += json_as_string(nameItr);
+ chatrooms->insert(std::make_pair((char*)_T2A(room->thread_id.c_str()), room));
+ }
}
- JSONNODE *count_ = json_get(gthreadinfo, "participant_total_count");
- unsigned int count = json_as_int(count_);
+ }*/
- if (count > namesCount) {
- TCHAR more[200];
- mir_sntprintf(more, SIZEOF(more), TranslateT("%s and more (%d)"), name.c_str(), count - namesCount);
- name = more;
- }
- }
+ std::map<std::string, std::string> thread_ids;
+ for (unsigned int i = 0; i < json_size(threads); i++) {
+ JSONNODE *it = json_at(threads, i);
- if (name.empty())
- name = thread_id;
+ JSONNODE *is_canonical_user_ = json_get(it, "is_canonical_user");
+ JSONNODE *thread_id_ = json_get(it, "thread_id");
+ JSONNODE *name_ = json_get(it, "name");
+ //JSONNODE *message_count_ = json_get(it, "message_count");
+ JSONNODE *unread_count_ = json_get(it, "unread_count"); // TODO: use it to check against number of loaded messages... but how?
+ JSONNODE *folder_ = json_get(it, "folder");
- for (unsigned int n = 0; n < json_size(participants_ids); n++) {
- JSONNODE *idItr = json_at(participants_ids, n);
- std::string pId = json_as_pstring(idItr);
+ if (thread_id_ == NULL || is_canonical_user_ == NULL || json_as_bool(is_canonical_user_))
+ continue;
- JSONNODE *nameItr = json_at(participants_names, n);
- std::string pName = json_as_pstring(nameItr);
+ std::tstring tid = json_as_string(thread_id_);
- if (!proto->IsChatContact(thread_id.c_str(), pId.c_str())) {
- proto->AddChatContact(thread_id.c_str(), pId.c_str(), pName.c_str());
+ // TODO: allow more users to parse at once
+ if (fbc->thread_id != tid) {
+ continue;
}
- }
- std::string senderName = json_as_pstring(sender_name);
- std::string::size_type pos;
- if ((pos = senderName.find(" ")) != std::string::npos) {
- senderName = senderName.substr(0, pos);
- }
+ JSONNODE *participants = json_get(it, "participants");
+ for (unsigned int j = 0; j < json_size(participants); j++) {
+ JSONNODE *jt = json_at(participants, j);
+ std::string user_id = json_as_pstring(jt);
+ fbc->participants.insert(std::make_pair(user_id.substr(5), ""));
+ }
- // Last fall-back for adding this sender (in case he was not in the participants) - is this even needed?
- if (!proto->IsChatContact(thread_id.c_str(), id.c_str())) {
- proto->AddChatContact(thread_id.c_str(), id.c_str(), senderName.c_str());
+ fbc->chat_name = json_as_string(name_);
}
+
+ json_delete(root);
+ return EXIT_SUCCESS;
}
-*/ \ No newline at end of file
diff --git a/protocols/FacebookRM/src/json.h b/protocols/FacebookRM/src/json.h
index 70001e4a31..d1e8f2e44d 100644
--- a/protocols/FacebookRM/src/json.h
+++ b/protocols/FacebookRM/src/json.h
@@ -38,6 +38,7 @@ public:
int parse_thread_messages(void*, std::vector< facebook_message* >*, std::map< std::string, facebook_chatroom* >*, bool unreadOnly, bool inboxOnly, int limit);
int parse_thread_info(void* data, std::string* user_id);
int parse_user_info(void* data, facebook_user* fbu);
+ int parse_chat_info(void* data, facebook_chatroom* fbc);
facebook_json_parser(FacebookProto* proto)
{
diff --git a/protocols/FacebookRM/src/process.cpp b/protocols/FacebookRM/src/process.cpp
index 2f13369f5a..0d87147a58 100644
--- a/protocols/FacebookRM/src/process.cpp
+++ b/protocols/FacebookRM/src/process.cpp
@@ -380,9 +380,12 @@ void FacebookProto::ProcessUnreadMessage(void *p)
for (std::map<std::string, facebook_chatroom*>::iterator it = chatrooms.begin(); it != chatrooms.end(); ) {
- facebook_chatroom *room = it->second;
+ // TODO: refactor this too!
+ // TODO: have all chatrooms in facy, in memory, and then handle them as needed... somehow think about it...
+ /* facebook_chatroom *room = it->second;
MCONTACT hChatContact = NULL;
- if (GetChatUsers(room->thread_id.c_str()) == NULL) {
+ ptrA users(GetChatUsers(room->thread_id.c_str()));
+ if (users == NULL) {
AddChat(room->thread_id.c_str(), room->chat_name.c_str());
hChatContact = ChatIDToHContact(room->thread_id);
// Set thread id (TID) for later
@@ -397,7 +400,7 @@ void FacebookProto::ProcessUnreadMessage(void *p)
if (!hChatContact)
hChatContact = ChatIDToHContact(room->thread_id);
- ForkThread(&FacebookProto::ReadMessageWorker, (void*)hChatContact);
+ ForkThread(&FacebookProto::ReadMessageWorker, (void*)hChatContact);*/
delete it->second;
it = chatrooms.erase(it);
@@ -485,11 +488,13 @@ CODE_BLOCK_TRY
p->parse_thread_messages(&resp.data, &messages, &chatrooms, false, false, 20);
delete p;
- for (std::map<std::string, facebook_chatroom*>::iterator it = chatrooms.begin(); it != chatrooms.end();) {
+ // TODO: do something with this, chat is loading somewhere else... (in receiveMessages method right now)
+ /*for (std::map<std::string, facebook_chatroom*>::iterator it = chatrooms.begin(); it != chatrooms.end();) {
facebook_chatroom *room = it->second;
MCONTACT hChatContact = NULL;
- if (GetChatUsers(room->thread_id.c_str()) == NULL) {
+ ptrA users(GetChatUsers(room->thread_id.c_str()));
+ if (users == NULL) {
AddChat(room->thread_id.c_str(), room->chat_name.c_str());
hChatContact = ChatIDToHContact(room->thread_id);
// Set thread id (TID) for later
@@ -509,7 +514,7 @@ CODE_BLOCK_TRY
delete it->second;
it = chatrooms.erase(it);
}
- chatrooms.clear();
+ chatrooms.clear();*/
bool local_timestamp = getBool(FACEBOOK_KEY_LOCAL_TIMESTAMP_UNREAD, 0);
ReceiveMessages(messages, local_timestamp, true);
@@ -584,25 +589,51 @@ void FacebookProto::ReceiveMessages(std::vector<facebook_message*> messages, boo
// Multi-user message
debugLogA(" Got chat message: %s", messages[i]->message_text.c_str());
+ facebook_chatroom *fbc;
std::tstring tthread_id = _A2T(messages[i]->thread_id.c_str());
- // RM TODO: better use check if chatroom exists/is in db/is online... no?
- // like: if (ChatIDToHContact(tthread_id) == NULL) {
- if (GetChatUsers(tthread_id.c_str()) == NULL) {
+ std::map<std::tstring, facebook_chatroom*>::iterator it = facy.chat_rooms.find(tthread_id);
+ if (it != facy.chat_rooms.end()) {
+ fbc = it->second;
+ } else {
// In Naseem's spam mode we ignore outgoing messages sent from other instances
if (naseemsSpamMode && !messages[i]->isIncoming) {
delete messages[i];
continue;
}
- // TODO: We don't have this chat, lets load info about it (name, list of users, last messages, etc.)
- //LoadChatInfo(&fbu); // In this method use json's parse_chat_info
- std::tstring tthread_name = tthread_id; // TODO: use correct name for chat, not thread_id
+ // We don't have this chat loaded in memory yet, lets load some info (name, list of users)
+ fbc = new facebook_chatroom(tthread_id);
+ LoadChatInfo(fbc);
+ facy.chat_rooms.insert(std::make_pair(tthread_id, fbc));
+ }
- AddChat(tthread_id.c_str(), tthread_name.c_str());
+ MCONTACT hChatContact;
+ // RM TODO: better use check if chatroom exists/is in db/is online... no?
+ // like: if (ChatIDToHContact(tthread_id) == NULL) {
+ ptrA users(GetChatUsers(tthread_id.c_str()));
+ if (users == NULL) {
+ AddChat(fbc->thread_id.c_str(), fbc->chat_name.c_str());
+ hChatContact = ChatIDToHContact(fbc->thread_id);
+ // Set thread id (TID) for later
+ setTString(hChatContact, FACEBOOK_KEY_TID, fbc->thread_id.c_str());
+
+ for (std::map<std::string, std::string>::iterator jt = fbc->participants.begin(); jt != fbc->participants.end(); ++jt) {
+ // If this contact isn't already in chat, add it
+ if (!IsChatContact(fbc->thread_id.c_str(), jt->first.c_str())) // TODO: is this needed?
+ AddChatContact(fbc->thread_id.c_str(), jt->first.c_str(), jt->second.c_str());
+ }
}
- MCONTACT hChatContact = ChatIDToHContact(tthread_id);
+ if (!hChatContact)
+ hChatContact = ChatIDToHContact(fbc->thread_id);
+
+ if (!hChatContact) {
+ // hopefully shouldn't happen, but who knows?
+ debugLog(_T("! ! ! No hChatContact for %s"), fbc->thread_id.c_str());
+ delete messages[i];
+ continue;
+ }
// Save last (this) message ID
setString(hChatContact, FACEBOOK_KEY_MESSAGE_ID, messages[i]->message_id.c_str());
@@ -642,6 +673,13 @@ void FacebookProto::ReceiveMessages(std::vector<facebook_message*> messages, boo
hContact = AddToContactList(&fbu, CONTACT_NONE);
}
+ if (!hContact) {
+ // hopefully shouldn't happen, but who knows?
+ debugLogA("! ! ! No hContact for %s", messages[i]->user_id);
+ delete messages[i];
+ continue;
+ }
+
// Save last (this) message ID
setString(hContact, FACEBOOK_KEY_MESSAGE_ID, messages[i]->message_id.c_str());
diff --git a/protocols/FacebookRM/src/proto.h b/protocols/FacebookRM/src/proto.h
index 7a1b208707..8fd911ed63 100644
--- a/protocols/FacebookRM/src/proto.h
+++ b/protocols/FacebookRM/src/proto.h
@@ -210,10 +210,12 @@ public:
void RenameChat(const char *chat_id, const char *name);
bool IsChatContact(const TCHAR *chat_id, const char *id);
void AddChatContact(const TCHAR *chat_id, const char *id, const char *name);
- void RemoveChatContact(const TCHAR *chat_id, const char *id);
+ void RemoveChatContact(const TCHAR *chat_id, const char *id, const char *name);
void SetChatStatus(const char *chat_id, int status);
char *GetChatUsers(const TCHAR *chat_id);
void ReceiveMessages(std::vector<facebook_message*> messages, bool local_timestamp, bool check_duplicates = false);
+ void LoadChatInfo(facebook_chatroom* fbc);
+ void LoadParticipantsNames(facebook_chatroom *fbc);
// Connection client
facebook_client facy; // TODO: Refactor to "client" and make dynamic