From 3364fd6b8bdc21692805302a4333e49b44590b2c Mon Sep 17 00:00:00 2001 From: Alexander Lantsev Date: Wed, 18 Mar 2015 20:28:01 +0000 Subject: SkypeWeb: - contact list loading - refactoring git-svn-id: http://svn.miranda-ng.org/main/trunk@12431 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/SkypeWeb/SkypeWeb_12.vcxproj | 2 + protocols/SkypeWeb/SkypeWeb_12.vcxproj.filters | 6 ++ protocols/SkypeWeb/res/resource.rc | 8 +-- protocols/SkypeWeb/src/common.h | 3 +- protocols/SkypeWeb/src/requests/contacts.h | 17 ++++++ protocols/SkypeWeb/src/requests/login.h | 4 +- protocols/SkypeWeb/src/resource.h | 4 +- protocols/SkypeWeb/src/skype_contacts.cpp | 83 +++++++++++++++++++++++--- protocols/SkypeWeb/src/skype_events.cpp | 6 +- protocols/SkypeWeb/src/skype_options.cpp | 12 ++-- protocols/SkypeWeb/src/skype_proto.cpp | 4 +- protocols/SkypeWeb/src/skype_proto.h | 35 ++--------- protocols/SkypeWeb/src/skype_request.cpp | 42 +++++++++++++ 13 files changed, 171 insertions(+), 55 deletions(-) create mode 100644 protocols/SkypeWeb/src/requests/contacts.h create mode 100644 protocols/SkypeWeb/src/skype_request.cpp (limited to 'protocols') diff --git a/protocols/SkypeWeb/SkypeWeb_12.vcxproj b/protocols/SkypeWeb/SkypeWeb_12.vcxproj index 824dd30c22..697f430030 100644 --- a/protocols/SkypeWeb/SkypeWeb_12.vcxproj +++ b/protocols/SkypeWeb/SkypeWeb_12.vcxproj @@ -203,6 +203,7 @@ + @@ -215,6 +216,7 @@ + Create diff --git a/protocols/SkypeWeb/SkypeWeb_12.vcxproj.filters b/protocols/SkypeWeb/SkypeWeb_12.vcxproj.filters index 3e97d03543..e4467299e4 100644 --- a/protocols/SkypeWeb/SkypeWeb_12.vcxproj.filters +++ b/protocols/SkypeWeb/SkypeWeb_12.vcxproj.filters @@ -48,6 +48,9 @@ Header Files\requests + + Header Files\requests + @@ -86,6 +89,9 @@ Source Files + + Source Files + diff --git a/protocols/SkypeWeb/res/resource.rc b/protocols/SkypeWeb/res/resource.rc index 6e79cc7696..b59bd87258 100644 --- a/protocols/SkypeWeb/res/resource.rc +++ b/protocols/SkypeWeb/res/resource.rc @@ -94,8 +94,8 @@ EXSTYLE WS_EX_CONTROLPARENT FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN EDITTEXT IDC_PASSWORD,49,16,135,12,ES_PASSWORD | ES_AUTOHSCROLL - LTEXT "Login:",IDC_STATIC,0,2,49,12 - EDITTEXT IDC_LOGIN,49,0,135,12,ES_AUTOHSCROLL + LTEXT "Skypename:",IDC_STATIC,0,2,49,12 + EDITTEXT IDC_SKYPENAME,49,0,135,12,ES_AUTOHSCROLL LTEXT "Password:",IDC_STATIC,0,18,49,12 LTEXT "Default group:",IDC_STATIC,0,34,49,12 EDITTEXT IDC_GROUP,49,32,135,12,ES_AUTOHSCROLL @@ -107,8 +107,8 @@ EXSTYLE WS_EX_CONTROLPARENT FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN GROUPBOX "Account",IDC_STATIC,7,7,296,63,NOT WS_VISIBLE - LTEXT "Name:",IDC_STATIC,12,19,69,11 - EDITTEXT IDC_LOGIN,81,17,217,12,ES_AUTOHSCROLL + LTEXT "Skypename:",IDC_STATIC,12,19,69,11 + EDITTEXT IDC_SKYPENAME, 81, 17, 217, 12, ES_AUTOHSCROLL LTEXT "Password:",IDC_STATIC,12,34,69,8 EDITTEXT IDC_PASSWORD,81,33,217,12,ES_PASSWORD | ES_AUTOHSCROLL LTEXT "Default group:",IDC_STATIC,12,51,69,12 diff --git a/protocols/SkypeWeb/src/common.h b/protocols/SkypeWeb/src/common.h index 511fafb404..e8184c9e50 100644 --- a/protocols/SkypeWeb/src/common.h +++ b/protocols/SkypeWeb/src/common.h @@ -45,6 +45,7 @@ struct CSkypeProto; #include "http_request.h" #include "requests\login.h" #include "requests\logout.h" +#include "requests\contacts.h" #include "request_queue.h" #include "skype_proto.h" @@ -52,7 +53,7 @@ extern HINSTANCE g_hInstance; #define MODULE "SKYPE" -#define SKYPE_SETTINGS_ID "Login" +#define SKYPE_SETTINGS_ID "Skypename" #define SKYPE_SETTINGS_PASSWORD "Password" #define SKYPE_SETTINGS_GROUP "DefaultGroup" diff --git a/protocols/SkypeWeb/src/requests/contacts.h b/protocols/SkypeWeb/src/requests/contacts.h new file mode 100644 index 0000000000..3ba86d9b2e --- /dev/null +++ b/protocols/SkypeWeb/src/requests/contacts.h @@ -0,0 +1,17 @@ +#ifndef _SKYPE_REQUEST_CONTACTS_H_ +#define _SKYPE_REQUEST_CONTACTS_H_ + +class GetContactsRequest : public HttpRequest +{ +public: + GetContactsRequest(const char *token) : + HttpRequest(REQUEST_GET, "api.skype.com/users/self/contacts") + { + flags |= NLHRF_SSL; + + AddHeader("X-Skypetoken", token); + AddHeader("Accept", "application/json"); + } +}; + +#endif //_SKYPE_REQUEST_CONTACTS_H_ diff --git a/protocols/SkypeWeb/src/requests/login.h b/protocols/SkypeWeb/src/requests/login.h index e1d94806b7..73003b5046 100644 --- a/protocols/SkypeWeb/src/requests/login.h +++ b/protocols/SkypeWeb/src/requests/login.h @@ -12,7 +12,7 @@ public: url.Append("?client_id=578134&redirect_uri=https%3A%2F%2Fweb.skype.com"); } - LoginRequest(const char *username, const char *password, const char *pie, const char *etm) : + LoginRequest(const char *skypename, const char *password, const char *pie, const char *etm) : HttpRequest(REQUEST_POST, "login.skype.com/login") { flags |= NLHRF_SSL; @@ -26,7 +26,7 @@ public: int minutes = tzi->Bias % -60; CMStringA data = ""; - data.AppendFormat("username=%s&", username); + data.AppendFormat("username=%s&", skypename); data.AppendFormat("password=%s&", password); data.AppendFormat("pie=%s&", ptrA(mir_urlEncode(pie))); data.AppendFormat("etm=%s&", ptrA(mir_urlEncode(etm))); diff --git a/protocols/SkypeWeb/src/resource.h b/protocols/SkypeWeb/src/resource.h index bbd89be4de..22accb8c18 100644 --- a/protocols/SkypeWeb/src/resource.h +++ b/protocols/SkypeWeb/src/resource.h @@ -2,11 +2,11 @@ // Microsoft Visual C++ generated include file. // Used by E:\Projects\C++\MirandaNG\protocols\SkypeWeb\res\resource.rc // -#define IDC_LOGIN 101 +#define IDI_SKYPE 100 +#define IDC_SKYPENAME 101 #define IDC_PASSWORD 102 #define IDD_ACCOUNT_MANAGER 103 #define IDD_OPTIONS_MAIN 104 -#define IDI_SKYPE 105 #define IDC_GROUP 106 #define IDD_PASSWORD_EDITOR 107 #define IDC_SAVEPERMANENTLY 108 diff --git a/protocols/SkypeWeb/src/skype_contacts.cpp b/protocols/SkypeWeb/src/skype_contacts.cpp index c8aea263e5..cc50f7cef9 100644 --- a/protocols/SkypeWeb/src/skype_contacts.cpp +++ b/protocols/SkypeWeb/src/skype_contacts.cpp @@ -41,13 +41,13 @@ MCONTACT CSkypeProto::GetContactFromAuthEvent(MEVENT hEvent) return DbGetAuthEventContact(&dbei); } -MCONTACT CSkypeProto::GetContact(const char *login) +MCONTACT CSkypeProto::GetContact(const char *skypename) { MCONTACT hContact = NULL; for (hContact = db_find_first(m_szModuleName); hContact; hContact = db_find_next(hContact, m_szModuleName)) { - ptrA contactLogin(getStringA(hContact, SKYPE_SETTINGS_ID)); - if (mir_strcmpi(login, contactLogin) == 0) + ptrA cSkypename(getStringA(hContact, SKYPE_SETTINGS_ID)); + if (mir_strcmpi(skypename, cSkypename) == 0) { break; } @@ -55,15 +55,15 @@ MCONTACT CSkypeProto::GetContact(const char *login) return hContact; } -MCONTACT CSkypeProto::AddContact(const char *login, bool isTemporary) +MCONTACT CSkypeProto::AddContact(const char *skypename, bool isTemporary) { - MCONTACT hContact = GetContact(login); + MCONTACT hContact = GetContact(skypename); if (!hContact) { hContact = (MCONTACT)CallService(MS_DB_CONTACT_ADD, 0, 0); CallService(MS_PROTO_ADDTOCONTACT, hContact, (LPARAM)m_szModuleName); - setString(hContact, SKYPE_SETTINGS_ID, login); + setString(hContact, SKYPE_SETTINGS_ID, skypename); DBVARIANT dbv; if (!getTString(SKYPE_SETTINGS_GROUP, &dbv)) @@ -83,8 +83,77 @@ MCONTACT CSkypeProto::AddContact(const char *login, bool isTemporary) return hContact; } -void CSkypeProto::LoadFriendList(void*) +//[{"skypename":"echo123", "fullname" : "Echo \/ Sound Test Service", "authorized" : true, "blocked" : false, "display_name" : null, "pstn_number" : null, \ + "phone1" : null, "phone1_label" : null, "phone2" : null, "phone2_label" : null, "phone3" : null, "phone3_label" : null}] +void CSkypeProto::LoadContacts(const NETLIBHTTPREQUEST *response) { + if (response == NULL) + return; + + JSONROOT root(response->pData); + if (root == NULL) + return; + + JSONNODE *items = json_as_array(root), *item, *node; + for (size_t i = 0; i < json_size(items); i++) + { + item = json_at(items, i); + if (item == NULL) + break; + + node = json_get(item, "skypename"); + ptrA skypename(mir_t2a(ptrT(json_as_string(node)))); + MCONTACT hContact = AddContact(skypename, _T("")); + if (hContact) + { + node = json_get(item, "fullname"); + CMString realname = ptrT(json_as_string(node)); + if (!realname.IsEmpty() && realname != "null") + { + size_t pos = realname.Find(' ', 1); + if (mir_strcmpi(skypename, "echo123") != 0 && pos != -1) + { + setTString(hContact, "FirstName", realname.Mid(0, pos)); + setTString(hContact, "LastName", realname.Mid(pos + 1)); + } + else + { + setTString(hContact, "FirstName", realname); + delSetting(hContact, "LastName"); + } + } + else + { + delSetting(hContact, "FirstName"); + delSetting(hContact, "LastName"); + } + + node = json_get(item, "display_name"); + CMString nick = ptrT(json_as_string(node)); + if (!nick.IsEmpty() && nick != "null") + setTString(hContact, "Nick", nick); + else + { + node = json_get(item, "pstn_number"); + CMString pstn = ptrT(json_as_string(node)); + if (!nick.IsEmpty() && pstn != "null") + setTString(hContact, "Nick", pstn); + else + delSetting(hContact, "Nick"); + } + + node = json_get(item, "authorized"); + if (json_as_bool(node)) + { + delSetting(hContact, "Auth"); + delSetting(hContact, "Grant"); + } + + node = json_get(item, "blocked"); + setByte(hContact, "IsBlocked", json_as_bool(node)); + } + } + json_delete(items); } INT_PTR CSkypeProto::OnRequestAuth(WPARAM hContact, LPARAM lParam) diff --git a/protocols/SkypeWeb/src/skype_events.cpp b/protocols/SkypeWeb/src/skype_events.cpp index c4655bd310..d45c344b4b 100644 --- a/protocols/SkypeWeb/src/skype_events.cpp +++ b/protocols/SkypeWeb/src/skype_events.cpp @@ -36,10 +36,10 @@ void CSkypeProto::OnLoginFirst(const NETLIBHTTPREQUEST *response) } std::string etm = match[1]; - ptrA login(mir_utf8encodeT(ptrT(getTStringA(SKYPE_SETTINGS_ID)))); + ptrA skypename(mir_utf8encodeT(ptrT(getTStringA(SKYPE_SETTINGS_ID)))); ptrA password(mir_utf8encodeT(ptrT(getTStringA(SKYPE_SETTINGS_PASSWORD)))); - requestQueue->Push(new LoginRequest(login, password, pie.c_str(), etm.c_str()), HttpResponse<&CSkypeProto::OnLoginSecond>, this); + PushRequest(new LoginRequest(skypename, password, pie.c_str(), etm.c_str()), &CSkypeProto::OnLoginSecond); } void CSkypeProto::OnLoginSecond(const NETLIBHTTPREQUEST *response) @@ -89,5 +89,7 @@ void CSkypeProto::OnLoginSecond(const NETLIBHTTPREQUEST *response) cookies[match[1]] = match[2]; } + PushRequest(new GetContactsRequest(token.c_str()), &CSkypeProto::LoadContacts); + ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)ID_STATUS_CONNECTING, m_iStatus = m_iDesiredStatus); } \ No newline at end of file diff --git a/protocols/SkypeWeb/src/skype_options.cpp b/protocols/SkypeWeb/src/skype_options.cpp index bf5c2901f3..ae8c1b9c4e 100644 --- a/protocols/SkypeWeb/src/skype_options.cpp +++ b/protocols/SkypeWeb/src/skype_options.cpp @@ -13,8 +13,8 @@ INT_PTR CSkypeProto::MainOptionsProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM SetWindowLongPtr(hwnd, GWLP_USERDATA, lParam); ptrA login(proto->getStringA(SKYPE_SETTINGS_ID)); - SetDlgItemTextA(hwnd, IDC_LOGIN, login); - SendDlgItemMessage(hwnd, IDC_LOGIN, EM_LIMITTEXT, 32, 0); + SetDlgItemTextA(hwnd, IDC_SKYPENAME, login); + SendDlgItemMessage(hwnd, IDC_SKYPENAME, EM_LIMITTEXT, 32, 0); ptrA password(proto->getStringA("Password")); SetDlgItemTextA(hwnd, IDC_PASSWORD, password); @@ -30,7 +30,7 @@ INT_PTR CSkypeProto::MainOptionsProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM { switch (LOWORD(wParam)) { - case IDC_LOGIN: + case IDC_SKYPENAME: case IDC_GROUP: case IDC_PASSWORD: if ((HWND)lParam == GetFocus()) @@ -46,9 +46,9 @@ INT_PTR CSkypeProto::MainOptionsProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM case WM_NOTIFY: if (((NMHDR*)lParam)->code == PSN_APPLY) { - char login[32]; - GetDlgItemTextA(hwnd, IDC_LOGIN, login, SIZEOF(login)); - proto->setString(SKYPE_SETTINGS_ID, login); + char skypename[32]; + GetDlgItemTextA(hwnd, IDC_SKYPENAME, skypename, SIZEOF(skypename)); + proto->setString(SKYPE_SETTINGS_ID, skypename); char password[20]; GetDlgItemTextA(hwnd, IDC_PASSWORD, password, SIZEOF(password)); diff --git a/protocols/SkypeWeb/src/skype_proto.cpp b/protocols/SkypeWeb/src/skype_proto.cpp index 1eddc4c2b8..4efd89426d 100644 --- a/protocols/SkypeWeb/src/skype_proto.cpp +++ b/protocols/SkypeWeb/src/skype_proto.cpp @@ -37,7 +37,7 @@ DWORD_PTR CSkypeProto::GetCaps(int type, MCONTACT) case PFLAGNUM_3: return PF2_ONLINE; case PFLAG_UNIQUEIDTEXT: - return (INT_PTR)"Login"; + return (INT_PTR)"Skypename"; case PFLAG_UNIQUEIDSETTING: return (DWORD_PTR)SKYPE_SETTINGS_ID; } @@ -135,7 +135,7 @@ int CSkypeProto::SetStatus(int iNewStatus) m_iStatus = ID_STATUS_CONNECTING; requestQueue->Start(); - PushRequest(new LoginRequest(), HttpResponse<&CSkypeProto::OnLoginFirst>, this); + PushRequest(new LoginRequest(), &CSkypeProto::OnLoginFirst); } else { diff --git a/protocols/SkypeWeb/src/skype_proto.h b/protocols/SkypeWeb/src/skype_proto.h index b704bd4133..286e562ab7 100644 --- a/protocols/SkypeWeb/src/skype_proto.h +++ b/protocols/SkypeWeb/src/skype_proto.h @@ -1,7 +1,7 @@ #ifndef _TOX_PROTO_H_ #define _TOX_PROTO_H_ -class RequestQueueItem; +typedef void(CSkypeProto::*SkypeResponseCallback)(const NETLIBHTTPREQUEST *response); struct CSkypeProto : public PROTO < CSkypeProto > { @@ -93,31 +93,8 @@ private: INT_PTR __cdecl OnAccountManagerInit(WPARAM, LPARAM); - // api response wrappers - template - static void HttpResponse(const NETLIBHTTPREQUEST *response, void *arg) - { - (((CSkypeProto*)arg)->*ResponseCallback)(response); - } - - template - static void JsonResponse(const NETLIBHTTPREQUEST *response, void *arg) - { - JSONROOT root(response->pData); - (((CSkypeProto*)arg)->*ResponseCallback)(root); - } - - void PushRequest(HttpRequest *request, HttpResponseCallback response = NULL, void *arg = NULL) - { - if (!cookies.empty()) - { - CMStringA allCookies; - for (std::map::iterator cookie = cookies.begin(); cookie != cookies.end(); ++cookie) - allCookies.AppendFormat("%s=%s; ", cookie->first.c_str(), cookie->second.c_str()); - request->SetCookie(allCookies); - } - requestQueue->Push(request, response, arg); - } + // requests + void PushRequest(HttpRequest *request, SkypeResponseCallback response = NULL); // icons static IconInfo Icons[]; @@ -146,13 +123,13 @@ private: void SetContactStatus(MCONTACT hContact, WORD status); void SetAllContactsStatus(WORD status); - MCONTACT GetContact(const char *login); + MCONTACT GetContact(const char *skypename); - MCONTACT AddContact(const char *login, bool isTemporary = false); + MCONTACT AddContact(const char *skypename, bool isTemporary = false); MCONTACT GetContactFromAuthEvent(MEVENT hEvent); - void __cdecl LoadFriendList(void*); + void LoadContacts(const NETLIBHTTPREQUEST *response); INT_PTR __cdecl OnRequestAuth(WPARAM hContact, LPARAM lParam); INT_PTR __cdecl OnGrantAuth(WPARAM hContact, LPARAM); diff --git a/protocols/SkypeWeb/src/skype_request.cpp b/protocols/SkypeWeb/src/skype_request.cpp new file mode 100644 index 0000000000..1cd5d654f0 --- /dev/null +++ b/protocols/SkypeWeb/src/skype_request.cpp @@ -0,0 +1,42 @@ +#include "common.h" + +class SkypeResponseDelegate +{ +private: + CSkypeProto *proto; + SkypeResponseCallback responseCallback; + +public: + SkypeResponseDelegate(CSkypeProto *proto, SkypeResponseCallback responseCallback) + : proto(proto), responseCallback(responseCallback) { } + + void Invoke(const NETLIBHTTPREQUEST *response) + { + (proto->*(responseCallback))(response); + } +}; + +static void SkypeHttpResponse(const NETLIBHTTPREQUEST *response, void *arg) +{ + ((SkypeResponseDelegate*)arg)->Invoke(response); +} + +void CSkypeProto::PushRequest(HttpRequest *request, SkypeResponseCallback response) +{ + if (!cookies.empty()) + { + CMStringA allCookies; + for (std::map::iterator cookie = cookies.begin(); cookie != cookies.end(); ++cookie) + allCookies.AppendFormat("%s=%s; ", cookie->first.c_str(), cookie->second.c_str()); + request->SetCookie(allCookies); + } + + if (response == NULL) + { + requestQueue->Push(request); + return; + } + + SkypeResponseDelegate *delegate = new SkypeResponseDelegate(this, response); + requestQueue->Push(request, SkypeHttpResponse, delegate); +} \ No newline at end of file -- cgit v1.2.3