From 925a58a69d336f2535a1083ca05cb454e755e226 Mon Sep 17 00:00:00 2001 From: Kirill Volinsky Date: Mon, 6 Apr 2015 08:57:39 +0000 Subject: avatar support 1st attempt git-svn-id: http://svn.miranda-ng.org/main/trunk@12623 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/SkypeWeb/SkypeWeb_12.vcxproj | 2 + protocols/SkypeWeb/SkypeWeb_12.vcxproj.filters | 6 ++ protocols/SkypeWeb/src/common.h | 1 + protocols/SkypeWeb/src/requests/avatars.h | 13 ++++ protocols/SkypeWeb/src/skype_avatars.cpp | 98 ++++++++++++++++++++++++++ protocols/SkypeWeb/src/skype_profile.cpp | 9 ++- protocols/SkypeWeb/src/skype_proto.cpp | 1 + protocols/SkypeWeb/src/skype_proto.h | 6 ++ 8 files changed, 134 insertions(+), 2 deletions(-) create mode 100644 protocols/SkypeWeb/src/requests/avatars.h create mode 100644 protocols/SkypeWeb/src/skype_avatars.cpp diff --git a/protocols/SkypeWeb/SkypeWeb_12.vcxproj b/protocols/SkypeWeb/SkypeWeb_12.vcxproj index 32dcf3f02c..4b7908a5bc 100644 --- a/protocols/SkypeWeb/SkypeWeb_12.vcxproj +++ b/protocols/SkypeWeb/SkypeWeb_12.vcxproj @@ -203,6 +203,7 @@ + @@ -225,6 +226,7 @@ + diff --git a/protocols/SkypeWeb/SkypeWeb_12.vcxproj.filters b/protocols/SkypeWeb/SkypeWeb_12.vcxproj.filters index ee77cf1361..d5a2443798 100644 --- a/protocols/SkypeWeb/SkypeWeb_12.vcxproj.filters +++ b/protocols/SkypeWeb/SkypeWeb_12.vcxproj.filters @@ -78,6 +78,9 @@ Header Files + + Header Files\requests + @@ -131,6 +134,9 @@ Source Files + + Source Files + diff --git a/protocols/SkypeWeb/src/common.h b/protocols/SkypeWeb/src/common.h index bbe6addfb1..405836348b 100644 --- a/protocols/SkypeWeb/src/common.h +++ b/protocols/SkypeWeb/src/common.h @@ -57,6 +57,7 @@ struct CSkypeProto; #include "requests\subscriptions.h" #include "requests\messages.h" #include "requests\poll.h" +#include "requests\avatars.h" #include "request_queue.h" #include "skype_proto.h" diff --git a/protocols/SkypeWeb/src/requests/avatars.h b/protocols/SkypeWeb/src/requests/avatars.h new file mode 100644 index 0000000000..550b4a9e5c --- /dev/null +++ b/protocols/SkypeWeb/src/requests/avatars.h @@ -0,0 +1,13 @@ +#ifndef _SKYPE_REQUEST_AVATAR_H_ +#define _SKYPE_REQUEST_AVATAR_H_ + +class GetAvatarRequest : public HttpRequest +{ +public: + GetAvatarRequest(const char *url) : HttpRequest(REQUEST_GET, url) + { + flags |= NLHRF_REDIRECT; + } +}; + +#endif //_SKYPE_REQUEST_AVATAR_H_ diff --git a/protocols/SkypeWeb/src/skype_avatars.cpp b/protocols/SkypeWeb/src/skype_avatars.cpp new file mode 100644 index 0000000000..b997c92bb1 --- /dev/null +++ b/protocols/SkypeWeb/src/skype_avatars.cpp @@ -0,0 +1,98 @@ +#include "common.h" + +void CSkypeProto::ReloadAvatarInfo(MCONTACT hContact) +{ + if (!hContact) { + CallService(MS_AV_REPORTMYAVATARCHANGED, (WPARAM)m_szModuleName, 0); + return; + } + PROTO_AVATAR_INFORMATIONT AI = { sizeof(AI) }; + AI.hContact = hContact; + SvcGetAvatarInfo(0, (LPARAM)&AI); +} + +void CSkypeProto::OnReceiveAvatar(const NETLIBHTTPREQUEST *response, void *arg) +{ + MCONTACT hContact = (MCONTACT)arg; + if (response->resultCode != 200) + return; + + PROTO_AVATAR_INFORMATIONT AI = { sizeof(AI) }; + GetAvatarFileName(hContact, AI.filename, SIZEOF(AI.filename)); + AI.format = ProtoGetBufferFormat(response->pData); + + FILE *out = _tfopen(AI.filename, _T("wb")); + if (out == NULL) { + ProtoBroadcastAck(hContact, ACKTYPE_AVATAR, ACKRESULT_FAILED, &AI, 0); + return; + } + + fwrite(response->pData, 1, response->dataLength, out); + fclose(out); + setByte(hContact, "NeedNewAvatar", 0); + ProtoBroadcastAck(hContact, ACKTYPE_AVATAR, ACKRESULT_SUCCESS, &AI, 0); +} + +INT_PTR CSkypeProto::SvcGetAvatarInfo(WPARAM, LPARAM lParam) +{ + PROTO_AVATAR_INFORMATIONT* AI = (PROTO_AVATAR_INFORMATIONT*)lParam; + + ptrA szUrl(getStringA(AI->hContact, "AvatarUrl")); + if (szUrl == NULL) + return GAIR_NOAVATAR; + + TCHAR tszFileName[MAX_PATH]; + GetAvatarFileName(AI->hContact, tszFileName, SIZEOF(tszFileName)); + _tcsncpy(AI->filename, tszFileName, SIZEOF(AI->filename)); + + AI->format = ProtoGetAvatarFormat(AI->filename); + + if (::_taccess(AI->filename, 0) == 0 && !getBool(AI->hContact, "NeedNewAvatar", 0)) + return GAIR_SUCCESS; + + if (IsOnline()) { + PushRequest(new GetAvatarRequest(szUrl), &CSkypeProto::OnReceiveAvatar, (void*)AI->hContact); + debugLogA("Requested to read an avatar from '%s'", szUrl); + return GAIR_WAITFOR; + } + + debugLogA("No avatar"); + return GAIR_NOAVATAR; +} + +void CSkypeProto::GetAvatarFileName(MCONTACT hContact, TCHAR* pszDest, size_t cbLen) +{ + int tPathLen = mir_sntprintf(pszDest, cbLen, _T("%s\\%S"), VARST(_T("%miranda_avatarcache%")), m_szModuleName); + + DWORD dwAttributes = GetFileAttributes(pszDest); + if (dwAttributes == 0xffffffff || (dwAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) + CreateDirectoryTreeT(pszDest); + + pszDest[tPathLen++] = '\\'; + + const TCHAR* szFileType = _T(".jpg"); + ptrA username(getStringA(hContact, "Skypename")); + mir_sntprintf(pszDest + tPathLen, MAX_PATH - tPathLen, _T("%s%s"), _A2T(username), szFileType); +} + +void CSkypeProto::SetAvatarUrl(MCONTACT hContact, CMString &tszUrl) +{ + CMString oldUrl(getTStringA(hContact, "AvatarUrl")); + + if (tszUrl == oldUrl) + return; + + if (tszUrl.IsEmpty()) { + delSetting(hContact, "AvatarUrl"); + ProtoBroadcastAck(hContact, ACKTYPE_AVATAR, ACKRESULT_SUCCESS, NULL, 0); + } + else { + setTString(hContact, "AvatarUrl", tszUrl.GetBuffer()); + setByte(hContact,"NeedNewAvatar", 1); + PROTO_AVATAR_INFORMATIONT AI = { sizeof(AI) }; + AI.hContact = hContact; + GetAvatarFileName(AI.hContact, AI.filename, SIZEOF(AI.filename)); + AI.format = ProtoGetAvatarFormat(AI.filename); + ProtoBroadcastAck(hContact, ACKTYPE_AVATAR, ACKRESULT_SUCCESS, (HANDLE)&AI, 0); + } +} \ No newline at end of file diff --git a/protocols/SkypeWeb/src/skype_profile.cpp b/protocols/SkypeWeb/src/skype_profile.cpp index c260380fc2..3ddb5b56c9 100644 --- a/protocols/SkypeWeb/src/skype_profile.cpp +++ b/protocols/SkypeWeb/src/skype_profile.cpp @@ -427,8 +427,13 @@ void CSkypeProto::UpdateProfileXStatusMessage(JSONNODE *root, MCONTACT hContact) void CSkypeProto::UpdateProfileAvatar(JSONNODE *root, MCONTACT hContact) { - //JSONNODE *node = json_get(root, "avatarUrl"); - // add avatar support + JSONNODE *node = json_get(root, "avatarUrl"); + CMString province = mir_t2a(ptrT(json_as_string(node))); + if (!province.IsEmpty() && province != "null") + { + SetAvatarUrl(hContact, province); + ReloadAvatarInfo(hContact); + } } //{"firstname":"Echo \/ Sound Test Service", "lastname" : null, "birthday" : null, "gender" : null, "country" : null, "city" : null, "language" : null, "homepage" : null, "about" : null, "province" : null, "jobtitle" : null, "emails" : [], "phoneMobile" : null, "phoneHome" : null, "phoneOffice" : null, "mood" : null, "richMood" : null, "avatarUrl" : null, "username" : "echo123"} diff --git a/protocols/SkypeWeb/src/skype_proto.cpp b/protocols/SkypeWeb/src/skype_proto.cpp index 35174e3eee..d66af083a4 100644 --- a/protocols/SkypeWeb/src/skype_proto.cpp +++ b/protocols/SkypeWeb/src/skype_proto.cpp @@ -17,6 +17,7 @@ PROTO(protoName, userName), password(NULL) requestQueue = new RequestQueue(m_hNetlibUser); CreateProtoService(PS_CREATEACCMGRUI, &CSkypeProto::OnAccountManagerInit); + CreateProtoService(PS_GETAVATARINFOT, &CSkypeProto::SvcGetAvatarInfo); // custom event DBEVENTTYPEDESCR dbEventType = { sizeof(dbEventType) }; diff --git a/protocols/SkypeWeb/src/skype_proto.h b/protocols/SkypeWeb/src/skype_proto.h index 6757aba4dd..39ec1acbf0 100644 --- a/protocols/SkypeWeb/src/skype_proto.h +++ b/protocols/SkypeWeb/src/skype_proto.h @@ -102,6 +102,7 @@ private: int __cdecl OnAccountLoaded(WPARAM, LPARAM); INT_PTR __cdecl OnAccountManagerInit(WPARAM, LPARAM); + INT_PTR __cdecl SvcGetAvatarInfo(WPARAM, LPARAM); // requests void PushRequest(HttpRequest *request); @@ -158,6 +159,11 @@ private: void SetContactStatus(MCONTACT hContact, WORD status); void SetAllContactsStatus(WORD status); + void SetAvatarUrl(MCONTACT hContact, CMString &tszUrl); + void ReloadAvatarInfo(MCONTACT hContact); + void GetAvatarFileName(MCONTACT hContact, TCHAR* pszDest, size_t cbLen); + void OnReceiveAvatar(const NETLIBHTTPREQUEST *response, void *arg); + MCONTACT GetContact(const char *skypename); MCONTACT AddContact(const char *skypename, bool isTemporary = false); -- cgit v1.2.3