summaryrefslogtreecommitdiff
path: root/protocols/WhatsAppWeb/src/avatars.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'protocols/WhatsAppWeb/src/avatars.cpp')
-rw-r--r--protocols/WhatsAppWeb/src/avatars.cpp83
1 files changed, 80 insertions, 3 deletions
diff --git a/protocols/WhatsAppWeb/src/avatars.cpp b/protocols/WhatsAppWeb/src/avatars.cpp
index fb51e03c79..fe84739d2e 100644
--- a/protocols/WhatsAppWeb/src/avatars.cpp
+++ b/protocols/WhatsAppWeb/src/avatars.cpp
@@ -7,6 +7,39 @@ Copyright © 2019-21 George Hazan
#include "stdafx.h"
+void WhatsAppProto::OnGetAvatarInfo(const JSONNode &root, void *pUserInfo)
+{
+ if (!root) return;
+
+ MCONTACT hContact = (UINT_PTR)pUserInfo;
+
+ PROTO_AVATAR_INFORMATION ai = {};
+ ai.hContact = hContact;
+ ai.format = PA_FORMAT_JPEG;
+ wcsncpy_s(ai.filename, GetAvatarFileName(hContact), _TRUNCATE);
+
+ DWORD dwLastChangeTime = _wtoi(root["tag"].as_mstring());
+
+ CMStringA szUrl(root["eurl"].as_mstring());
+ if (szUrl.IsEmpty()) {
+ setDword(hContact, DBKEY_AVATAR_TAG, 0); // avatar doesn't exist, don't check it later
+
+LBL_Error:
+ ProtoBroadcastAck(hContact, ACKTYPE_AVATAR, ACKRESULT_FAILED, HANDLE(&ai));
+ return;
+ }
+
+ // if avatar was changed or not present at all, download it
+ if (dwLastChangeTime > getDword(hContact, DBKEY_AVATAR_TAG)) {
+ if (!g_plugin.SaveFile(szUrl, ai))
+ goto LBL_Error;
+
+ // set timestamp of avatar being saved
+ setDword(hContact, DBKEY_AVATAR_TAG, dwLastChangeTime);
+ }
+ ProtoBroadcastAck(hContact, ACKTYPE_AVATAR, ACKRESULT_SUCCESS, HANDLE(&ai));
+}
+
INT_PTR WhatsAppProto::GetAvatarInfo(WPARAM wParam, LPARAM lParam)
{
PROTO_AVATAR_INFORMATION *pai = (PROTO_AVATAR_INFORMATION*)lParam;
@@ -19,10 +52,10 @@ INT_PTR WhatsAppProto::GetAvatarInfo(WPARAM wParam, LPARAM lParam)
wcsncpy_s(pai->filename, tszFileName.c_str(), _TRUNCATE);
pai->format = PA_FORMAT_JPEG;
- ptrA szAvatarId(getStringA(pai->hContact, DBKEY_AVATAR_ID));
- if (szAvatarId == NULL || (wParam & GAIF_FORCE) != 0)
+ DWORD dwTag = getDword(pai->hContact, DBKEY_AVATAR_TAG, -1);
+ if (dwTag == -1 || (wParam & GAIF_FORCE) != 0)
if (pai->hContact != NULL && isOnline()) {
- // m_pConnection->sendGetPicture(id, "image");
+ WSSend(CMStringA(FORMAT, "[\"query\",\"ProfilePicThumb\",\"%s\"]", id.get()), &WhatsAppProto::OnGetAvatarInfo, (void*)pai->hContact);
return GAIR_WAITFOR;
}
@@ -30,6 +63,8 @@ INT_PTR WhatsAppProto::GetAvatarInfo(WPARAM wParam, LPARAM lParam)
return GAIR_NOAVATAR;
}
+/////////////////////////////////////////////////////////////////////////////////////////
+
INT_PTR WhatsAppProto::GetAvatarCaps(WPARAM wParam, LPARAM lParam)
{
switch (wParam) {
@@ -79,3 +114,45 @@ INT_PTR WhatsAppProto::SetMyAvatar(WPARAM, LPARAM)
{
return 0;
}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+bool CMPlugin::SaveFile(const char *pszUrl, PROTO_AVATAR_INFORMATION &ai)
+{
+ NETLIBHTTPREQUEST req = {};
+ req.cbSize = sizeof(req);
+ req.flags = NLHRF_NODUMP | NLHRF_PERSISTENT | NLHRF_SSL | NLHRF_HTTP11 | NLHRF_REDIRECT;
+ req.requestType = REQUEST_GET;
+ req.szUrl = (char*)pszUrl;
+ req.nlc = hAvatarConn;
+
+ NETLIBHTTPREQUEST *pReply = Netlib_HttpTransaction(hAvatarUser, &req);
+ if (pReply == nullptr) {
+ hAvatarConn = nullptr;
+ debugLogA("Failed to retrieve avatar from url: %s", pszUrl);
+ return false;
+ }
+
+ hAvatarConn = pReply->nlc;
+
+ bool bSuccess = false;
+ if (pReply->resultCode == 200 && pReply->pData && pReply->dataLength) {
+ if (auto *pszHdr = Netlib_GetHeader(pReply, "Content-Type"))
+ ai.format = ProtoGetAvatarFormatByMimeType(pszHdr);
+
+ if (ai.format != PA_FORMAT_UNKNOWN) {
+ FILE *fout = _wfopen(ai.filename, L"wb");
+ if (fout) {
+ fwrite(pReply->pData, 1, pReply->dataLength, fout);
+ fclose(fout);
+ bSuccess = true;
+ }
+ else debugLogA("Error saving avatar to file %S", ai.filename);
+ }
+ else debugLogA("unknown avatar mime type");
+ }
+ else debugLogA("Error %d reading avatar from url: %s", pReply->resultCode, pszUrl);
+
+ Netlib_FreeHttpRequest(pReply);
+ return bSuccess;
+}