From ebbf4ad769d99f07c6d5184d9fe4323e7eaf0246 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Wed, 28 Jan 2015 23:20:50 +0000 Subject: avatars are back git-svn-id: http://svn.miranda-ng.org/main/trunk@11943 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/WhatsApp/src/WhatsAPI++/WAConnection.cpp | 26 ++------- protocols/WhatsApp/src/WhatsAPI++/WAConnection.h | 34 ++--------- protocols/WhatsApp/src/contacts.cpp | 51 ++-------------- protocols/WhatsApp/src/proto.cpp | 68 +++++++++++++++++++++- protocols/WhatsApp/src/proto.h | 19 +++--- protocols/WhatsApp/src/theme.cpp | 1 - protocols/WhatsApp/src/version.h | 2 +- 7 files changed, 94 insertions(+), 107 deletions(-) (limited to 'protocols/WhatsApp') diff --git a/protocols/WhatsApp/src/WhatsAPI++/WAConnection.cpp b/protocols/WhatsApp/src/WhatsAPI++/WAConnection.cpp index 29aaec738b..27dd4aff3a 100644 --- a/protocols/WhatsApp/src/WhatsAPI++/WAConnection.cpp +++ b/protocols/WhatsApp/src/WhatsAPI++/WAConnection.cpp @@ -650,31 +650,15 @@ void WAConnection::sendGetOwningGroups() throw (WAException) this->mutex->unlock(); } -void WAConnection::sendGetPicture(const std::string& jid, const std::string& type, const std::string& oldId, const std::string& newId) throw (WAException) +void WAConnection::sendGetPicture(const std::string& jid, const std::string& type) throw (WAException) { - std::string id = makeId("get_picture_"); - this->pending_server_requests[id] = new IqResultGetPhotoHandler(this, jid, oldId, newId); + std::string id = makeId("iq_"); + this->pending_server_requests[id] = new IqResultGetPhotoHandler(this, jid); - ProtocolTreeNode *listNode = new ProtocolTreeNode("picture") - << XATTR("xmlns", "w:profile:picture") << XATTR("type", type); + ProtocolTreeNode *listNode = new ProtocolTreeNode("picture") << XATTR("type", type); this->out->write(ProtocolTreeNode("iq", listNode) - << XATTR("id", id) << XATTR("to", jid) << XATTR("type", "get")); -} - -void WAConnection::sendGetPictureIds(const std::vector& jids) throw (WAException) -{ - std::string id = makeId("get_picture_ids_"); - this->pending_server_requests[id] = new IqResultGetPictureIdsHandler(this); - - std::vector* children = new std::vector(); - for (size_t i = 0; i < jids.size(); i++) { - ProtocolTreeNode *child = new ProtocolTreeNode("user") << XATTR("jid", jids[i]); - children->push_back(child); - } - - ProtocolTreeNode *queryNode = new ProtocolTreeNode("list", NULL, children) << XATTR("xmlns", "w:profile:picture"); - this->out->write(ProtocolTreeNode("iq", queryNode) << XATTR("id", id) << XATTR("type", "get")); + << XATTR("id", id) << XATTR("to", jid) << XATTR("xmlns", "w:profile:picture") << XATTR("type", "get")); } void WAConnection::sendGetPrivacyList() throw (WAException) diff --git a/protocols/WhatsApp/src/WhatsAPI++/WAConnection.h b/protocols/WhatsApp/src/WhatsAPI++/WAConnection.h index 560f957634..5a5dfc5b83 100644 --- a/protocols/WhatsApp/src/WhatsAPI++/WAConnection.h +++ b/protocols/WhatsApp/src/WhatsAPI++/WAConnection.h @@ -45,8 +45,7 @@ public: virtual void onDirty(const std::map& paramHashtable)=0; virtual void onDirtyResponse(int paramHashtable)=0; virtual void onRelayRequest(const std::string& paramString1, int paramInt, const std::string& paramString2)=0; - virtual void onSendGetPictureIds(std::map* ids)=0; - virtual void onSendGetPicture(const std::string& jid, const std::vector& data, const std::string& oldId, const std::string& newId)=0; + virtual void onSendGetPicture(const std::string& jid, const std::vector& data, const std::string& id)=0; virtual void onPictureChanged(const std::string& from, const std::string& author, bool set)=0; virtual void onDeleteAccount(bool result)=0; }; @@ -254,10 +253,8 @@ class WAConnection { std::string oldId; std::string newId; public: - IqResultGetPhotoHandler(WAConnection* con, const std::string& jid, const std::string& oldId, const std::string& newId):IqResultHandler(con) { + IqResultGetPhotoHandler(WAConnection* con, const std::string& jid):IqResultHandler(con) { this->jid = jid; - this->oldId = oldId; - this->newId = newId; } virtual void parse(ProtocolTreeNode* node, const std::string& from) throw (WAException) { const string &attributeValue = node->getAttributeValue("type"); @@ -269,7 +266,7 @@ class WAConnection { const string &id = current->getAttributeValue("id"); if (!id.empty() && current->data != NULL && current->data->size() > 0) { if (current->data != NULL) - this->con->event_handler->onSendGetPicture(this->jid, *current->data, this->oldId, this->newId); + this->con->event_handler->onSendGetPicture(this->jid, *current->data, id); break; } } @@ -278,7 +275,7 @@ class WAConnection { void error(ProtocolTreeNode* node) throw (WAException) { if (this->con->event_handler != NULL) { std::vector v; - this->con->event_handler->onSendGetPicture("error", v, "", ""); + this->con->event_handler->onSendGetPicture("error", v, ""); } } }; @@ -299,26 +296,6 @@ class WAConnection { } }; - class IqResultGetPictureIdsHandler: public IqResultHandler { - public: - IqResultGetPictureIdsHandler(WAConnection* con):IqResultHandler(con) {} - virtual void parse(ProtocolTreeNode* node, const std::string& from) throw (WAException) { - // logData("onGetPhotoIds %s", node->toString().c_str()); - ProtocolTreeNode* groupNode = node->getChild("list"); - std::vector children(groupNode->getAllChildren("user")); - std::map ids; - for (size_t i = 0; i < children.size(); i++) { - const string &jid = children[i]->getAttributeValue("jid"); - const string &id = children[i]->getAttributeValue("id"); - if (!jid.empty()) - ids[jid] = id; - } - - if (this->con->event_handler != NULL) - this->con->event_handler->onSendGetPictureIds(&ids); - } - }; - class IqResultSendDeleteAccount: public IqResultHandler { public: IqResultSendDeleteAccount(WAConnection* con):IqResultHandler(con) {} @@ -446,8 +423,7 @@ public: void sendRemoveParticipants(const std::string& gjid, const std::vector& participants) throw (WAException); void sendSetNewSubject(const std::string& gjid, const std::string& subject) throw (WAException); void sendStatusUpdate(std::string& status) throw (WAException); - void sendGetPicture(const std::string& jid, const std::string& type, const std::string& oldId, const std::string& newId) throw (WAException); - void sendGetPictureIds(const std::vector& jids) throw (WAException); + void sendGetPicture(const std::string& jid, const std::string& type) throw (WAException); void sendSetPicture(const std::string& jid, std::vector* data) throw (WAException); void sendNotificationReceived(const std::string& from, const std::string& id) throw(WAException); void sendDeleteAccount() throw(WAException); diff --git a/protocols/WhatsApp/src/contacts.cpp b/protocols/WhatsApp/src/contacts.cpp index 39b7c48849..1efadd1876 100644 --- a/protocols/WhatsApp/src/contacts.cpp +++ b/protocols/WhatsApp/src/contacts.cpp @@ -128,11 +128,6 @@ void WhatsAppProto::ProcessBuddyList(void*) ptrA jid(getStringA(hContact, WHATSAPP_KEY_ID)); if (jid) { try { - if (!db_get_b(hContact, "CList", "Hidden", 0)) { - // Do not request picture for inactive groups - this would make the group visible again - jids.push_back(string(jid)); - } - if (getByte(hContact, "SimpleChatRoom", 0) == 0) { m_pConnection->sendQueryLastOnline((char*)jid); m_pConnection->sendPresenceSubscriptionRequest((char*)jid); @@ -142,12 +137,6 @@ void WhatsAppProto::ProcessBuddyList(void*) } } - if (jids.size() > 0) { - try { - m_pConnection->sendGetPictureIds(jids); - } - CODE_BLOCK_CATCH_ALL - } try { m_pConnection->sendGetGroups(); m_pConnection->sendGetOwningGroups(); @@ -199,34 +188,30 @@ void WhatsAppProto::onPictureChanged(const std::string& from, const std::string& if (this->isOnline()) { vector ids; ids.push_back(from); - m_pConnection->sendGetPictureIds(ids); + m_pConnection->sendGetPicture(from, "image"); } } -void WhatsAppProto::onSendGetPicture(const std::string& jid, const std::vector& data, const std::string& oldId, const std::string& newId) +void WhatsAppProto::onSendGetPicture(const std::string& jid, const std::vector& data, const std::string& id) { MCONTACT hContact = this->ContactIDToHContact(jid); if (hContact) { debugLogA("Updating avatar for jid %s", jid.c_str()); // Save avatar - std::tstring filename = this->GetAvatarFolder(); - if (_taccess(filename.c_str(), 0)) - CallService(MS_UTILS_CREATEDIRTREET, 0, (LPARAM)filename.c_str()); - filename = filename + _T("\\") + (TCHAR*)_A2T(jid.c_str()) + _T("-") + (TCHAR*)_A2T(newId.c_str()) + _T(".jpg"); + std::tstring filename = GetAvatarFileName(hContact); FILE *f = _tfopen(filename.c_str(), _T("wb")); - int r = (int)fwrite(std::string(data.begin(), data.end()).c_str(), 1, data.size(), f); + size_t r = fwrite(std::string(data.begin(), data.end()).c_str(), 1, data.size(), f); fclose(f); PROTO_AVATAR_INFORMATIONT ai = { sizeof(ai) }; ai.hContact = hContact; ai.format = PA_FORMAT_JPEG; - _tcsncpy(ai.filename, filename.c_str(), SIZEOF(ai.filename)); - ai.filename[SIZEOF(ai.filename) - 1] = 0; + _tcsncpy_s(ai.filename, filename.c_str(), _TRUNCATE); int ackResult; if (r > 0) { - setString(hContact, WHATSAPP_KEY_AVATAR_ID, newId.c_str()); + setString(hContact, WHATSAPP_KEY_AVATAR_ID, id.c_str()); ackResult = ACKRESULT_SUCCESS; } else { @@ -236,30 +221,6 @@ void WhatsAppProto::onSendGetPicture(const std::string& jid, const std::vector* ids) -{ - for (std::map::iterator it = ids->begin(); it != ids->end(); ++it) { - MCONTACT hContact = this->AddToContactList(it->first); - if (hContact != NULL) { - DBVARIANT dbv; - std::string oldId; - if (getString(hContact, WHATSAPP_KEY_AVATAR_ID, &dbv)) - oldId = ""; - else { - oldId = dbv.pszVal; - db_free(&dbv); - } - - if (it->second.size() > 0 && it->second.compare(oldId) != 0) { - try { - m_pConnection->sendGetPicture(it->first, "image", oldId, it->second); - } - CODE_BLOCK_CATCH_ALL - } - } - } -} - TCHAR* WhatsAppProto::GetContactDisplayName(const string& jid) { MCONTACT hContact = this->ContactIDToHContact(jid); diff --git a/protocols/WhatsApp/src/proto.cpp b/protocols/WhatsApp/src/proto.cpp index fcd64ebd8a..eaf6b3d358 100644 --- a/protocols/WhatsApp/src/proto.cpp +++ b/protocols/WhatsApp/src/proto.cpp @@ -21,6 +21,9 @@ WhatsAppProto::WhatsAppProto(const char* proto_name, const TCHAR* username) : CreateProtoService(PS_JOINCHAT, &WhatsAppProto::OnJoinChat); CreateProtoService(PS_LEAVECHAT, &WhatsAppProto::OnLeaveChat); + CreateProtoService(PS_GETAVATARINFOT, &WhatsAppProto::GetAvatarInfo); + CreateProtoService(PS_GETAVATARCAPS, &WhatsAppProto::GetAvatarCaps); + HookProtoEvent(ME_OPT_INITIALISE, &WhatsAppProto::OnOptionsInit); HookProtoEvent(ME_SYSTEM_MODULESLOADED, &WhatsAppProto::OnModulesLoaded); HookProtoEvent(ME_CLIST_PREBUILDSTATUSMENU, &WhatsAppProto::OnBuildStatusMenu); @@ -41,7 +44,10 @@ WhatsAppProto::WhatsAppProto(const char* proto_name, const TCHAR* username) : WASocketConnection::initNetwork(m_hNetlibUser); - def_avatar_folder_ = std::tstring(VARST(_T("%miranda_avatarcache%"))) + _T("\\") + m_tszUserName; + m_tszAvatarFolder = std::tstring(VARST(_T("%miranda_avatarcache%"))) + _T("\\") + m_tszUserName; + DWORD dwAttributes = GetFileAttributes(m_tszAvatarFolder.c_str()); + if (dwAttributes == 0xffffffff || (dwAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) + CreateDirectoryTreeT(m_tszAvatarFolder.c_str()); SetAllContactStatuses(ID_STATUS_OFFLINE, true); } @@ -348,9 +354,65 @@ void WhatsAppProto::RequestFriendship(MCONTACT hContact) } } -std::tstring WhatsAppProto::GetAvatarFolder() +INT_PTR WhatsAppProto::GetAvatarInfo(WPARAM wParam, LPARAM lParam) +{ + PROTO_AVATAR_INFORMATIONT* AI = (PROTO_AVATAR_INFORMATIONT*)lParam; + + ptrA id(getStringA(AI->hContact, WHATSAPP_KEY_ID)); + if (id == NULL) + return GAIR_NOAVATAR; + + std::tstring tszFileName = GetAvatarFileName(AI->hContact); + _tcsncpy_s(AI->filename, tszFileName.c_str(), _TRUNCATE); + AI->format = PA_FORMAT_JPEG; + + ptrA szAvatarId(getStringA(AI->hContact, WHATSAPP_KEY_AVATAR_ID)); + if (szAvatarId == NULL || (wParam & GAIF_FORCE) != 0) + if (AI->hContact != NULL && m_pConnection != NULL) { + m_pConnection->sendGetPicture((const char*)id, "image"); + 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 = 96; + return 0; + } + return -1; +} + +std::tstring WhatsAppProto::GetAvatarFileName(MCONTACT hContact) { - return def_avatar_folder_; + std::tstring result = m_tszAvatarFolder + _T("\\"); + + std::string jid; + if (hContact != NULL) { + ptrA szId(getStringA(hContact, "ID")); + if (szId == NULL) + return _T(""); + + jid = szId; + } + else jid = this->jid; + + return result + std::tstring(_A2T(jid.c_str())) + _T(".jpg"); } LRESULT CALLBACK PopupDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) diff --git a/protocols/WhatsApp/src/proto.h b/protocols/WhatsApp/src/proto.h index a55d357e3f..25f145be59 100644 --- a/protocols/WhatsApp/src/proto.h +++ b/protocols/WhatsApp/src/proto.h @@ -74,12 +74,12 @@ public: INT_PTR __cdecl OnJoinChat(WPARAM, LPARAM); INT_PTR __cdecl OnLeaveChat(WPARAM, LPARAM); INT_PTR __cdecl OnCreateGroup(WPARAM, LPARAM); - int __cdecl OnOptionsInit(WPARAM, LPARAM); - int __cdecl OnModulesLoaded(WPARAM, LPARAM); ////////////////////////////////////////////////////////////////////////////////////// // Events + int __cdecl OnOptionsInit(WPARAM, LPARAM); + int __cdecl OnModulesLoaded(WPARAM, LPARAM); int __cdecl OnBuildStatusMenu(WPARAM, LPARAM); int __cdecl OnChatOutgoing(WPARAM, LPARAM); int __cdecl OnPrebuildContactMenu(WPARAM, LPARAM); @@ -143,9 +143,17 @@ private: LONG m_iSerial; - std::tstring GetAvatarFolder(); void ToggleStatusMenuItems(BOOL bEnable); + ////////////////////////////////////////////////////////////////////////////////////// + // Avatars + + std::tstring GetAvatarFileName(MCONTACT); + std::tstring m_tszAvatarFolder; + + INT_PTR __cdecl GetAvatarInfo(WPARAM, LPARAM); + INT_PTR __cdecl GetAvatarCaps(WPARAM, LPARAM); + ////////////////////////////////////////////////////////////////////////////////////// // Handles, Locks @@ -156,8 +164,6 @@ private: HANDLE log_lock_; HANDLE update_loop_lock_; - std::tstring def_avatar_folder_; - WASocketConnection *conn; WAConnection *m_pConnection; Mutex connMutex; @@ -188,8 +194,7 @@ protected: virtual void onDirty(const std::map& paramHashtable) { } virtual void onDirtyResponse(int paramHashtable) { } virtual void onRelayRequest(const std::string ¶mString1, int paramInt, const std::string ¶mString2) { } - virtual void onSendGetPictureIds(std::map* ids); - virtual void onSendGetPicture(const std::string &jid, const std::vector& data, const std::string &oldId, const std::string &newId); + virtual void onSendGetPicture(const std::string &jid, const std::vector& data, const std::string &id); virtual void onPictureChanged(const std::string &from, const std::string &author, bool set); virtual void onDeleteAccount(bool result) { } diff --git a/protocols/WhatsApp/src/theme.cpp b/protocols/WhatsApp/src/theme.cpp index 576407ca91..94e46e8b14 100644 --- a/protocols/WhatsApp/src/theme.cpp +++ b/protocols/WhatsApp/src/theme.cpp @@ -81,7 +81,6 @@ void WhatsAppProto::InitContactMenus() ::HookEvent(ME_CLIST_PREBUILDCONTACTMENU, PrebuildContactMenu); CLISTMENUITEM mi = { sizeof(mi) }; - mi.position = -2000006100; mi.icolibItem = GetIconHandle("leaveGroup"); mi.pszName = GetIconDescription("leaveGroup"); diff --git a/protocols/WhatsApp/src/version.h b/protocols/WhatsApp/src/version.h index 6dc5649787..6d60ffbd86 100644 --- a/protocols/WhatsApp/src/version.h +++ b/protocols/WhatsApp/src/version.h @@ -1,7 +1,7 @@ #define __MAJOR_VERSION 0 #define __MINOR_VERSION 1 #define __RELEASE_NUM 2 -#define __BUILD_NUM 3 +#define __BUILD_NUM 4 #include -- cgit v1.2.3