diff options
author | George Hazan <ghazan@miranda.im> | 2020-01-02 22:30:54 +0300 |
---|---|---|
committer | George Hazan <ghazan@miranda.im> | 2020-01-02 22:30:54 +0300 |
commit | 26d7cc8c81533ca32ec795f1035b01a23c71a06d (patch) | |
tree | 8695c3a8143cbb2fe0e0a63ccb03250c7419f0f5 /protocols/Facebook | |
parent | 7f88379698aa8a608c9a2b3f23c4e21c207f5735 (diff) |
Facebook: stickers support
Diffstat (limited to 'protocols/Facebook')
-rw-r--r-- | protocols/Facebook/src/avatars.cpp | 195 | ||||
-rw-r--r-- | protocols/Facebook/src/server.cpp | 64 |
2 files changed, 64 insertions, 195 deletions
diff --git a/protocols/Facebook/src/avatars.cpp b/protocols/Facebook/src/avatars.cpp index 284332f32e..1823c8da4d 100644 --- a/protocols/Facebook/src/avatars.cpp +++ b/protocols/Facebook/src/avatars.cpp @@ -134,198 +134,3 @@ INT_PTR FacebookProto::GetAvatarCaps(WPARAM wParam, LPARAM lParam) return res; } - - -/* -bool FacebookProto::GetDbAvatarInfo(PROTO_AVATAR_INFORMATION &pai, std::string *url) -{ - ptrA id(getStringA(pai.hContact, FACEBOOK_KEY_ID)); - if (id == nullptr) - return false; - - if (url) { - *url = FACEBOOK_URL_PICTURE; - utils::text::replace_first(url, "%s", std::string(id)); - } - - std::wstring filename = GetAvatarFolder() + L'\\' + std::wstring(_A2T(id)) + L".jpg"; - - wcsncpy_s(pai.filename, filename.c_str(), _TRUNCATE); - pai.format = ProtoGetAvatarFormat(pai.filename); - return true; -} - -void FacebookProto::CheckAvatarChange(MCONTACT hContact, const std::string &image_url) -{ - std::wstring::size_type pos = image_url.rfind("/"); - - // Facebook contacts always have some avatar - keep avatar in database even if we have loaded empty one (e.g. for 'On Mobile' contacts) - if (image_url.empty() || pos == std::wstring::npos) - return; - - // Get name of image - std::string image_name = image_url.substr(pos + 1); - - // Remove eventual parameters from name - pos = image_name.rfind("?"); - if (pos != std::wstring::npos) - image_name = image_name.substr(0, pos); - - // Append our parameters to allow comparing for avatar/settings change - if (getBool(FACEBOOK_KEY_BIG_AVATARS, DEFAULT_BIG_AVATARS)) - image_name += "?big"; - - // Check for avatar change - ptrA old_name(getStringA(hContact, FACEBOOK_KEY_AVATAR)); - bool update_required = (old_name == nullptr || image_name.compare(old_name) != 0); - - // TODO: Remove this in some newer version - if (old_name == nullptr) { - // Remove AvatarURL value, which was used in previous versions of plugin - delSetting(hContact, "AvatarURL"); - } - - if (update_required) - setString(hContact, FACEBOOK_KEY_AVATAR, image_name.c_str()); - - if (!hContact) { - PROTO_AVATAR_INFORMATION ai = { 0 }; - if (GetAvatarInfo(update_required ? GAIF_FORCE : 0, (LPARAM)&ai) != GAIR_WAITFOR) - ReportSelfAvatarChanged(); - } - else if (update_required) { - db_set_b(hContact, "ContactPhoto", "NeedUpdate", 1); - ProtoBroadcastAck(hContact, ACKTYPE_AVATAR, ACKRESULT_STATUS, nullptr); - } -} - -void FacebookProto::UpdateAvatarWorker(void *) -{ - HNETLIBCONN nlc = nullptr; - - debugLogA("*** UpdateAvatarWorker"); - - std::string params = getBool(FACEBOOK_KEY_BIG_AVATARS, DEFAULT_BIG_AVATARS) ? "?width=200&height=200" : "?width=80&height=80"; - - for (;;) { - std::string url; - PROTO_AVATAR_INFORMATION ai = { 0 }; - ai.hContact = avatar_queue[0]; - - if (Miranda_IsTerminated()) { - debugLogA("*** Terminating avatar update early: %s", url.c_str()); - break; - } - - if (GetDbAvatarInfo(ai, &url)) { - debugLogA("*** Updating avatar: %s", url.c_str()); - bool success = facy.save_url(url + params, ai.filename, nlc); - - if (ai.hContact) - ProtoBroadcastAck(ai.hContact, ACKTYPE_AVATAR, success ? ACKRESULT_SUCCESS : ACKRESULT_FAILED, (HANDLE)&ai); - else if (success) - ReportSelfAvatarChanged(); - } - - mir_cslock s(avatar_lock_); - avatar_queue.erase(avatar_queue.begin()); - if (avatar_queue.empty()) - break; - } - Netlib_CloseHandle(nlc); -} - -std::wstring FacebookProto::GetAvatarFolder() -{ - wchar_t path[MAX_PATH]; - mir_snwprintf(path, L"%s\\%s", VARSW(L"%miranda_avatarcache%"), m_tszUserName); - return path; -} - -INT_PTR FacebookProto::GetAvatarCaps(WPARAM wParam, LPARAM lParam) -{ - int res = 0; - - switch (wParam) { - case AF_MAXSIZE: - ((POINT*)lParam)->x = -1; - ((POINT*)lParam)->y = -1; - break; - - case AF_FORMATSUPPORTED: - res = (lParam == PA_FORMAT_JPEG || lParam == PA_FORMAT_GIF); - break; - - case AF_DELAYAFTERFAIL: - res = 10 * 60 * 1000; - break; - - case AF_ENABLED: - case AF_FETCHIFPROTONOTVISIBLE: - case AF_FETCHIFCONTACTOFFLINE: - res = 1; - break; - } - - return res; -} - -INT_PTR FacebookProto::GetAvatarInfo(WPARAM wParam, LPARAM lParam) -{ - if (!lParam) - return GAIR_NOAVATAR; - - PROTO_AVATAR_INFORMATION* pai = (PROTO_AVATAR_INFORMATION*)lParam; - if (GetDbAvatarInfo(*pai, nullptr)) { - bool fileExist = _waccess(pai->filename, 0) == 0; - - bool needLoad; - if (pai->hContact) - needLoad = (wParam & GAIF_FORCE) && (!fileExist || db_get_b(pai->hContact, "ContactPhoto", "NeedUpdate", 0)); - else - needLoad = (wParam & GAIF_FORCE) || !fileExist; - - if (needLoad) { - debugLogA("*** Starting avatar request thread for %s", _T2A(pai->filename)); - mir_cslock s(avatar_lock_); - - if (std::find(avatar_queue.begin(), avatar_queue.end(), pai->hContact) == avatar_queue.end()) { - bool is_empty = avatar_queue.empty(); - avatar_queue.push_back(pai->hContact); - if (is_empty) - ForkThread(&FacebookProto::UpdateAvatarWorker, nullptr); - } - return GAIR_WAITFOR; - } - else if (fileExist) - return GAIR_SUCCESS; - - } - return GAIR_NOAVATAR; -} - -INT_PTR FacebookProto::GetMyAvatar(WPARAM wParam, LPARAM lParam) -{ - debugLogA("*** GetMyAvatar"); - - if (!wParam || !lParam) - return -3; - - wchar_t* buf = (wchar_t*)wParam; - int size = (int)lParam; - - PROTO_AVATAR_INFORMATION ai = { 0 }; - switch (GetAvatarInfo(0, (LPARAM)&ai)) { - case GAIR_SUCCESS: - wcsncpy(buf, ai.filename, size); - buf[size - 1] = 0; - return 0; - - case GAIR_WAITFOR: - return -1; - - default: - return -2; - } -} -*/
\ No newline at end of file diff --git a/protocols/Facebook/src/server.cpp b/protocols/Facebook/src/server.cpp index 257f4974d5..004633fc12 100644 --- a/protocols/Facebook/src/server.cpp +++ b/protocols/Facebook/src/server.cpp @@ -461,6 +461,70 @@ void FacebookProto::OnPublishPrivateMessage(const JSONNode &root) std::string szBody(root["body"].as_string()); std::string szId(metadata["messageId"].as_string()); + CMStringA stickerId = root["stickerId"].as_mstring(); + if (!stickerId.IsEmpty()) { + if (ServiceExists(MS_SMILEYADD_LOADCONTACTSMILEYS)) { + CMStringW wszPath(FORMAT, L"%s\\%S\\Stickers", VARSW(L"%miranda_avatarcache%").get(), m_szModuleName); + CreateDirectoryTreeW(wszPath); + + bool bSuccess = false; + CMStringW wszFileName(FORMAT, L"%s\\%S.png", wszPath.c_str(), stickerId.c_str()); + if (GetFileAttributesW(wszFileName) == INVALID_FILE_ATTRIBUTES) { + auto *pReq = CreateRequestGQL(FB_API_QUERY_STICKER); + pReq << CHAR_PARAM("query_params", CMStringA(FORMAT, "{\"0\":[\"%s\"]}", stickerId.c_str())); + pReq->CalcSig(); + + JsonReply reply(ExecuteRequest(pReq)); + if (!reply.error()) { + for (auto &sticker : reply.data()) { + for (auto &img : sticker["thread_image"]) { + CMStringA szUrl(img.as_mstring()); + + NETLIBHTTPREQUEST req = {}; + req.cbSize = sizeof(req); + req.flags = NLHRF_NODUMP | NLHRF_SSL | NLHRF_HTTP11 | NLHRF_REDIRECT; + req.requestType = REQUEST_GET; + req.szUrl = szUrl.GetBuffer(); + + NETLIBHTTPREQUEST *pReply = Netlib_HttpTransaction(m_hNetlibUser, &req); + if (pReply != nullptr && pReply->resultCode == 200 && pReply->pData && pReply->dataLength) { + int iImageFormat = PA_FORMAT_UNKNOWN; + for (int i = 0; i < pReply->headersCount; i++) + if (!mir_strcmp(pReply->headers[i].szName, "Content-Type")) { + iImageFormat = ProtoGetAvatarFormatByMimeType(pReply->headers[i].szValue); + break; + } + + if (iImageFormat != PA_FORMAT_UNKNOWN) { + bSuccess = true; + FILE *out = _wfopen(wszFileName, L"wb"); + fwrite(pReply->pData, 1, pReply->dataLength, out); + fclose(out); + } + } + } + } + } + } + else bSuccess = true; + + if (bSuccess) { + if (!szBody.empty()) + szBody += "\r\n"; + szBody += stickerId.c_str(); + + SMADD_CONT cont; + cont.cbSize = sizeof(SMADD_CONT); + cont.hContact = pUser->hContact; + cont.type = 1; + cont.path = wszFileName.GetBuffer(); + CallService(MS_SMILEYADD_LOADCONTACTSMILEYS, 0, (LPARAM)&cont); + } + else szBody += TranslateU("Sticker received"); + } + else szBody += TranslateU("SmileyAdd plugin required to support stickers"); + } + PROTORECVEVENT pre = {}; pre.timestamp = DWORD(_wtoi64(metadata["timestamp"].as_mstring()) / 1000); pre.szMessage = (char *)szBody.c_str(); |