diff options
author | Robert Pösel <robyer@seznam.cz> | 2014-04-14 10:03:02 +0000 |
---|---|---|
committer | Robert Pösel <robyer@seznam.cz> | 2014-04-14 10:03:02 +0000 |
commit | 5a3503225b9f0b864e901067867e481905f8f2d9 (patch) | |
tree | 7d3552a84a66da83342de73320900dfdedea42a6 /protocols | |
parent | 98cc2fb7669f4fe014c78baca0e71015f63b6191 (diff) |
Facebook: Refactor receiving multi-chat messages
- This will broke loading list of 5 users in room
- Instead of name it will use id everytime
-> but this will be fixed in the future in some better way than it was
git-svn-id: http://svn.miranda-ng.org/main/trunk@8971 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'protocols')
-rw-r--r-- | protocols/FacebookRM/src/json.cpp | 154 | ||||
-rw-r--r-- | protocols/FacebookRM/src/process.cpp | 48 |
2 files changed, 109 insertions, 93 deletions
diff --git a/protocols/FacebookRM/src/json.cpp b/protocols/FacebookRM/src/json.cpp index 65e2658dd7..9c85ebc08d 100644 --- a/protocols/FacebookRM/src/json.cpp +++ b/protocols/FacebookRM/src/json.cpp @@ -3,7 +3,7 @@ Facebook plugin for Miranda Instant Messenger
_____________________________________________
-Copyright © 2009-11 Michal Zelinka, 2011-13 Robert Pösel
+Copyright � 2009-11 Michal Zelinka, 2011-13 Robert P�sel
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -521,85 +521,29 @@ int facebook_json_parser::parse_messages(void* data, std::vector< facebook_messa if (message_text.empty())
continue;
- // Multi-user
JSONNODE *gthreadinfo = json_get(msg, "group_thread_info");
if (gthreadinfo != NULL) {
- std::tstring thread_id = json_as_string(tid);
-
- // 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");
-
- JSONNODE *thread_name_ = json_get(gthreadinfo, "name");
- std::tstring name = json_as_string(thread_name_);
-
- // 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
-
- for (unsigned int n = 0; n < json_size(participants_names) && n < namesCount; n++) {
- JSONNODE *nameItr = json_at(participants_names, n);
-
- if (!name.empty())
- name += _T(", ");
-
- name += json_as_string(nameItr);
- }
- 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;
- }
- }
-
- MCONTACT hChatContact = NULL;
-
- // RM TODO: better use check if chatroom exists/is in db/is online... no?
- /// e.g. HANDLE hChatContact = proto->ChatIDToHContact(thread_id); ?
- if (proto->GetChatUsers(thread_id.c_str()) == NULL) {
- proto->AddChat(thread_id.c_str(), name.c_str());
- hChatContact = proto->ChatIDToHContact(thread_id);
- // Set thread id (TID) for later
- proto->setTString(hChatContact, FACEBOOK_KEY_TID, thread_id.c_str());
- }
-
- if (!hChatContact)
- hChatContact = proto->ChatIDToHContact(thread_id);
-
- 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);
-
- JSONNODE *nameItr = json_at(participants_names, n);
- std::string pName = json_as_pstring(nameItr);
-
- if (!proto->IsChatContact(thread_id.c_str(), pId.c_str())) {
- proto->AddChatContact(thread_id.c_str(), pId.c_str(), pName.c_str());
- }
- }
-
- 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);
- }*/
+ // Multi-user message
+ facebook_message* message = new facebook_message();
- // 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());
- }
+ message->isChat = true;
+ message->isUnread = true;
+ message->isIncoming = (id != proto->facy.self_.user_id);
+ message->message_text = message_text;
+ message->sender_name = utils::text::special_expressions_decode(utils::text::slashu_to_utf8(json_as_pstring(sender_name))); // TODO: or if not incomming use my own name from facy.self_ ?
+ message->time = utils::time::fix_timestamp(json_as_float(timestamp));
+ message->thread_id = json_as_pstring(tid); // TODO: or if not incomming use my own id from facy.self_ ?
+ message->user_id = id;
+ message->message_id = message_id;
- // Update chat with message
- // TODO: support also system messages (rename chat, user quit, etc.)! (here? or it is somewhere else?)
- proto->UpdateChat(thread_id.c_str(), id.c_str(), senderName.c_str(), message_text.c_str(), utils::time::fix_timestamp(json_as_float(timestamp)));
- proto->setString(hChatContact, FACEBOOK_KEY_MESSAGE_ID, message_id.c_str());
- proto->ForkThread(&FacebookProto::ReadMessageWorker, (void*)hChatContact);
- } else {
+ messages->push_back(message);
+ }
+ else {
+ // Standard message
facebook_message* message = new facebook_message();
-
+
+ message->isChat = false;
+ message->isUnread = true;
message->isIncoming = (id != proto->facy.self_.user_id);
message->message_text = message_text;
message->sender_name = message->isIncoming ? utils::text::special_expressions_decode(utils::text::slashu_to_utf8(json_as_pstring(sender_name))) : "";
@@ -846,6 +790,7 @@ int facebook_json_parser::parse_thread_messages(void* data, std::vector< faceboo JSONNODE *canonical = json_get(it, "canonical_fbid");
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");
@@ -1025,3 +970,62 @@ int facebook_json_parser::parse_user_info(void* data, facebook_user* fbu) json_delete(root);
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");
+
+ JSONNODE *thread_name_ = json_get(gthreadinfo, "name");
+ std::tstring name = json_as_string(thread_name_);
+
+ // 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
+
+ for (unsigned int n = 0; n < json_size(participants_names) && n < namesCount; n++) {
+ JSONNODE *nameItr = json_at(participants_names, n);
+
+ if (!name.empty())
+ name += _T(", ");
+
+ name += json_as_string(nameItr);
+ }
+ 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;
+ }
+ }
+
+ if (name.empty())
+ name = thread_id;
+
+ 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);
+
+ JSONNODE *nameItr = json_at(participants_names, n);
+ std::string pName = json_as_pstring(nameItr);
+
+ if (!proto->IsChatContact(thread_id.c_str(), pId.c_str())) {
+ proto->AddChatContact(thread_id.c_str(), pId.c_str(), pName.c_str());
+ }
+ }
+
+ 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);
+ }
+
+ // 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());
+ }
+}
+*/
\ No newline at end of file diff --git a/protocols/FacebookRM/src/process.cpp b/protocols/FacebookRM/src/process.cpp index 2d6802bfe8..d0dc4085d6 100644 --- a/protocols/FacebookRM/src/process.cpp +++ b/protocols/FacebookRM/src/process.cpp @@ -411,20 +411,16 @@ void FacebookProto::ReceiveMessages(std::vector<facebook_message*> messages, boo bool naseemsSpamMode = getBool(FACEBOOK_KEY_NASEEMS_SPAM_MODE, false);
for(std::vector<facebook_message*>::size_type i = 0; i < messages.size(); i++) {
+ DWORD timestamp = local_timestamp || !messages[i]->time ? ::time(NULL) : messages[i]->time;
+
if (messages[i]->isChat) {
+ // Multi-user message
debugLogA(" Got chat message: %s", messages[i]->message_text.c_str());
std::tstring tthread_id = _A2T(messages[i]->thread_id.c_str());
- std::string user_id = messages[i]->user_id;
- std::string user_name = messages[i]->sender_name;
- std::string message_text = messages[i]->message_text;
- std::string message_id = messages[i]->message_id;
- DWORD timestamp = local_timestamp || !messages[i]->time ? ::time(NULL) : messages[i]->time;
-
- MCONTACT hChatContact = ChatIDToHContact(tthread_id);
// RM TODO: better use check if chatroom exists/is in db/is online... no?
- /// e.g. HANDLE hChatContact = proto->ChatIDToHContact(thread_id); ?
+ // like: if (ChatIDToHContact(tthread_id) == NULL) {
if (GetChatUsers(tthread_id.c_str()) == NULL) {
// In Naseem's spam mode we ignore outgoing messages sent from other instances
if (naseemsSpamMode && !messages[i]->isIncoming) {
@@ -432,20 +428,35 @@ void FacebookProto::ReceiveMessages(std::vector<facebook_message*> messages, boo continue;
}
- AddChat(tthread_id.c_str(), tthread_id.c_str()); // TODO: use correct name for chat, not thread_id
- hChatContact = ChatIDToHContact(tthread_id);
- // Set thread id (TID) for later
- setTString(hChatContact, FACEBOOK_KEY_TID, tthread_id.c_str());
+ // 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
+
+ AddChat(tthread_id.c_str(), tthread_name.c_str());
}
- if (!hChatContact)
- hChatContact = ChatIDToHContact(tthread_id);
+ MCONTACT hChatContact = ChatIDToHContact(tthread_id);
+
+ // Save last (this) message ID
+ setString(hChatContact, FACEBOOK_KEY_MESSAGE_ID, messages[i]->message_id.c_str());
- UpdateChat(tthread_id.c_str(), user_id.c_str(), user_name.c_str(), message_text.c_str(), timestamp);
- setString(hChatContact, FACEBOOK_KEY_MESSAGE_ID, message_id.c_str());
+ // Save TID if not exists already
+ ptrA tid(getStringA(hChatContact, FACEBOOK_KEY_TID));
+ if (!tid || strcmp(tid, messages[i]->thread_id.c_str()))
+ setString(hChatContact, FACEBOOK_KEY_TID, messages[i]->thread_id.c_str());
+
+ ParseSmileys(messages[i]->message_text, hChatContact);
+
+ // TODO: support also system messages (rename chat, user quit, etc.)! (here? or it is somewhere else?
+ // ... we must add some new "type" field into facebook_message structure and use it also for Pokes and similar)
+ UpdateChat(tthread_id.c_str(), messages[i]->user_id.c_str(), messages[i]->sender_name.c_str(), messages[i]->message_text.c_str(), timestamp);
+
+ // Automatically mark message as read because chatroom doesn't support onRead event (yet)
ForkThread(&FacebookProto::ReadMessageWorker, (void*)hChatContact);
} else {
+ // Single-user message
debugLogA(" Got message: %s", messages[i]->message_text.c_str());
+
facebook_user fbu;
fbu.user_id = messages[i]->user_id;
fbu.real_name = messages[i]->sender_name;
@@ -464,6 +475,7 @@ void FacebookProto::ReceiveMessages(std::vector<facebook_message*> messages, boo hContact = AddToContactList(&fbu, CONTACT_NONE);
}
+ // Save last (this) message ID
setString(hContact, FACEBOOK_KEY_MESSAGE_ID, messages[i]->message_id.c_str());
// Save TID if not exists already
@@ -477,7 +489,7 @@ void FacebookProto::ReceiveMessages(std::vector<facebook_message*> messages, boo PROTORECVEVENT recv = { 0 };
recv.flags = PREF_UTF;
recv.szMessage = const_cast<char*>(messages[i]->message_text.c_str());
- recv.timestamp = local_timestamp || !messages[i]->time ? ::time(NULL) : messages[i]->time;
+ recv.timestamp = timestamp;
ProtoChainRecvMsg(hContact, &recv);
} else {
DBEVENTINFO dbei = { 0 };
@@ -485,7 +497,7 @@ void FacebookProto::ReceiveMessages(std::vector<facebook_message*> messages, boo dbei.eventType = EVENTTYPE_MESSAGE;
dbei.flags = DBEF_SENT | DBEF_UTF;
dbei.szModule = m_szModuleName;
- dbei.timestamp = local_timestamp || !messages[i]->time ? ::time(NULL) : messages[i]->time;
+ dbei.timestamp = timestamp;
dbei.cbBlob = (DWORD)messages[i]->message_text.length() + 1;
dbei.pBlob = (PBYTE)messages[i]->message_text.c_str();
db_event_add(hContact, &dbei);
|