From 59de222d916876cc158d03909b661dd8b2cf6a3f Mon Sep 17 00:00:00 2001 From: George Hazan Date: Mon, 7 Oct 2013 16:29:17 +0000 Subject: - frient list & statuses; - code cleaning git-svn-id: http://svn.miranda-ng.org/main/trunk@6396 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/VKontakte/src/misc.cpp | 21 ++++++ protocols/VKontakte/src/vk.h | 5 +- protocols/VKontakte/src/vk_proto.cpp | 7 ++ protocols/VKontakte/src/vk_proto.h | 13 +++- protocols/VKontakte/src/vk_queue.cpp | 29 ++++---- protocols/VKontakte/src/vk_thread.cpp | 126 ++++++++++++++++++++++++++++++++-- 6 files changed, 176 insertions(+), 25 deletions(-) diff --git a/protocols/VKontakte/src/misc.cpp b/protocols/VKontakte/src/misc.cpp index a59a4a16b4..6470a303ad 100644 --- a/protocols/VKontakte/src/misc.cpp +++ b/protocols/VKontakte/src/misc.cpp @@ -38,6 +38,27 @@ void CVkProto::SetAllContactStatuses(int iStatus) } } +HANDLE CVkProto::FindUser(LPCSTR pUserid, bool bCreate) +{ + for (HANDLE hContact = db_find_first(m_szModuleName); hContact; hContact = db_find_next(hContact, m_szModuleName)) { + ptrA dbUserid(getStringA(hContact, "ID")); + if (dbUserid == NULL) + continue; + + if ( !strcmp(dbUserid, pUserid)) + return hContact; + } + + if (!bCreate) + return NULL; + + HANDLE hNewContact = (HANDLE)CallService(MS_DB_CONTACT_ADD, 0, 0); + CallService(MS_PROTO_ADDTOCONTACT, (WPARAM)hNewContact, (LPARAM)m_szModuleName); + setString(hNewContact, "ID", pUserid); + db_set_ts(hNewContact, "CList", "Group", m_defaultGroup); + return hNewContact; +} + int CVkProto::SetServerStatus(int iStatus) { return 0; diff --git a/protocols/VKontakte/src/vk.h b/protocols/VKontakte/src/vk.h index d6a9a0f9d0..8b979cd8cf 100644 --- a/protocols/VKontakte/src/vk.h +++ b/protocols/VKontakte/src/vk.h @@ -20,7 +20,10 @@ along with this program. If not, see . #define VK_API_URL "api.vk.com" #define VK_REDIRECT_URL "http://" VK_API_URL "/blank.html" -typedef NETLIBHTTPHEADER HttpParam; +struct HttpParam +{ + LPCSTR szName, szValue; +}; extern HINSTANCE hInst; diff --git a/protocols/VKontakte/src/vk_proto.cpp b/protocols/VKontakte/src/vk_proto.cpp index d2e213e998..a93c84d647 100644 --- a/protocols/VKontakte/src/vk_proto.cpp +++ b/protocols/VKontakte/src/vk_proto.cpp @@ -38,6 +38,13 @@ CVkProto::CVkProto(const char *szModuleName, const TCHAR *ptszUserName) : mir_sntprintf(descr, SIZEOF(descr), _T("%%miranda_avatarcache%%\\%s"), m_tszUserName); hAvatarFolder = FoldersRegisterCustomPathT(LPGEN("Avatars"), m_szModuleName, descr, m_tszUserName); + m_defaultGroup = getTStringA("ProtoGroup"); + if (m_defaultGroup == NULL) + m_defaultGroup = mir_tstrdup( TranslateT("VKontakte")); + Clist_CreateGroup(NULL, m_defaultGroup); + + db_set_resident(m_szModuleName, "Status"); + // Set all contacts offline -- in case we crashed SetAllContactStatuses(ID_STATUS_OFFLINE); } diff --git a/protocols/VKontakte/src/vk_proto.h b/protocols/VKontakte/src/vk_proto.h index c8ee1a21cb..71a9eecf1c 100644 --- a/protocols/VKontakte/src/vk_proto.h +++ b/protocols/VKontakte/src/vk_proto.h @@ -89,6 +89,12 @@ struct CVkProto : public PROTO TCHAR* GetUserStoredPassword(void); + void RetrieveUserInfo(LPCSTR szUserId); + void OnReceiveUserInfo(NETLIBHTTPREQUEST*); + + void RetrieveFriends(); + void OnReceiveFriends(NETLIBHTTPREQUEST*); + __forceinline bool IsOnline() const { return m_bOnline; } private: @@ -113,7 +119,7 @@ private: void InitQueue(); void UninitQueue(); void ExecuteRequest(AsyncHttpRequest*); - bool PushAsyncHttpRequest(int iRequestType, LPCSTR szUrl, bool bSecure, VK_REQUEST_HANDLER pFunc, int nParams = 0, NETLIBHTTPHEADER *pParams = 0, int iTimeout = 10000); + bool PushAsyncHttpRequest(int iRequestType, LPCSTR szUrl, bool bSecure, VK_REQUEST_HANDLER pFunc, int nParams = 0, HttpParam *pParams = 0, int iTimeout = 10000); bool PushAsyncHttpRequest(AsyncHttpRequest*, int iTimeout = 10000); int SetupConnection(void); void __cdecl WorkerThread(void*); @@ -125,6 +131,8 @@ private: void OnLoggedOut(); void ShutdownSession(); + HANDLE FindUser(LPCSTR userid, bool bCreate = false); + void SetAllContactStatuses(int status); int SetServerStatus(int); @@ -132,5 +140,6 @@ private: HANDLE m_hNetlibUser, m_hNetlibConn; HANDLE hAvatarFolder; - ptrA m_szAccessToken; + ptrA m_szAccessToken, m_myUserId; + ptrT m_defaultGroup; }; diff --git a/protocols/VKontakte/src/vk_queue.cpp b/protocols/VKontakte/src/vk_queue.cpp index be8c8868eb..47a146ffa9 100644 --- a/protocols/VKontakte/src/vk_queue.cpp +++ b/protocols/VKontakte/src/vk_queue.cpp @@ -60,7 +60,7 @@ void CVkProto::ExecuteRequest(AsyncHttpRequest *pReq) ///////////////////////////////////////////////////////////////////////////////////////// -bool CVkProto::PushAsyncHttpRequest(int iRequestType, LPCSTR szUrl, bool bSecure, VK_REQUEST_HANDLER pFunc, int nParams, NETLIBHTTPHEADER *pParams, int iTimeout) +bool CVkProto::PushAsyncHttpRequest(int iRequestType, LPCSTR szUrl, bool bSecure, VK_REQUEST_HANDLER pFunc, int nParams, HttpParam *pParams, int iTimeout) { if ( !SetupConnection()) return false; @@ -124,27 +124,22 @@ void CVkProto::WorkerThread(void*) } while(true) { - DWORD dwRet = WaitForSingleObject(m_evRequestsQueue, 1000); - if (dwRet == WAIT_TIMEOUT) { - // check expiration; - continue; - } - - if (dwRet != WAIT_OBJECT_0) - continue; - + WaitForSingleObject(m_evRequestsQueue, 1000); if (m_bTerminated) break; AsyncHttpRequest *pReq; - { mir_cslock lck(m_csRequestsQueue); - if (m_arRequestsQueue.getCount() == 0) - continue; - - pReq = m_arRequestsQueue[0]; - m_arRequestsQueue.remove(0); + while(true) { + { + mir_cslock lck(m_csRequestsQueue); + if (m_arRequestsQueue.getCount() == 0) + break; + + pReq = m_arRequestsQueue[0]; + m_arRequestsQueue.remove(0); + } + ExecuteRequest(pReq); } - ExecuteRequest(pReq); } OnLoggedOut(); diff --git a/protocols/VKontakte/src/vk_thread.cpp b/protocols/VKontakte/src/vk_thread.cpp index 18b10add99..92b0f4ce76 100644 --- a/protocols/VKontakte/src/vk_thread.cpp +++ b/protocols/VKontakte/src/vk_thread.cpp @@ -45,6 +45,8 @@ void CVkProto::OnLoggedIn() HttpParam param = { "access_token", m_szAccessToken }; PushAsyncHttpRequest(REQUEST_GET, "/method/getUserInfoEx.json", true, &CVkProto::OnReceiveMyInfo, 1, ¶m); + + SetAllContactStatuses(ID_STATUS_OFFLINE); } void CVkProto::OnLoggedOut() @@ -143,12 +145,13 @@ LBL_NoForm: void CVkProto::OnReceiveMyInfo(NETLIBHTTPREQUEST *reply) { + Netlib_Logf(m_hNetlibUser, "CVkProto::OnReceiveMyInfo %d", reply->resultCode); if (reply->resultCode != 200) { ConnectionFailed(LOGINERR_WRONGPASSWORD); return; } - JSONNODE *pRoot = json_parse(reply->pData); + JSONROOT pRoot(reply->pData); if ( !CheckJsonResult(pRoot)) return; @@ -159,8 +162,11 @@ void CVkProto::OnReceiveMyInfo(NETLIBHTTPREQUEST *reply) for (size_t i = 0; i < json_size(pResponse); i++) { JSONNODE *it = json_at(pResponse, i); LPCSTR id = json_name(it); - if ( !_stricmp(id, "user_id")) - setTString("ID", ptrT( json_as_string(it))); + if ( !_stricmp(id, "user_id")) { + ptrT userid( json_as_string(it)); + m_myUserId = mir_t2a(userid); + setTString("ID", userid); + } else if ( !_stricmp(id, "user_name")) setTString("Nick", ptrT( json_as_string(it))); else if ( !_stricmp(id, "user_sex")) @@ -168,13 +174,123 @@ void CVkProto::OnReceiveMyInfo(NETLIBHTTPREQUEST *reply) else if ( !_stricmp(id, "user_bdate")) { ptrT date( json_as_string(it)); int d, m, y; - if ( _tscanf(date, _T("%d.%d.%d"), &d, &m, &y) == 3) { + if ( _stscanf(date, _T("%d.%d.%d"), &d, &m, &y) == 3) { setByte("BirthDay", d); setByte("BirthMonth", m); - setByte("BirthYear", y); + setWord("BirthYear", y); } } else if ( !_stricmp(id, "user_photo")) setTString("Photo", ptrT( json_as_string(it))); } + + RetrieveUserInfo(m_myUserId); + RetrieveFriends(); +} + +///////////////////////////////////////////////////////////////////////////////////////// + +void CVkProto::RetrieveUserInfo(LPCSTR szUserId) +{ + HttpParam params[] = { + { "fields", "uid,first_name,last_name,photo,sex,bdate,city,relation" }, + { "uids", szUserId }, + { "access_token", m_szAccessToken } + }; + PushAsyncHttpRequest(REQUEST_GET, "/method/getProfiles.json", true, &CVkProto::OnReceiveUserInfo, SIZEOF(params), params); +} + +void CVkProto::OnReceiveUserInfo(NETLIBHTTPREQUEST *reply) +{ + Netlib_Logf(m_hNetlibUser, "CVkProto::OnReceiveUserInfo %d", reply->resultCode); + if (reply->resultCode != 200) + return; + + JSONROOT pRoot(reply->pData); + if ( !CheckJsonResult(pRoot)) + return; + + JSONNODE *pResponse = json_get(pRoot, "response"); + if (pResponse == NULL) + return; + + HANDLE hContact; + for (size_t i = 0; i < json_size(pResponse); i++) { + JSONNODE *it = json_at(pResponse, i); + LPCSTR id = json_name(it); + if ( !_stricmp(id, "user_id")) { + ptrA userid( _T2A( json_as_string(it))); + if ( !lstrcmpA(userid, m_myUserId)) + hContact = NULL; + else if ((hContact = FindUser(userid, false)) == NULL) + return; + } + else if ( !_stricmp(id, "user_name")) + setTString(hContact, "Nick", ptrT( json_as_string(it))); + else if ( !_stricmp(id, "user_sex")) + setByte(hContact, "Gender", json_as_int(it) == 2 ? 'M' : 'F'); + else if ( !_stricmp(id, "user_bdate")) { + ptrT date( json_as_string(it)); + int d, m, y; + if ( _stscanf(date, _T("%d.%d.%d"), &d, &m, &y) == 3) { + setByte(hContact, "BirthDay", d); + setByte(hContact, "BirthMonth", m); + setWord(hContact, "BirthYear", y); + } + } + else if ( !_stricmp(id, "user_photo")) + setTString(hContact, "Photo", ptrT( json_as_string(it))); + } +} + +///////////////////////////////////////////////////////////////////////////////////////// + +void CVkProto::RetrieveFriends() +{ + Netlib_Logf(m_hNetlibUser, "CVkProto::RetrieveFriends"); + + HttpParam params[] = { + { "fields", "uid,first_name,last_name,photo,contacts" }, + { "count", "1000" }, + { "access_token", m_szAccessToken } + }; + PushAsyncHttpRequest(REQUEST_GET, "/method/friends.get.json", true, &CVkProto::OnReceiveFriends, SIZEOF(params), params); +} + +void CVkProto::OnReceiveFriends(NETLIBHTTPREQUEST *reply) +{ + Netlib_Logf(m_hNetlibUser, "CVkProto::OnReceiveFriends %d", reply->resultCode); + if (reply->resultCode != 200) + return; + + JSONROOT pRoot(reply->pData); + if ( !CheckJsonResult(pRoot)) + return; + + JSONNODE *pResponse = json_get(pRoot, "response"), *pInfo; + if (pResponse == NULL) + return; + + for (int i=0; (pInfo = json_at(pResponse, i)) != NULL; i++) { + ptrT szValue( json_as_string( json_get(pInfo, "uid"))); + if (szValue == NULL) + continue; + + HANDLE hContact = FindUser(_T2A(szValue), true); + szValue = json_as_string( json_get(pInfo, "first_name")); + if (szValue) setTString(hContact, "FirstName", szValue); + + szValue = json_as_string( json_get(pInfo, "last_name")); + if (szValue) setTString(hContact, "LastName", szValue); + + szValue = json_as_string( json_get(pInfo, "photo")); + if (szValue) setTString(hContact, "AvatarUrl", szValue); + + setWord(hContact, "Status", (json_as_int( json_get(pInfo, "online")) == 0) ? ID_STATUS_OFFLINE : ID_STATUS_ONLINE); + + szValue = json_as_string( json_get(pInfo, "mobile_phone")); + if (szValue && *szValue) setTString(hContact, "Phone0", szValue); + szValue = json_as_string( json_get(pInfo, "home_phone")); + if (szValue && *szValue) setTString(hContact, "Phone1", szValue); + } } -- cgit v1.2.3