summaryrefslogtreecommitdiff
path: root/protocols/FacebookRM
diff options
context:
space:
mode:
authorRobert Pösel <robyer@seznam.cz>2017-02-26 01:30:13 +0100
committerRobert Pösel <robyer@seznam.cz>2017-02-26 01:30:13 +0100
commit7b550e3c80a63cf7a063a28fc7b0ce020a47c51b (patch)
tree34fe26715f12e54bf1b1e54a633c42d356a5bd37 /protocols/FacebookRM
parent33c7f1e7bc3517df2ea45bc68a164b6380167072 (diff)
Facebook: Don't block main thread when refreshing user info
Diffstat (limited to 'protocols/FacebookRM')
-rw-r--r--protocols/FacebookRM/src/contacts.cpp85
-rw-r--r--protocols/FacebookRM/src/proto.cpp78
-rw-r--r--protocols/FacebookRM/src/proto.h1
3 files changed, 88 insertions, 76 deletions
diff --git a/protocols/FacebookRM/src/contacts.cpp b/protocols/FacebookRM/src/contacts.cpp
index c072808eb4..cec21e5904 100644
--- a/protocols/FacebookRM/src/contacts.cpp
+++ b/protocols/FacebookRM/src/contacts.cpp
@@ -672,6 +672,91 @@ void FacebookProto::SendPokeWorker(void *p)
delete id;
}
+void FacebookProto::RefreshUserInfo(void *data)
+{
+ if (data == NULL)
+ return;
+
+ MCONTACT hContact = *(MCONTACT*)data;
+ delete (MCONTACT*)data;
+
+ ptrA user_id(getStringA(hContact, FACEBOOK_KEY_ID));
+ if (user_id == NULL || isOffline()) {
+ ProtoBroadcastAck(hContact, ACKTYPE_GETINFO, ACKRESULT_FAILED, (HANDLE)0, 0);
+ return;
+ }
+
+ facebook_user fbu;
+ fbu.user_id = user_id;
+
+ LoadContactInfo(&fbu);
+
+ // TODO: don't duplicate code this way, refactor all this userInfo loading
+ // TODO: load more info about user (authorization state,...)
+
+ std::string homepage = FACEBOOK_URL_PROFILE + fbu.user_id;
+ setString(hContact, "Homepage", homepage.c_str());
+
+ if (!fbu.real_name.empty()) {
+ SaveName(hContact, &fbu);
+ }
+
+ if (fbu.gender) {
+ setByte(hContact, "Gender", fbu.gender);
+ }
+
+ int oldType = getByte(hContact, FACEBOOK_KEY_CONTACT_TYPE, CONTACT_NONE);
+ // From server we won't get request/approve types, only none, so we don't want to overwrite and lost it in that case
+ if (fbu.type != CONTACT_NONE || (oldType != CONTACT_REQUEST && oldType != CONTACT_APPROVE)) {
+ if (oldType != fbu.type) {
+ setByte(hContact, FACEBOOK_KEY_CONTACT_TYPE, fbu.type);
+ }
+ }
+
+ // If this contact is page, set it as invisible (if enabled in options)
+ if (getBool(FACEBOOK_KEY_PAGES_ALWAYS_ONLINE, DEFAULT_PAGES_ALWAYS_ONLINE) && fbu.type == CONTACT_PAGE) {
+ setWord(hContact, "Status", ID_STATUS_INVISIBLE);
+ }
+
+ CheckAvatarChange(hContact, fbu.image_url);
+
+ // Load additional info from profile page (e.g., birthday)
+ http::response resp = facy.sendRequest(new ProfileInfoRequest(facy.mbasicWorks, fbu.user_id.c_str()));
+
+ if (resp.code == HTTP_CODE_OK) {
+ std::string birthday = utils::text::source_get_value(&resp.data, 4, ">Birthday</", "<td", ">", "</td>");
+ birthday = utils::text::remove_html(birthday);
+
+ std::string::size_type pos = birthday.find(" ");
+ std::string::size_type pos2 = birthday.find(",");
+ if (pos != std::string::npos) {
+ std::string month = birthday.substr(0, pos);
+ std::string day = birthday.substr(pos + 1, pos2 != std::string::npos ? pos2 - pos - 1 : std::string::npos);
+
+ setByte(hContact, "BirthDay", atoi(day.c_str()));
+
+ const static char *months[] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" };
+ for (int i = 0; i < 12; i++) {
+ if (!mir_strcmp(months[i], month.c_str())) {
+ setByte(hContact, "BirthMonth", i + 1);
+ break;
+ }
+ }
+
+ if (pos2 != std::string::npos) {
+ std::string year = birthday.substr(pos2 + 2, 4);
+ setWord(hContact, "BirthYear", atoi(year.c_str()));
+ }
+ else {
+ // We have to set ANY year, otherwise UserInfoEx shows completely wrong date
+ setWord(hContact, "BirthYear", 1800);
+ }
+ }
+ }
+
+ ProtoBroadcastAck(hContact, ACKTYPE_GETINFO, ACKRESULT_SUCCESS, (HANDLE)0, 0);
+}
+
HANDLE FacebookProto::GetAwayMsg(MCONTACT)
{
diff --git a/protocols/FacebookRM/src/proto.cpp b/protocols/FacebookRM/src/proto.cpp
index d92f8c8e5f..62adf63216 100644
--- a/protocols/FacebookRM/src/proto.cpp
+++ b/protocols/FacebookRM/src/proto.cpp
@@ -344,82 +344,8 @@ int FacebookProto::AuthDeny(MEVENT hDbEvent, const wchar_t *)
int FacebookProto::GetInfo(MCONTACT hContact, int)
{
- ptrA user_id(getStringA(hContact, FACEBOOK_KEY_ID));
- if (user_id == NULL)
- return 1;
-
- facebook_user fbu;
- fbu.user_id = user_id;
-
- LoadContactInfo(&fbu);
-
- // TODO: don't duplicate code this way, refactor all this userInfo loading
- // TODO: load more info about user (authorization state,...)
-
- std::string homepage = FACEBOOK_URL_PROFILE + fbu.user_id;
- setString(hContact, "Homepage", homepage.c_str());
-
- if (!fbu.real_name.empty()) {
- SaveName(hContact, &fbu);
- }
-
- if (fbu.gender) {
- setByte(hContact, "Gender", fbu.gender);
- }
-
- int oldType = getByte(hContact, FACEBOOK_KEY_CONTACT_TYPE, CONTACT_NONE);
- // From server we won't get request/approve types, only none, so we don't want to overwrite and lost it in that case
- if (fbu.type != CONTACT_NONE || (oldType != CONTACT_REQUEST && oldType != CONTACT_APPROVE)) {
- if (oldType != fbu.type) {
- setByte(hContact, FACEBOOK_KEY_CONTACT_TYPE, fbu.type);
- }
- }
-
- // If this contact is page, set it as invisible (if enabled in options)
- if (getBool(FACEBOOK_KEY_PAGES_ALWAYS_ONLINE, DEFAULT_PAGES_ALWAYS_ONLINE) && fbu.type == CONTACT_PAGE) {
- setWord(hContact, "Status", ID_STATUS_INVISIBLE);
- }
-
- CheckAvatarChange(hContact, fbu.image_url);
-
- // Load additional info from profile page (e.g., birthday)
- if (isOffline())
- return 1;
-
- http::response resp = facy.sendRequest(new ProfileInfoRequest(facy.mbasicWorks, fbu.user_id.c_str()));
-
- if (resp.code == HTTP_CODE_OK) {
- std::string birthday = utils::text::source_get_value(&resp.data, 4, ">Birthday</", "<td", ">", "</td>");
- birthday = utils::text::remove_html(birthday);
-
- std::string::size_type pos = birthday.find(" ");
- std::string::size_type pos2 = birthday.find(",");
- if (pos != std::string::npos) {
- std::string month = birthday.substr(0, pos);
- std::string day = birthday.substr(pos + 1, pos2 != std::string::npos ? pos2 - pos - 1 : std::string::npos);
-
- setByte(hContact, "BirthDay", atoi(day.c_str()));
-
- const static char *months[] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" };
- for (int i = 0; i < 12; i++) {
- if (!mir_strcmp(months[i], month.c_str())) {
- setByte(hContact, "BirthMonth", i + 1);
- break;
- }
- }
-
- if (pos2 != std::string::npos) {
- std::string year = birthday.substr(pos2 + 2, 4);
- setWord(hContact, "BirthYear", atoi(year.c_str()));
- }
- else {
- // We have to set ANY year, otherwise UserInfoEx shows completely wrong date
- setWord(hContact, "BirthYear", 1800);
- }
- }
- }
-
- return 1;
+ ForkThread(&FacebookProto::RefreshUserInfo, (void*)new MCONTACT(hContact));
+ return 0;
}
//////////////////////////////////////////////////////////////////////////////
diff --git a/protocols/FacebookRM/src/proto.h b/protocols/FacebookRM/src/proto.h
index bcceed5864..2d46f0f7d6 100644
--- a/protocols/FacebookRM/src/proto.h
+++ b/protocols/FacebookRM/src/proto.h
@@ -195,6 +195,7 @@ public:
void __cdecl CancelFriendsRequest(void*);
void __cdecl SendPokeWorker(void*);
void __cdecl IgnoreFriendshipRequest(void*);
+ void __cdecl RefreshUserInfo(void*);
// Contacts handling
bool IsMyContact(MCONTACT, bool include_chat = false);