From e4b1413ff3fb8c169e2725c3e7686f47eaf93ec8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20P=C3=B6sel?= Date: Sat, 27 Apr 2013 08:56:44 +0000 Subject: Facebook: Fixed getting offline messages. Loading some timestamp value of contacts (dword "LastActiveTS") for... I don't know. Version bump. git-svn-id: http://svn.miranda-ng.org/main/trunk@4548 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/FacebookRM/src/process.cpp | 232 +++++++++++++++++++---------------- 1 file changed, 129 insertions(+), 103 deletions(-) (limited to 'protocols/FacebookRM/src/process.cpp') diff --git a/protocols/FacebookRM/src/process.cpp b/protocols/FacebookRM/src/process.cpp index e0608e3555..35aaa52bff 100644 --- a/protocols/FacebookRM/src/process.cpp +++ b/protocols/FacebookRM/src/process.cpp @@ -97,13 +97,20 @@ void FacebookProto::ProcessBuddyList(void* data) fbu->handle = AddToContactList(fbu, FACEBOOK_CONTACT_FRIEND); if (!fbu->real_name.empty()) { - db_set_utf(fbu->handle,m_szModuleName,FACEBOOK_KEY_NAME,fbu->real_name.c_str()); - db_set_utf(fbu->handle,m_szModuleName,FACEBOOK_KEY_NICK,fbu->real_name.c_str()); + db_set_utf(fbu->handle, m_szModuleName, FACEBOOK_KEY_NAME, fbu->real_name.c_str()); + db_set_utf(fbu->handle, m_szModuleName, FACEBOOK_KEY_NICK, fbu->real_name.c_str()); } } - if (db_get_w(fbu->handle,m_szModuleName,"Status", 0) != fbu->status_id) { - db_set_w(fbu->handle,m_szModuleName,"Status", fbu->status_id); + if (db_get_w(fbu->handle, m_szModuleName, "Status", 0) != fbu->status_id) { + db_set_w(fbu->handle, m_szModuleName, "Status", fbu->status_id); + } + + if (db_get_dw(fbu->handle, m_szModuleName, "LastActiveTS", 0) != fbu->last_active) { + if (fbu->last_active > 0) + db_set_dw(fbu->handle, m_szModuleName, "LastActiveTS", fbu->last_active); + else + db_unset(fbu->handle, m_szModuleName, "LastActiveTS"); } if (db_get_b(fbu->handle, m_szModuleName, FACEBOOK_KEY_CONTACT_TYPE, 0) != FACEBOOK_CONTACT_FRIEND) { @@ -278,145 +285,164 @@ void FacebookProto::ProcessUnreadMessages(void*) { facy.handle_entry("messages"); - std::string get_data = "sk=inbox&query=is%3Aunread"; + int count = 0; + std::string page; - std::string data = "&fb_dtsg=" + facy.dtsg_; - data += "&lsd=&phstamp=" + utils::time::mili_timestamp(); - data += "&__user=" + facy.self_.user_id; + while (count < 30) // allow max 30 unread threads to be parsed + { + std::string get_data = "&page=" + page; - // Get unread inbox threads - http::response resp = facy.flap(FACEBOOK_REQUEST_ASYNC, &data, &get_data); + http::response resp = facy.flap(FACEBOOK_REQUEST_UNREAD_MESSAGES, NULL, &get_data); - // sk=inbox, sk=other + // Process result data + facy.validate_response(&resp); - // Process result data - facy.validate_response(&resp); + if (resp.code == HTTP_CODE_OK) + { + std::string items = utils::text::source_get_value(&resp.data, 2, "
"); - if (resp.code != HTTP_CODE_OK) { - facy.handle_error("messages"); - return; + std::string::size_type pos = 0; + std::string::size_type pos2 = 0; + + while ((pos = items.find("id=\"threadlist_row_", pos)) != std::string::npos) { + std::string item = items.substr(pos, items.find("
", pos) - pos); + pos++; count++; + + std::string tid = utils::text::source_get_value2(&item, "?tid=", "&\""); + if (tid.empty()) + continue; + + std::string* data = new std::string(tid); + ForkThread(&FacebookProto::ProcessUnreadMessage, this, (void*)data); + } + + page = utils::text::source_get_value(&items, 3, "id=\"see_older_threads\"", "page=", "&"); + if (page.empty()) + break; // No more results + } } - std::string threadlist = utils::text::slashu_to_utf8(resp.data); - - std::string::size_type pos = 0; +} - while ((pos = threadlist.find("
  • ", pos); - std::string thread_content = threadlist.substr(pos, pos2 - pos); +void FacebookProto::ProcessUnreadMessage(void *tid_data) +{ + if (tid_data == NULL) + return; - pos = pos2; + std::string* tid = (std::string*)tid_data; - get_data = "sk=inbox&query=is%3Aunread&thread_query=is%3Aunread&action=read&tid="; - get_data += utils::text::source_get_value(&thread_content, 2, "id=\\\"", "\\\""); - utils::text::replace_all(&get_data, "+", "%2B"); - - resp = facy.flap(FACEBOOK_REQUEST_ASYNC, &data, &get_data); - // TODO: move this to new thread... + std::string data = "&fb_dtsg=" + facy.dtsg_; + data += "&lsd=&phstamp=" + utils::time::mili_timestamp(); + data += "&__user=" + facy.self_.user_id; - facy.validate_response(&resp); + std::string get_data = "sk=inbox&query=is%3Aunread&thread_query=is%3Aunread&action=read&tid=" + *tid; + http::response resp = facy.flap(FACEBOOK_REQUEST_ASYNC, &data, &get_data); + // TODO: move this to new thread... - if (resp.code != HTTP_CODE_OK) { - LOG(" !! !! Error when getting messages list"); - continue; - } + facy.validate_response(&resp); + + if (resp.code != HTTP_CODE_OK) { + LOG(" !! !! Error when getting messages list"); + delete tid; + return; + } - std::string messageslist = utils::text::slashu_to_utf8(resp.data); + std::string messageslist = utils::text::slashu_to_utf8(resp.data); - std::string user_id = utils::text::source_get_value(&messageslist, 2, "single_thread_id\":", ","); - if (user_id.empty()) { - LOG(" !! !! Thread id is empty - this is groupchat message."); // TODO: remove as this is not such 'error' - continue; - } - - facebook_user fbu; - fbu.user_id = user_id; - - HANDLE hContact = AddToContactList(&fbu, FACEBOOK_CONTACT_NONE); - // TODO: if contact is newly added, get his user info - // TODO: maybe create new "receiveMsg" function and use it for offline and channel messages? + std::string user_id = utils::text::source_get_value(&messageslist, 2, "single_thread_id\":", ","); + if (user_id.empty()) { + LOG(" !! !! Thread id is empty - this is groupchat message."); // TODO: remove as this is not such 'error' + delete tid; + return; + } - pos2 = 0; - while ((pos2 = messageslist.find("class=\\\"MessagingMessage ", pos2)) != std::string::npos) { - pos2 += 8; - std::string strclass = messageslist.substr(pos2, messageslist.find("\\\"", pos2) - pos2); + facebook_user fbu; + fbu.user_id = user_id; - if (strclass.find("MessagingMessageUnread") == std::string::npos) - continue; // ignoring old messages + HANDLE hContact = AddToContactList(&fbu, FACEBOOK_CONTACT_NONE); + // TODO: if contact is newly added, get his user info + // TODO: maybe create new "receiveMsg" function and use it for offline and channel messages? - //std::string::size_type pos3 = messageslist.find("/li>", pos2); // TODO: ne proti tomuhle li, protože i přílohy mají li... - std::string::size_type pos3 = messageslist.find("class=\\\"MessagingMessage ", pos2); - std::string messagesgroup = messageslist.substr(pos2, pos3 - pos2); + std::string::size_type pos2 = 0; + while ((pos2 = messageslist.find("class=\\\"MessagingMessage ", pos2)) != std::string::npos) { + pos2 += 8; + std::string strclass = messageslist.substr(pos2, messageslist.find("\\\"", pos2) - pos2); - DWORD timestamp = utils::conversion::to_timestamp( - utils::text::source_get_value(&messagesgroup, 2, "data-utime=\\\"", "\\\"")); + if (strclass.find("MessagingMessageUnread") == std::string::npos) + continue; // ignoring old messages - pos3 = 0; - while ((pos3 = messagesgroup.find("class=\\\"content noh", pos3)) != std::string::npos) - { + //std::string::size_type pos3 = messageslist.find("/li>", pos2); // TODO: ne proti tomuhle li, protože i přílohy mají li... + std::string::size_type pos3 = messageslist.find("class=\\\"MessagingMessage ", pos2); + std::string messagesgroup = messageslist.substr(pos2, pos3 - pos2); - std::string message_attachments = ""; - std::string::size_type pos4 = 0; - if ((pos4 = messagesgroup.find("class=\\\"attachments\\\"", pos4)) != std::string::npos) { - std::string attachments = messagesgroup.substr(pos4, messagesgroup.find("<\\/ul", pos4) - pos4); + DWORD timestamp = utils::conversion::to_timestamp( + utils::text::source_get_value(&messagesgroup, 2, "data-utime=\\\"", "\\\"")); - pos4 = 0; - while ((pos4 = attachments.find("", pos4) - pos4); - std::string link = utils::text::source_get_value(&attachment, 4, "", "<\\/a>"); - std::string name = utils::text::trim( - utils::text::special_expressions_decode( - utils::text::remove_html(attachment))); + pos4 = 0; + while ((pos4 = attachments.find("", pos4) - pos4); + std::string link = utils::text::source_get_value(&attachment, 4, " " + FACEBOOK_URL_HOMEPAGE; - message_attachments += link + "\r\n"; + // or first: std::string name = utils::text::source_get_value(&attachment, 4, "", "<\\/a>"); + std::string name = utils::text::trim( + utils::text::special_expressions_decode( + utils::text::remove_html(attachment))); - pos4++; + if (link.find("/ajax/messaging/attachments/photo/dialog.php?uri=") != std::string::npos) { + link = link.substr(49); + link = utils::url::decode(link); } + message_attachments += "< " + name + " > " + FACEBOOK_URL_HOMEPAGE; + message_attachments += link + "\r\n"; + + pos4++; } - std::string message_text = messagesgroup.substr(pos3, messagesgroup.find("<\\/div", pos3) + 6 - pos3); - LOG("Got unread message: \"%s\"", message_text.c_str()); - message_text = utils::text::source_get_value(&message_text, 2, "\\\">", "<\\/div"); - message_text = utils::text::trim( - utils::text::special_expressions_decode( - utils::text::remove_html(message_text))); + } - parseSmileys(message_text, hContact); + std::string message_text = messagesgroup.substr(pos3, messagesgroup.find("<\\/div", pos3) + 6 - pos3); + message_text = utils::text::source_get_value(&message_text, 2, "\\\">", "<\\/div"); + message_text = utils::text::trim( + utils::text::special_expressions_decode( + utils::text::remove_html(message_text))); - if (!message_attachments.empty()) { - if (!message_text.empty()) - message_text += "\r\n\r\n"; + LOG("Got unread message: \"%s\"", message_text.c_str()); - message_text += Translate("Attachments:"); - message_text += "\r\n" + message_attachments; - } + parseSmileys(message_text, hContact); - PROTORECVEVENT recv = {0}; - recv.flags = PREF_UTF; - recv.szMessage = const_cast(message_text.c_str()); - recv.timestamp = timestamp; - ProtoChainRecvMsg(hContact, &recv); + if (!message_attachments.empty()) { + if (!message_text.empty()) + message_text += "\r\n\r\n"; - pos3++; + message_text += Translate("Attachments:"); + message_text += "\r\n" + message_attachments; } + PROTORECVEVENT recv = {0}; + recv.flags = PREF_UTF; + recv.szMessage = const_cast(message_text.c_str()); + recv.timestamp = timestamp; + ProtoChainRecvMsg(hContact, &recv); + + pos3++; } - + } + delete tid; } void FacebookProto::ProcessMessages(void* data) -- cgit v1.2.3