From e63ffcd3b3c8598d28ee899bd2537b02c02d8d39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20P=C3=B6sel?= Date: Sun, 18 May 2014 09:47:19 +0000 Subject: Facebook: Refactor various working threads and updating contacts procedure; Version bump This should eliminate creation of duplicite contacts, maybe made little slower or faster logging in... git-svn-id: http://svn.miranda-ng.org/main/trunk@9217 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/FacebookRM/src/client.h | 5 - protocols/FacebookRM/src/communication.cpp | 124 ---------------------- protocols/FacebookRM/src/connection.cpp | 27 ++--- protocols/FacebookRM/src/contacts.cpp | 55 +++++----- protocols/FacebookRM/src/process.cpp | 163 +++++++++++++++++++++-------- protocols/FacebookRM/src/proto.cpp | 4 +- protocols/FacebookRM/src/proto.h | 3 +- protocols/FacebookRM/src/version.h | 4 +- 8 files changed, 162 insertions(+), 223 deletions(-) (limited to 'protocols/FacebookRM/src') diff --git a/protocols/FacebookRM/src/client.h b/protocols/FacebookRM/src/client.h index 3e6993eb9a..b17cc8b202 100644 --- a/protocols/FacebookRM/src/client.h +++ b/protocols/FacebookRM/src/client.h @@ -148,11 +148,6 @@ public: HANDLE buddies_lock_; HANDLE send_message_lock_; - bool buddy_list(); - bool load_friends(); - bool load_pages(); - bool feeds(); - //////////////////////////////////////////////////////////// // Messages handling diff --git a/protocols/FacebookRM/src/communication.cpp b/protocols/FacebookRM/src/communication.cpp index 6eb267b1e0..4caf79d536 100644 --- a/protocols/FacebookRM/src/communication.cpp +++ b/protocols/FacebookRM/src/communication.cpp @@ -1009,130 +1009,6 @@ bool facebook_client::reconnect() } } -bool facebook_client::buddy_list() -{ - handle_entry("buddy_list"); - - // Prepare update data - std::string data = "user=" + this->self_.user_id + "&fetch_mobile=true&phstamp=0&fb_dtsg=" + this->dtsg_ + "&__user=" + this->self_.user_id; - - { - ScopedLock s(buddies_lock_); - - data += "&cached_user_info_ids="; - int counter = 0; - for (List::Item< facebook_user >* i = buddies.begin(); i != NULL; i = i->next, counter++) - { - data += i->data->user_id + "%2C"; - } - } - - // Get buddy list - http::response resp = flap(REQUEST_BUDDY_LIST, &data); - - switch (resp.code) { - case HTTP_CODE_OK: - parent->ForkThread(&FacebookProto::ProcessBuddyList, new std::string(resp.data)); - return handle_success("buddy_list"); - - case HTTP_CODE_FAKE_ERROR: - case HTTP_CODE_FAKE_DISCONNECTED: - default: - return handle_error("buddy_list"); - } -} - -bool facebook_client::load_friends() -{ - handle_entry("load_friends"); - - // Get buddy list - http::response resp = flap(REQUEST_LOAD_FRIENDS); - - switch (resp.code) { - case HTTP_CODE_OK: - parent->ForkThread(&FacebookProto::ProcessFriendList, new std::string(resp.data)); - return handle_success("load_friends"); - - case HTTP_CODE_FAKE_ERROR: - case HTTP_CODE_FAKE_DISCONNECTED: - default: - return handle_error("load_friends"); - } -} - -bool facebook_client::feeds() -{ - handle_entry("feeds"); - - // Get feeds - http::response resp = flap(REQUEST_FEEDS); - - switch (resp.code) { - case HTTP_CODE_OK: - if (resp.data.find("\"num_stories\":0") == std::string::npos) - parent->ForkThread(&FacebookProto::ProcessFeeds, new std::string(resp.data)); - - return handle_success("feeds"); - - case HTTP_CODE_FAKE_ERROR: - case HTTP_CODE_FAKE_DISCONNECTED: - default: - return handle_error("feeds"); - } -} - -bool facebook_client::load_pages() -{ - if (!parent->getByte(FACEBOOK_KEY_LOAD_PAGES, DEFAULT_LOAD_PAGES)) - return true; - - handle_entry("load_pages"); - - // Get feeds - http::response resp = flap(REQUEST_PAGES); - - switch (resp.code) { - case HTTP_CODE_OK: - { - std::string content = utils::text::source_get_value(&resp.data, 2, "id=\"bookmarksSeeAllSection\"", ""); - - std::string::size_type start, end; - start = content.find(""); - - start = content.find("debugLogA(" Got page: %s (%s)", title.c_str(), id.c_str()); - pages[id] = title; - } - - return handle_success("load_pages"); - } - case HTTP_CODE_FAKE_ERROR: - case HTTP_CODE_FAKE_DISCONNECTED: - default: - return handle_error("load_pages"); - } -} - bool facebook_client::channel() { handle_entry("channel"); diff --git a/protocols/FacebookRM/src/connection.cpp b/protocols/FacebookRM/src/connection.cpp index 4ff500a31b..48c290dfba 100644 --- a/protocols/FacebookRM/src/connection.cpp +++ b/protocols/FacebookRM/src/connection.cpp @@ -77,13 +77,12 @@ void FacebookProto::ChangeStatus(void*) ResetEvent(update_loop_lock_); - if (NegotiateConnection() && facy.home()) + if (NegotiateConnection() && facy.home() && facy.reconnect()) { - facy.reconnect(); - facy.load_friends(); - facy.load_pages(); + // Load all friends + ProcessFriendList(NULL); - // Process Friends requests + // Process friendship requests ForkThread(&FacebookProto::ProcessFriendRequests, NULL); // Get unread messages @@ -92,6 +91,9 @@ void FacebookProto::ChangeStatus(void*) // Get notifications ForkThread(&FacebookProto::ProcessNotifications, NULL); + // Load pages for post status dialog + ForkThread(&FacebookProto::ProcessPages, NULL); + setDword("LogonTS", (DWORD)time(NULL)); ForkThread(&FacebookProto::UpdateLoop, NULL); ForkThread(&FacebookProto::MessageLoop, NULL); @@ -122,7 +124,8 @@ void FacebookProto::ChangeStatus(void*) } facy.chat_state(m_iDesiredStatus != ID_STATUS_INVISIBLE); - facy.buddy_list(); + + ForkThread(&FacebookProto::ProcessBuddyList, NULL); m_iStatus = facy.self_.status_id = m_iDesiredStatus; ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, m_iStatus); @@ -175,16 +178,14 @@ void FacebookProto::UpdateLoop(void *) for (int i = -1; !isOffline(); i = ++i % 50) { - if (i != -1) { - if (!facy.buddy_list()) - break; - } + if (i != -1) + ProcessBuddyList(NULL); + if (i == 2 && getByte(FACEBOOK_KEY_EVENT_FEEDS_ENABLE, DEFAULT_EVENT_FEEDS_ENABLE)) - if (!facy.feeds()) - break; + ProcessFeeds(NULL); if (i == 49) - ForkThread(&FacebookProto::ProcessFriendRequests, NULL); + ProcessFriendRequests(NULL); debugLogA("***** FacebookProto::UpdateLoop[%d] going to sleep...", tim); if (WaitForSingleObjectEx(update_loop_lock_, GetPollRate() * 1000, true) != WAIT_TIMEOUT) diff --git a/protocols/FacebookRM/src/contacts.cpp b/protocols/FacebookRM/src/contacts.cpp index 5c82419ac1..2fb0d5fb70 100644 --- a/protocols/FacebookRM/src/contacts.cpp +++ b/protocols/FacebookRM/src/contacts.cpp @@ -171,50 +171,43 @@ void FacebookProto::LoadContactInfo(facebook_user* fbu) } } -MCONTACT FacebookProto::AddToContactList(facebook_user* fbu, ContactType type, bool force_save) +MCONTACT FacebookProto::AddToContactList(facebook_user* fbu, ContactType type, bool force_add) { - MCONTACT hContact; + // First, check if this contact exists (and if does, just return it) + if (!force_add) { + MCONTACT hContact = ContactIDToHContact(fbu->user_id); - // First, check if this contact exists - hContact = ContactIDToHContact(fbu->user_id); - - // If we have contact and don't need to force save data, just return it - if (hContact && !force_save) - return hContact; - - force_save = !hContact; + if (hContact) + return hContact; + } - // If not, try to make a new contact - if (!hContact) { - hContact = (MCONTACT)CallService(MS_DB_CONTACT_ADD, 0, 0); + // Try to make a new contact + MCONTACT hContact = (MCONTACT)CallService(MS_DB_CONTACT_ADD, 0, 0); - if (hContact && CallService(MS_PROTO_ADDTOCONTACT, hContact, (LPARAM)m_szModuleName) != 0) { - CallService(MS_DB_CONTACT_DELETE, hContact, 0); - hContact = NULL; - } + if (hContact && CallService(MS_PROTO_ADDTOCONTACT, hContact, (LPARAM)m_szModuleName) != 0) { + CallService(MS_DB_CONTACT_DELETE, hContact, 0); + hContact = NULL; } // If we have some contact, we'll save its data if (hContact) { - if (force_save) { - // Save these values only when adding new contact, not when updating existing - setString(hContact, FACEBOOK_KEY_ID, fbu->user_id.c_str()); + // Save these values only when adding new contact, not when updating existing + setString(hContact, FACEBOOK_KEY_ID, fbu->user_id.c_str()); - std::string homepage = FACEBOOK_URL_PROFILE + fbu->user_id; - setString(hContact, "Homepage", homepage.c_str()); - setTString(hContact, "MirVer", fbu->getMirVer()); + std::string homepage = FACEBOOK_URL_PROFILE + fbu->user_id; + setString(hContact, "Homepage", homepage.c_str()); + setTString(hContact, "MirVer", fbu->getMirVer()); - db_unset(hContact, "CList", "MyHandle"); + db_unset(hContact, "CList", "MyHandle"); - ptrT group(getTStringA(NULL, FACEBOOK_KEY_DEF_GROUP)); - if (group) - db_set_ts(hContact, "CList", "Group", group); + ptrT group(getTStringA(NULL, FACEBOOK_KEY_DEF_GROUP)); + if (group) + db_set_ts(hContact, "CList", "Group", group); - setByte(hContact, FACEBOOK_KEY_CONTACT_TYPE, type); + setByte(hContact, FACEBOOK_KEY_CONTACT_TYPE, type); - if (getByte(FACEBOOK_KEY_DISABLE_STATUS_NOTIFY, 0)) - CallService(MS_IGNORE_IGNORE, hContact, (LPARAM)IGNOREEVENT_USERONLINE); - } + if (getByte(FACEBOOK_KEY_DISABLE_STATUS_NOTIFY, 0)) + CallService(MS_IGNORE_IGNORE, hContact, (LPARAM)IGNOREEVENT_USERONLINE); if (!fbu->real_name.empty()) SaveName(hContact, fbu); diff --git a/protocols/FacebookRM/src/process.cpp b/protocols/FacebookRM/src/process.cpp index 8b4778f8b2..639fdee23d 100644 --- a/protocols/FacebookRM/src/process.cpp +++ b/protocols/FacebookRM/src/process.cpp @@ -22,24 +22,38 @@ along with this program. If not, see . #include "common.h" -void FacebookProto::ProcessBuddyList(void* data) +void FacebookProto::ProcessBuddyList(void*) { - if (data == NULL) + ScopedLock s(facy.buddies_lock_); + + if (isOffline()) return; - ScopedLock s(facy.buddies_lock_); + facy.handle_entry("ProcessBuddyList"); - std::string* resp = (std::string*)data; + // Prepare update data + std::string post_data = "user=" + facy.self_.user_id + "&fetch_mobile=true&phstamp=0&fb_dtsg=" + facy.dtsg_ + "&__user=" + facy.self_.user_id + "&cached_user_info_ids="; + + int counter = 0; + for (List::Item< facebook_user >* i = facy.buddies.begin(); i != NULL; i = i->next, counter++) + { + post_data += i->data->user_id + "%2C"; + } - if (isOffline()) - goto exit; + // Get buddy list + http::response resp = facy.flap(REQUEST_BUDDY_LIST, &post_data); + + if (resp.code != HTTP_CODE_OK) { + facy.handle_error("buddy_list"); + return; + } debugLogA("***** Starting processing buddy list"); CODE_BLOCK_TRY facebook_json_parser* p = new facebook_json_parser(this); - p->parse_buddy_list(data, &facy.buddies); + p->parse_buddy_list(&resp.data, &facy.buddies); delete p; for (List::Item< facebook_user >* i = facy.buddies.begin(); i != NULL;) @@ -130,17 +144,24 @@ void FacebookProto::ProcessBuddyList(void* data) debugLogA("***** Error processing buddy list: %s", e.what()); CODE_BLOCK_END - -exit: - delete resp; } -void FacebookProto::ProcessFriendList(void* data) +void FacebookProto::ProcessFriendList(void*) { - if (data == NULL) + ScopedLock s(facy.buddies_lock_); + + if (isOffline()) return; - std::string* resp = (std::string*)data; + facy.handle_entry("load_friends"); + + // Get buddy list + http::response resp = facy.flap(REQUEST_LOAD_FRIENDS); + + if (resp.code != HTTP_CODE_OK) { + facy.handle_error("load_friends"); + return; + } debugLogA("***** Starting processing friend list"); @@ -149,7 +170,7 @@ void FacebookProto::ProcessFriendList(void* data) std::map friends; facebook_json_parser* p = new facebook_json_parser(this); - p->parse_friends(data, &friends); + p->parse_friends(&resp.data, &friends); delete p; @@ -234,7 +255,7 @@ void FacebookProto::ProcessFriendList(void* data) // Check remaining contacts in map and add them to contact list for (std::map< std::string, facebook_user* >::iterator it = friends.begin(); it != friends.end(); ) { if (!it->second->deleted) - AddToContactList(it->second, CONTACT_FRIEND, true); // there could be race-condition between this thread and channel/buddy_list thread, so this contact might be created already + AddToContactList(it->second, CONTACT_FRIEND, true); // we know this contact doesn't exists, so we force add it delete it->second; it = friends.erase(it); @@ -248,8 +269,6 @@ void FacebookProto::ProcessFriendList(void* data) debugLogA("***** Error processing friend list: %s", e.what()); CODE_BLOCK_END - - delete resp; } void FacebookProto::ProcessUnreadMessages(void*) @@ -269,30 +288,30 @@ void FacebookProto::ProcessUnreadMessages(void*) http::response resp = facy.flap(REQUEST_UNREAD_THREADS, &data); - if (resp.code == HTTP_CODE_OK) { - - CODE_BLOCK_TRY + if (resp.code != HTTP_CODE_OK) { + facy.handle_error("ProcessUnreadMessages"); + return; + } + + CODE_BLOCK_TRY - std::vector threads; + std::vector threads; - facebook_json_parser* p = new facebook_json_parser(this); - p->parse_unread_threads(&resp.data, &threads, inboxOnly); - delete p; + facebook_json_parser* p = new facebook_json_parser(this); + p->parse_unread_threads(&resp.data, &threads, inboxOnly); + delete p; - ForkThread(&FacebookProto::ProcessUnreadMessage, new std::vector(threads)); + ForkThread(&FacebookProto::ProcessUnreadMessage, new std::vector(threads)); - debugLogA("***** Unread threads list processed"); + debugLogA("***** Unread threads list processed"); - CODE_BLOCK_CATCH + CODE_BLOCK_CATCH - debugLogA("***** Error processing unread threads list: %s", e.what()); + debugLogA("***** Error processing unread threads list: %s", e.what()); - CODE_BLOCK_END + CODE_BLOCK_END - facy.handle_success("ProcessUnreadMessages"); - } else { - facy.handle_error("ProcessUnreadMessages"); - } + facy.handle_success("ProcessUnreadMessages"); } void FacebookProto::ProcessUnreadMessage(void *p) @@ -717,13 +736,21 @@ void FacebookProto::ProcessFriendRequests(void*) void FacebookProto::ProcessFeeds(void* data) { - if (data == NULL) + if (!isOnline()) return; - std::string* resp = (std::string*)data; + facy.handle_entry("feeds"); - if (!isOnline()) - goto exit; + // Get feeds + http::response resp = facy.flap(REQUEST_FEEDS); + + if (resp.code != HTTP_CODE_OK) { + facy.handle_error("feeds"); + return; + } + + if (resp.data.empty() || resp.data.find("\"num_stories\":0") != std::string::npos) + return; CODE_BLOCK_TRY @@ -734,16 +761,16 @@ void FacebookProto::ProcessFeeds(void* data) std::string::size_type pos = 0; UINT limit = 0; - *resp = utils::text::slashu_to_utf8(*resp); - *resp = utils::text::source_get_value(resp, 2, "\"html\":\"", ">\""); + resp.data = utils::text::slashu_to_utf8(resp.data); + resp.data = utils::text::source_get_value(&resp.data, 2, "\"html\":\"", ">\""); - while ((pos = resp->find("
find("
length(); + pos2 = resp.data.length(); - std::string post = resp->substr(pos, pos2 - pos); + std::string post = resp.data.substr(pos, pos2 - pos); pos += 5; std::string post_header = utils::text::source_get_value(&post, 4, "
", "<\\/h5>"); @@ -817,8 +844,54 @@ void FacebookProto::ProcessFeeds(void* data) CODE_BLOCK_END -exit: - delete resp; + facy.handle_success("feeds"); +} + +void FacebookProto::ProcessPages(void *data) +{ + if (!getByte(FACEBOOK_KEY_LOAD_PAGES, DEFAULT_LOAD_PAGES)) + return; + + facy.handle_entry("load_pages"); + + // Get feeds + http::response resp = facy.flap(REQUEST_PAGES); + + if (resp.code != HTTP_CODE_OK) { + facy.handle_error("load_pages"); + return; + } + + std::string content = utils::text::source_get_value(&resp.data, 2, "id=\"bookmarksSeeAllSection\"", ""); + + std::string::size_type start, end; + start = content.find(""); + + start = content.find(" -- cgit v1.2.3