diff options
-rw-r--r-- | protocols/Facebook/src/proto.h | 2 | ||||
-rw-r--r-- | protocols/Facebook/src/server.cpp | 134 | ||||
-rw-r--r-- | protocols/Facebook/src/version.h | 2 |
3 files changed, 81 insertions, 57 deletions
diff --git a/protocols/Facebook/src/proto.h b/protocols/Facebook/src/proto.h index e2dffa6513..e86117bfff 100644 --- a/protocols/Facebook/src/proto.h +++ b/protocols/Facebook/src/proto.h @@ -298,7 +298,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. * value is set too high, HTTP request will fail. This is due to the * request data being too large. */ -#define FB_API_CONTACTS_COUNT "500" +#define FB_API_CONTACTS_COUNT 500 #define FACEBOOK_MESSAGE_LIMIT 100000 diff --git a/protocols/Facebook/src/server.cpp b/protocols/Facebook/src/server.cpp index eee0b7bddf..2b80a4bcae 100644 --- a/protocols/Facebook/src/server.cpp +++ b/protocols/Facebook/src/server.cpp @@ -130,69 +130,93 @@ FacebookUser* FacebookProto::UserFromJson(const JSONNode &root, CMStringW &wszUs int FacebookProto::RefreshContacts() { - auto *pReq = CreateRequestGQL(FB_API_QUERY_CONTACTS); - pReq->flags |= NLHRF_NODUMPSEND; - pReq << CHAR_PARAM("query_params", "{\"0\":[\"user\"],\"1\":\"" FB_API_CONTACTS_COUNT "\"}"); - pReq->CalcSig(); + CMStringA szCursor; + bool bNeedUpdate = false; - JsonReply reply(ExecuteRequest(pReq)); - if (int iErrorCode = reply.error()) - return iErrorCode; // unknown error + while (true) { + JSONNode root; root << CHAR_PARAM("0", "user"); - bool bNeedUpdate = false; - bool bLoadAll = m_bLoadAll; - - for (auto &it : reply.data()["viewer"]["messenger_contacts"]["nodes"]) { - auto &n = it["represented_profile"]; - CMStringW wszId(n["id"].as_mstring()); - __int64 id = _wtoi64(wszId); - - MCONTACT hContact; - if (id != m_uid) { - bool bIsFriend = bLoadAll || n["friendship_status"].as_mstring() == L"ARE_FRIENDS"; - - auto *pUser = FindUser(id); - if (pUser == nullptr) { - if (!bIsFriend) - continue; - pUser = AddContact(wszId, false); - } - else if (!bIsFriend) - Contact_RemoveFromList(pUser->hContact); // adios! + AsyncHttpRequest *pReq; + pReq->flags |= NLHRF_NODUMPSEND; - hContact = pUser->hContact; + if (szCursor.IsEmpty()) { + pReq = CreateRequestGQL(FB_API_QUERY_CONTACTS); + root << INT_PARAM("1", FB_API_CONTACTS_COUNT); } - else hContact = 0; - - if (auto &nName = it["structured_name"]) { - CMStringW wszName(nName["text"].as_mstring()); - setWString(hContact, DBKEY_NICK, wszName); - for (auto &nn : nName["parts"]) { - CMStringW wszPart(nn["part"].as_mstring()); - int offset = nn["offset"].as_int(), length = nn["length"].as_int(); - if (wszPart == L"first") - setWString(hContact, "FirstName", wszName.Mid(offset, length)); - else if (wszPart == L"last") - setWString(hContact, "LastName", wszName.Mid(offset, length)); - } + else { + pReq = CreateRequestGQL(FB_API_QUERY_CONTACTS_AFTER); + root << CHAR_PARAM("1", szCursor) << INT_PARAM("2", FB_API_CONTACTS_COUNT); } + pReq << CHAR_PARAM("query_params", root.write().c_str()); + pReq->CalcSig(); - if (auto &nBirth = n["birthdate"]) { - setDword(hContact, "BirthDay", nBirth["day"].as_int()); - setDword(hContact, "BirthMonth", nBirth["month"].as_int()); - } + JsonReply reply(ExecuteRequest(pReq)); + if (int iErrorCode = reply.error()) + return iErrorCode; // unknown error + + bool bLoadAll = m_bLoadAll; + auto &data = reply.data()["viewer"]["messenger_contacts"]; + + for (auto &it : data["nodes"]) { + auto &n = it["represented_profile"]; + CMStringW wszId(n["id"].as_mstring()); + __int64 id = _wtoi64(wszId); + + MCONTACT hContact; + if (id != m_uid) { + bool bIsFriend = bLoadAll || n["friendship_status"].as_mstring() == L"ARE_FRIENDS"; + + auto *pUser = FindUser(id); + if (pUser == nullptr) { + if (!bIsFriend) + continue; + pUser = AddContact(wszId, false); + } + else if (!bIsFriend) + Contact_RemoveFromList(pUser->hContact); // adios! - if (auto &nCity = n["current_city"]) - setWString(hContact, "City", nCity["name"].as_mstring()); + hContact = pUser->hContact; + } + else hContact = 0; + + if (auto &nName = it["structured_name"]) { + CMStringW wszName(nName["text"].as_mstring()); + setWString(hContact, DBKEY_NICK, wszName); + for (auto &nn : nName["parts"]) { + CMStringW wszPart(nn["part"].as_mstring()); + int offset = nn["offset"].as_int(), length = nn["length"].as_int(); + if (wszPart == L"first") + setWString(hContact, "FirstName", wszName.Mid(offset, length)); + else if (wszPart == L"last") + setWString(hContact, "LastName", wszName.Mid(offset, length)); + } + } + + if (auto &nBirth = n["birthdate"]) { + setDword(hContact, "BirthDay", nBirth["day"].as_int()); + setDword(hContact, "BirthMonth", nBirth["month"].as_int()); + } + + if (auto &nCity = n["current_city"]) + setWString(hContact, "City", nCity["name"].as_mstring()); - if (auto &nAva = it[(m_bUseBigAvatars) ? "hugePictureUrl" : "bigPictureUrl"]) { - CMStringW wszOldUrl(getMStringW(hContact, DBKEY_AVATAR)), wszNewUrl(nAva["uri"].as_mstring()); - if (wszOldUrl != wszNewUrl) { - bNeedUpdate = true; - setByte(hContact, "UpdateNeeded", 1); - setWString(hContact, DBKEY_AVATAR, wszNewUrl); + if (auto &nAva = it[(m_bUseBigAvatars) ? "hugePictureUrl" : "bigPictureUrl"]) { + CMStringW wszOldUrl(getMStringW(hContact, DBKEY_AVATAR)), wszNewUrl(nAva["uri"].as_mstring()); + if (wszOldUrl != wszNewUrl) { + bNeedUpdate = true; + setByte(hContact, "UpdateNeeded", 1); + setWString(hContact, DBKEY_AVATAR, wszNewUrl); + } } } + + if (!data["page_info"]["has_next_page"].as_bool()) { + debugLogA("Got no next page, exiting", szCursor.c_str()); + break; + } + + szCursor = data["page_info"]["end_cursor"].as_mstring(); + debugLogA("Got cursor: %s", szCursor.c_str()); } if (bNeedUpdate) @@ -203,7 +227,8 @@ int FacebookProto::RefreshContacts() bool FacebookProto::RefreshSid() { auto *pReq = CreateRequestGQL(FB_API_QUERY_SEQ_ID); - pReq << CHAR_PARAM("query_params", "{\"1\":\"0\"}"); + JSONNode root; root << CHAR_PARAM("1", "0"); + pReq << CHAR_PARAM("query_params", root.write().c_str()); pReq->CalcSig(); JsonReply reply(ExecuteRequest(pReq)); @@ -286,7 +311,6 @@ FacebookUser* FacebookProto::RefreshThread(JSONNode &n) FacebookUser* FacebookProto::RefreshThread(CMStringW &wszId) { auto *pReq = CreateRequestGQL(FB_API_QUERY_THREAD); - pReq << WCHAR_PARAM("query_params", CMStringW(FORMAT, L"{\"0\":[\"%s\"], \"12\":0, \"13\":\"false\"}", wszId.c_str())); pReq->CalcSig(); diff --git a/protocols/Facebook/src/version.h b/protocols/Facebook/src/version.h index f2d3aca766..157e9ad9b6 100644 --- a/protocols/Facebook/src/version.h +++ b/protocols/Facebook/src/version.h @@ -1,7 +1,7 @@ #define __MAJOR_VERSION 0 #define __MINOR_VERSION 1 #define __RELEASE_NUM 0 -#define __BUILD_NUM 10 +#define __BUILD_NUM 11 #include <stdver.h> |