summaryrefslogtreecommitdiff
path: root/protocols/WhatsApp/src/avatars.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'protocols/WhatsApp/src/avatars.cpp')
-rw-r--r--protocols/WhatsApp/src/avatars.cpp338
1 files changed, 169 insertions, 169 deletions
diff --git a/protocols/WhatsApp/src/avatars.cpp b/protocols/WhatsApp/src/avatars.cpp
index d2eda4014a..d648bb3801 100644
--- a/protocols/WhatsApp/src/avatars.cpp
+++ b/protocols/WhatsApp/src/avatars.cpp
@@ -1,169 +1,169 @@
-/*
-
-WhatsApp plugin for Miranda NG
-Copyright © 2019-22 George Hazan
-
-*/
-
-#include "stdafx.h"
-
-void WhatsAppProto::OnIqGetAvatar(const WANode &node)
-{
- auto *pUser = FindUser(node.getAttr("from"));
- if (pUser == nullptr)
- return;
-
- PROTO_AVATAR_INFORMATION ai = {};
- ai.hContact = pUser->hContact;
- ai.format = PA_FORMAT_JPEG;
- wcsncpy_s(ai.filename, GetAvatarFileName(pUser->hContact), _TRUNCATE);
-
- auto *pNode = node.getChild("picture");
-
- DWORD dwLastChangeTime = pNode->getAttrInt("id");
-
- CMStringA szUrl(pNode->getAttr("url"));
- if (szUrl.IsEmpty()) {
- setDword(pUser->hContact, DBKEY_AVATAR_TAG, 0); // avatar doesn't exist, don't check it later
-
-LBL_Error:
- ProtoBroadcastAck(pUser->hContact, ACKTYPE_AVATAR, ACKRESULT_FAILED, HANDLE(&ai));
- return;
- }
-
- // if avatar was changed or not present at all, download it
- if (dwLastChangeTime > getDword(pUser->hContact, DBKEY_AVATAR_TAG)) {
- if (!g_plugin.SaveFile(szUrl, ai))
- goto LBL_Error;
-
- // set timestamp of avatar being saved
- setDword(pUser->hContact, DBKEY_AVATAR_TAG, dwLastChangeTime);
- }
- ProtoBroadcastAck(pUser->hContact, ACKTYPE_AVATAR, ACKRESULT_SUCCESS, HANDLE(&ai));
-}
-
-INT_PTR WhatsAppProto::GetAvatarInfo(WPARAM wParam, LPARAM lParam)
-{
- PROTO_AVATAR_INFORMATION *pai = (PROTO_AVATAR_INFORMATION*)lParam;
-
- ptrA jid(getStringA(pai->hContact, isChatRoom(pai->hContact) ? "ChatRoomID" : DBKEY_ID));
- if (jid == NULL)
- return GAIR_NOAVATAR;
-
- CMStringW tszFileName(GetAvatarFileName(pai->hContact));
- wcsncpy_s(pai->filename, tszFileName.c_str(), _TRUNCATE);
- pai->format = PA_FORMAT_JPEG;
-
- DWORD dwTag = getDword(pai->hContact, DBKEY_AVATAR_TAG, -1);
- if (dwTag == -1 || (wParam & GAIF_FORCE) != 0)
- if (pai->hContact != NULL && isOnline()) {
- ServerFetchAvatar(jid);
- return GAIR_WAITFOR;
- }
-
- debugLogA("No avatar");
- return GAIR_NOAVATAR;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-INT_PTR WhatsAppProto::GetAvatarCaps(WPARAM wParam, LPARAM lParam)
-{
- switch (wParam) {
- case AF_PROPORTION:
- return PIP_SQUARE;
-
- case AF_FORMATSUPPORTED: // Jabber supports avatars of virtually all formats
- return PA_FORMAT_JPEG;
-
- case AF_ENABLED:
- return TRUE;
-
- case AF_MAXSIZE:
- POINT *size = (POINT*)lParam;
- if (size)
- size->x = size->y = 640;
- return 0;
- }
- return -1;
-}
-
-CMStringW WhatsAppProto::GetAvatarFileName(MCONTACT hContact)
-{
- CMStringW result = m_tszAvatarFolder + L"\\";
-
- CMStringA jid;
- if (hContact != NULL) {
- ptrA szId(getStringA(hContact, isChatRoom(hContact) ? "ChatRoomID" : DBKEY_ID));
- if (szId == NULL)
- return L"";
-
- jid = szId;
- }
- else jid = m_szJid;
-
- return result + _A2T(jid.c_str()) + L".jpg";
-}
-
-INT_PTR WhatsAppProto::GetMyAvatar(WPARAM wParam, LPARAM lParam)
-{
- std::wstring tszOwnAvatar(m_tszAvatarFolder + L"\\myavatar.jpg");
- wcsncpy_s((wchar_t*)wParam, lParam, tszOwnAvatar.c_str(), _TRUNCATE);
- return 0;
-}
-
-INT_PTR WhatsAppProto::SetMyAvatar(WPARAM, LPARAM)
-{
- return 0;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-void WhatsAppProto::ServerFetchAvatar(const char *jid)
-{
- WANodeIq iq(IQ::GET, "w:profile:picture", jid);
- *iq.addChild("picture") << CHAR_PARAM("type", "preview") << CHAR_PARAM("query", "url");
- WSSendNode(iq, &WhatsAppProto::OnIqGetAvatar);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-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;
-}
+/*
+
+WhatsApp plugin for Miranda NG
+Copyright © 2019-23 George Hazan
+
+*/
+
+#include "stdafx.h"
+
+void WhatsAppProto::OnIqGetAvatar(const WANode &node)
+{
+ auto *pUser = FindUser(node.getAttr("from"));
+ if (pUser == nullptr)
+ return;
+
+ PROTO_AVATAR_INFORMATION ai = {};
+ ai.hContact = pUser->hContact;
+ ai.format = PA_FORMAT_JPEG;
+ wcsncpy_s(ai.filename, GetAvatarFileName(pUser->hContact), _TRUNCATE);
+
+ auto *pNode = node.getChild("picture");
+
+ DWORD dwLastChangeTime = pNode->getAttrInt("id");
+
+ CMStringA szUrl(pNode->getAttr("url"));
+ if (szUrl.IsEmpty()) {
+ setDword(pUser->hContact, DBKEY_AVATAR_TAG, 0); // avatar doesn't exist, don't check it later
+
+LBL_Error:
+ ProtoBroadcastAck(pUser->hContact, ACKTYPE_AVATAR, ACKRESULT_FAILED, HANDLE(&ai));
+ return;
+ }
+
+ // if avatar was changed or not present at all, download it
+ if (dwLastChangeTime > getDword(pUser->hContact, DBKEY_AVATAR_TAG)) {
+ if (!g_plugin.SaveFile(szUrl, ai))
+ goto LBL_Error;
+
+ // set timestamp of avatar being saved
+ setDword(pUser->hContact, DBKEY_AVATAR_TAG, dwLastChangeTime);
+ }
+ ProtoBroadcastAck(pUser->hContact, ACKTYPE_AVATAR, ACKRESULT_SUCCESS, HANDLE(&ai));
+}
+
+INT_PTR WhatsAppProto::GetAvatarInfo(WPARAM wParam, LPARAM lParam)
+{
+ PROTO_AVATAR_INFORMATION *pai = (PROTO_AVATAR_INFORMATION*)lParam;
+
+ ptrA jid(getStringA(pai->hContact, isChatRoom(pai->hContact) ? "ChatRoomID" : DBKEY_ID));
+ if (jid == NULL)
+ return GAIR_NOAVATAR;
+
+ CMStringW tszFileName(GetAvatarFileName(pai->hContact));
+ wcsncpy_s(pai->filename, tszFileName.c_str(), _TRUNCATE);
+ pai->format = PA_FORMAT_JPEG;
+
+ DWORD dwTag = getDword(pai->hContact, DBKEY_AVATAR_TAG, -1);
+ if (dwTag == -1 || (wParam & GAIF_FORCE) != 0)
+ if (pai->hContact != NULL && isOnline()) {
+ ServerFetchAvatar(jid);
+ return GAIR_WAITFOR;
+ }
+
+ debugLogA("No avatar");
+ return GAIR_NOAVATAR;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+INT_PTR WhatsAppProto::GetAvatarCaps(WPARAM wParam, LPARAM lParam)
+{
+ switch (wParam) {
+ case AF_PROPORTION:
+ return PIP_SQUARE;
+
+ case AF_FORMATSUPPORTED: // Jabber supports avatars of virtually all formats
+ return PA_FORMAT_JPEG;
+
+ case AF_ENABLED:
+ return TRUE;
+
+ case AF_MAXSIZE:
+ POINT *size = (POINT*)lParam;
+ if (size)
+ size->x = size->y = 640;
+ return 0;
+ }
+ return -1;
+}
+
+CMStringW WhatsAppProto::GetAvatarFileName(MCONTACT hContact)
+{
+ CMStringW result = m_tszAvatarFolder + L"\\";
+
+ CMStringA jid;
+ if (hContact != NULL) {
+ ptrA szId(getStringA(hContact, isChatRoom(hContact) ? "ChatRoomID" : DBKEY_ID));
+ if (szId == NULL)
+ return L"";
+
+ jid = szId;
+ }
+ else jid = m_szJid;
+
+ return result + _A2T(jid.c_str()) + L".jpg";
+}
+
+INT_PTR WhatsAppProto::GetMyAvatar(WPARAM wParam, LPARAM lParam)
+{
+ std::wstring tszOwnAvatar(m_tszAvatarFolder + L"\\myavatar.jpg");
+ wcsncpy_s((wchar_t*)wParam, lParam, tszOwnAvatar.c_str(), _TRUNCATE);
+ return 0;
+}
+
+INT_PTR WhatsAppProto::SetMyAvatar(WPARAM, LPARAM)
+{
+ return 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+void WhatsAppProto::ServerFetchAvatar(const char *jid)
+{
+ WANodeIq iq(IQ::GET, "w:profile:picture", jid);
+ *iq.addChild("picture") << CHAR_PARAM("type", "preview") << CHAR_PARAM("query", "url");
+ WSSendNode(iq, &WhatsAppProto::OnIqGetAvatar);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+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;
+}