From 347b63f23b40b403470d9636d691337cf8713e54 Mon Sep 17 00:00:00 2001 From: Alexander Lantsev Date: Thu, 19 Mar 2015 22:01:53 +0000 Subject: SkypeWeb: - added own info reading - refactored contact info reading git-svn-id: http://svn.miranda-ng.org/main/trunk@12437 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/SkypeWeb/SkypeWeb_12.vcxproj | 3 +- protocols/SkypeWeb/SkypeWeb_12.vcxproj.filters | 5 +- protocols/SkypeWeb/src/common.h | 2 +- protocols/SkypeWeb/src/requests/contacts.h | 27 ++- protocols/SkypeWeb/src/requests/profile.h | 17 ++ protocols/SkypeWeb/src/requests/profiles.h | 27 --- protocols/SkypeWeb/src/skype_contacts.cpp | 94 +++------- protocols/SkypeWeb/src/skype_events.cpp | 3 +- protocols/SkypeWeb/src/skype_profile.cpp | 226 +++++++++++++++++++++++++ protocols/SkypeWeb/src/skype_proto.h | 26 ++- 10 files changed, 325 insertions(+), 105 deletions(-) create mode 100644 protocols/SkypeWeb/src/requests/profile.h delete mode 100644 protocols/SkypeWeb/src/requests/profiles.h create mode 100644 protocols/SkypeWeb/src/skype_profile.cpp (limited to 'protocols') diff --git a/protocols/SkypeWeb/SkypeWeb_12.vcxproj b/protocols/SkypeWeb/SkypeWeb_12.vcxproj index a67cf6a78a..d24592227f 100644 --- a/protocols/SkypeWeb/SkypeWeb_12.vcxproj +++ b/protocols/SkypeWeb/SkypeWeb_12.vcxproj @@ -206,7 +206,7 @@ - + @@ -217,6 +217,7 @@ + Create diff --git a/protocols/SkypeWeb/SkypeWeb_12.vcxproj.filters b/protocols/SkypeWeb/SkypeWeb_12.vcxproj.filters index 3d9cbab39c..8d6e04a255 100644 --- a/protocols/SkypeWeb/SkypeWeb_12.vcxproj.filters +++ b/protocols/SkypeWeb/SkypeWeb_12.vcxproj.filters @@ -51,7 +51,7 @@ Header Files\requests - + Header Files\requests @@ -95,6 +95,9 @@ Source Files + + Source Files + diff --git a/protocols/SkypeWeb/src/common.h b/protocols/SkypeWeb/src/common.h index 41012c2a6d..7c980f3620 100644 --- a/protocols/SkypeWeb/src/common.h +++ b/protocols/SkypeWeb/src/common.h @@ -45,8 +45,8 @@ struct CSkypeProto; #include "http_request.h" #include "requests\login.h" #include "requests\logout.h" +#include "requests\profile.h" #include "requests\contacts.h" -#include "requests\profiles.h" #include "request_queue.h" #include "skype_proto.h" diff --git a/protocols/SkypeWeb/src/requests/contacts.h b/protocols/SkypeWeb/src/requests/contacts.h index 5144de597a..2aec30499f 100644 --- a/protocols/SkypeWeb/src/requests/contacts.h +++ b/protocols/SkypeWeb/src/requests/contacts.h @@ -1,10 +1,10 @@ #ifndef _SKYPE_REQUEST_CONTACTS_H_ #define _SKYPE_REQUEST_CONTACTS_H_ -class GetContactsRequest : public HttpRequest +class GetContactListRequest : public HttpRequest { public: - GetContactsRequest(const char *token) : + GetContactListRequest(const char *token) : HttpRequest(REQUEST_GET, "api.skype.com/users/self/contacts?hideDetails=true") { flags |= NLHRF_SSL; @@ -14,4 +14,27 @@ public: } }; +class GetContactsInfoRequest : public HttpRequest +{ +public: + GetContactsInfoRequest(const char *token, const LIST &skypenames) : + HttpRequest(REQUEST_POST, "api.skype.com/users/self/contacts/profiles") + { + flags |= NLHRF_SSL; + + CMStringA data; + for (size_t i = 0; i < skypenames.getCount(); i++) + { + data.AppendFormat("contacts[]=%s&", skypenames[i]); + } + data.Delete(data.GetLength() - 1); + + SetData(data, data.GetLength()); + + AddHeader("X-Skypetoken", token); + AddHeader("Accept", "application/json"); + AddHeader("Content-Type", "application/x-www-form-urlencoded"); + } +}; + #endif //_SKYPE_REQUEST_CONTACTS_H_ diff --git a/protocols/SkypeWeb/src/requests/profile.h b/protocols/SkypeWeb/src/requests/profile.h new file mode 100644 index 0000000000..4d6fd94789 --- /dev/null +++ b/protocols/SkypeWeb/src/requests/profile.h @@ -0,0 +1,17 @@ +#ifndef _SKYPE_REQUEST_PROFILE_H_ +#define _SKYPE_REQUEST_PROFILE_H_ + +class GetProfileRequest : public HttpRequest +{ +public: + GetProfileRequest(const char *token) : + HttpRequest(REQUEST_GET, "api.skype.com/users/self/profile") + { + flags |= NLHRF_SSL; + + AddHeader("X-Skypetoken", token); + AddHeader("Accept", "application/json"); + } +}; + +#endif //_SKYPE_REQUEST_PROFILE_H_ diff --git a/protocols/SkypeWeb/src/requests/profiles.h b/protocols/SkypeWeb/src/requests/profiles.h deleted file mode 100644 index 564ee92b7f..0000000000 --- a/protocols/SkypeWeb/src/requests/profiles.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef _SKYPE_REQUEST_PROFILES_H_ -#define _SKYPE_REQUEST_PROFILES_H_ - -class GetProfilesRequest : public HttpRequest -{ -public: - GetProfilesRequest(const char *token, const LIST &skypenames) : - HttpRequest(REQUEST_POST, "api.skype.com//users/self/contacts/profiles") - { - flags |= NLHRF_SSL; - - CMStringA data; - for (size_t i = 0; i < skypenames.getCount(); i++) - { - data.AppendFormat("contacts[]=%s&", skypenames[i]); - } - data.Delete(data.GetLength() - 1); - - SetData(data, data.GetLength()); - - AddHeader("X-Skypetoken", token); - AddHeader("Accept", "application/json"); - AddHeader("Content-Type", "application/x-www-form-urlencoded"); - } -}; - -#endif //_SKYPE_REQUEST_PROFILES_H_ diff --git a/protocols/SkypeWeb/src/skype_contacts.cpp b/protocols/SkypeWeb/src/skype_contacts.cpp index f403c462e5..e0b8fc1722 100644 --- a/protocols/SkypeWeb/src/skype_contacts.cpp +++ b/protocols/SkypeWeb/src/skype_contacts.cpp @@ -83,21 +83,21 @@ MCONTACT CSkypeProto::AddContact(const char *skypename, bool isTemporary) return hContact; } -//[{ "username":"echo123", "firstname" : "Echo \/ Sound Test Service", "lastname" : null, "avatarUrl" : null, "mood" : null, "richMood" : null, "displayname" : null, "country" : null, "city" : null },...] -void CSkypeProto::LoadProfiles(const NETLIBHTTPREQUEST *response) +//[{"username":"echo123", "firstname" : "Echo \/ Sound Test Service", "lastname" : null, "avatarUrl" : null, "mood" : null, "richMood" : null, "displayname" : null, "country" : null, "city" : null},...] +void CSkypeProto::LoadContactsInfo(const NETLIBHTTPREQUEST *response) { if (response == NULL) return; - JSONROOT root(response->pData); - if (root == NULL) + 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) + for (size_t i = 0; i < json_size(items); i++) + { + item = json_at(items, i); + if (item == NULL) break; node = json_get(item, "username"); @@ -105,83 +105,37 @@ void CSkypeProto::LoadProfiles(const NETLIBHTTPREQUEST *response) MCONTACT hContact = AddContact(skypename); 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 - delSetting(hContact, "Nick"); - - node = json_get(item, "avatarUrl"); - CMStringA avatarUrl = mir_t2a(ptrT(json_as_string(node))); - if (avatarUrl && avatarUrl != "null") - ; // TODO: load avatar - - node = json_get(item, "mood"); - CMString mood = ptrT(json_as_string(node)); - if (!mood.IsEmpty() && mood != "null") - db_set_ts(hContact, "CList", "StatusMsg", mood); - else - db_unset(hContact, "CList", "StatusMsg"); - - node = json_get(item, "richMood"); - ptrT richMood(json_as_string(node)); - - node = json_get(item, "country"); - ptrA country(mir_t2a(ptrT(json_as_string(node)))); - - node = json_get(item, "city"); - CMString city = ptrT(json_as_string(node)); - if (!city.IsEmpty() && city != "null") - setTString(hContact, "City", city); - else - delSetting(hContact, "City"); + UpdateProfileFirstName(item, hContact); + UpdateProfileLastName(item, hContact); + UpdateProfileDisplayName(item, hContact); + UpdateProfileCountry(item, hContact); + UpdateProfileCity(item, hContact); + UpdateProfileStatusMessage(item, hContact); + //richMood + UpdateProfileAvatar(item, hContact); } - } json_delete(items); } //[{"skypename":"echo123", "authorized" : true, "blocked" : false, ...},...] // other properties is exists but empty -void CSkypeProto::LoadContacts(const NETLIBHTTPREQUEST *response) +void CSkypeProto::LoadContactList(const NETLIBHTTPREQUEST *response) { if (response == NULL) return; - JSONROOT root(response->pData); - if (root == NULL) + JSONROOT root(response->pData); + if (root == NULL) return; LIST skypenames(1); 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) + for (size_t i = 0; i < json_size(items); i++) + { + item = json_at(items, i); + if (item == NULL) break; node = json_get(item, "skypename"); @@ -211,7 +165,7 @@ void CSkypeProto::LoadContacts(const NETLIBHTTPREQUEST *response) if (skypenames.getCount() > 0) { ptrA token(getStringA("TokenSecret")); - PushRequest(new GetProfilesRequest(token, skypenames), &CSkypeProto::LoadProfiles); + PushRequest(new GetContactsInfoRequest(token, skypenames), &CSkypeProto::LoadContactsInfo); for (size_t i = 0; i < skypenames.getCount(); i++) { diff --git a/protocols/SkypeWeb/src/skype_events.cpp b/protocols/SkypeWeb/src/skype_events.cpp index d45c344b4b..5139642270 100644 --- a/protocols/SkypeWeb/src/skype_events.cpp +++ b/protocols/SkypeWeb/src/skype_events.cpp @@ -89,7 +89,8 @@ void CSkypeProto::OnLoginSecond(const NETLIBHTTPREQUEST *response) cookies[match[1]] = match[2]; } - PushRequest(new GetContactsRequest(token.c_str()), &CSkypeProto::LoadContacts); + PushRequest(new GetProfileRequest(token.c_str()), &CSkypeProto::LoadProfile); + PushRequest(new GetContactListRequest(token.c_str()), &CSkypeProto::LoadContactList); 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_profile.cpp b/protocols/SkypeWeb/src/skype_profile.cpp new file mode 100644 index 0000000000..85c72423f5 --- /dev/null +++ b/protocols/SkypeWeb/src/skype_profile.cpp @@ -0,0 +1,226 @@ +#include "common.h" + +void CSkypeProto::UpdateProfileFirstName(JSONNODE *root, MCONTACT hContact) +{ + JSONNODE *node = json_get(root, "firstname"); + CMString firstname = ptrT(json_as_string(node)); + if (!firstname.IsEmpty() && firstname != "null") + setTString(hContact, "FirstName", firstname); + else + delSetting(hContact, "FirstName"); +} + +void CSkypeProto::UpdateProfileLastName(JSONNODE *root, MCONTACT hContact) +{ + JSONNODE *node = json_get(root, "lastname"); + CMString lastname = ptrT(json_as_string(node)); + if (!lastname.IsEmpty() && lastname != "null") + setTString(hContact, "LastName", lastname); + else + delSetting(hContact, "LastName"); +} + +void CSkypeProto::UpdateProfileDisplayName(JSONNODE *root, MCONTACT hContact) +{ + JSONNODE *node = json_get(root, "displayname"); + CMString displayname = ptrT(json_as_string(node)); + if (!displayname.IsEmpty() && displayname != "null") + setTString(hContact, "Nick", displayname); + else + delSetting(hContact, "Nick"); +} + +void CSkypeProto::UpdateProfileGender(JSONNODE *root, MCONTACT hContact) +{ + JSONNODE *node = json_get(root, "gender"); + int value = json_as_int(node); + if (value) + setByte(hContact, "Gender", (BYTE)(value == 1 ? 'M' : 'F')); + else + delSetting(hContact, "Gender"); +} + +void CSkypeProto::UpdateProfileBirthday(JSONNODE *root, MCONTACT hContact) +{ + JSONNODE *node = json_get(root, "birthday"); + // parse "YYYY-MM-DD" +} + +void CSkypeProto::UpdateProfileCountry(JSONNODE *root, MCONTACT hContact) +{ + JSONNODE *node = json_get(root, "country"); + CMStringA isocode = mir_t2a(ptrT(json_as_string(node))); + if (!isocode.IsEmpty() && isocode != "null") + { + char *country = (char *)CallService(MS_UTILS_GETCOUNTRYBYISOCODE, (WPARAM)(char*)isocode.GetBuffer(), 0); + setTString(hContact, "Country", _A2T(country)); + } + else + delSetting(hContact, "Country"); +} + +void CSkypeProto::UpdateProfileState(JSONNODE *root, MCONTACT hContact) +{ + JSONNODE *node = json_get(root, "province"); + CMString province = mir_t2a(ptrT(json_as_string(node))); + if (!province.IsEmpty() && province != "null") + setTString(hContact, "State", province); + else + delSetting(hContact, "State"); +} + +void CSkypeProto::UpdateProfileCity(JSONNODE *root, MCONTACT hContact) +{ + JSONNODE *node = json_get(root, "city"); + CMString city = ptrT(json_as_string(node)); + if (!city.IsEmpty() && city != "null") + setTString(hContact, "City", city); + else + delSetting(hContact, "City"); +} + +void CSkypeProto::UpdateProfileLanguage(JSONNODE *root, MCONTACT hContact) +{ + JSONNODE *node = json_get(root, "language"); + CMStringA isocode = mir_t2a(ptrT(json_as_string(node))); + if (!isocode.IsEmpty() && isocode != "null") + { + // convert language code to language name + } + else + delSetting(hContact, "Language0"); +} + +void CSkypeProto::UpdateProfileHomepage(JSONNODE *root, MCONTACT hContact) +{ + JSONNODE *node = json_get(root, "homepage"); + CMString homepage = ptrT(json_as_string(node)); + if (!homepage.IsEmpty() && homepage != "null") + setTString(hContact, "Homepage", homepage); + else + delSetting(hContact, "Homepage"); +} + +void CSkypeProto::UpdateProfileAbout(JSONNODE *root, MCONTACT hContact) +{ + JSONNODE *node = json_get(root, "about"); + CMString about = ptrT(json_as_string(node)); + if (!about.IsEmpty() && about != "null") + setTString(hContact, "About", about); + else + delSetting(hContact, "About"); +} + +void CSkypeProto::UpdateProfileEmails(JSONNODE *root, MCONTACT hContact) +{ + JSONNODE *node = json_get(root, "emails"); + if (!json_empty(node)) + { + JSONNODE *items = json_as_array(root), *item; + for (size_t i = 0; i < min(json_size(items), 3); i++) + { + item = json_at(items, i); + if (item == NULL) + break; + + // how to read array of string? + //CMStringA name(FORMAT, "e-mail%d", i); + //CMString value = ptrT(json_as_string(item)); + //setTString(hContact, name, value); + } + json_delete(items); + } + else + { + delSetting(hContact, "e-mail0"); + delSetting(hContact, "e-mail1"); + delSetting(hContact, "e-mail2"); + } +} + +void CSkypeProto::UpdateProfilePhoneMobile(JSONNODE *root, MCONTACT hContact) +{ + JSONNODE *node = json_get(root, "phoneMobile"); + CMString province = mir_t2a(ptrT(json_as_string(node))); + if (!province.IsEmpty() && province != "null") + setTString(hContact, "Cellular", province); + else + delSetting(hContact, "Cellular"); +} + +void CSkypeProto::UpdateProfilePhoneHome(JSONNODE *root, MCONTACT hContact) +{ + JSONNODE *node = json_get(root, "phone"); + CMString province = mir_t2a(ptrT(json_as_string(node))); + if (!province.IsEmpty() && province != "null") + setTString(hContact, "Phone", province); + else + delSetting(hContact, "Phone"); +} + +void CSkypeProto::UpdateProfilePhoneOffice(JSONNODE *root, MCONTACT hContact) +{ + JSONNODE *node = json_get(root, "phoneOffice"); + CMString province = mir_t2a(ptrT(json_as_string(node))); + if (!province.IsEmpty() && province != "null") + setTString(hContact, "CompanyPhone", province); + else + delSetting(hContact, "CompanyPhone"); +} + +void CSkypeProto::UpdateProfileStatusMessage(JSONNODE *root, MCONTACT hContact) +{ + JSONNODE *node = json_get(root, "mood"); + CMString province = mir_t2a(ptrT(json_as_string(node))); + if (!province.IsEmpty() && province != "null") + setTString(hContact, "StatusMsg", province); + else + delSetting(hContact, "StatusMsg"); +} + +void CSkypeProto::UpdateProfileXStatusMessage(JSONNODE *root, MCONTACT hContact) +{ + JSONNODE *node = json_get(root, "richMood"); + CMString province = mir_t2a(ptrT(json_as_string(node))); + if (!province.IsEmpty() && province != "null") + setTString(hContact, "XStatusMsg", province); + else + delSetting(hContact, "XStatusMsg"); +} + +void CSkypeProto::UpdateProfileAvatar(JSONNODE *root, MCONTACT hContact) +{ + JSONNODE *node = json_get(root, "avatarUrl"); + // add avatar support +} + +//{"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"} +void CSkypeProto::LoadProfile(const NETLIBHTTPREQUEST *response) +{ + if (response == NULL) + return; + + JSONROOT root(response->pData); + if (root == NULL) + return; + + UpdateProfileFirstName(root); + UpdateProfileLastName(root); + UpdateProfileDisplayName(root); + UpdateProfileGender(root); + UpdateProfileBirthday(root); + UpdateProfileCountry(root); + UpdateProfileState(root); + UpdateProfileCity(root); + UpdateProfileLanguage(root); + UpdateProfileHomepage(root); + UpdateProfileAbout(root); + //jobtitle + UpdateProfileEmails(root); + UpdateProfilePhoneMobile(root); + UpdateProfilePhoneHome(root); + UpdateProfilePhoneOffice(root); + UpdateProfileStatusMessage(root); + //richMood + UpdateProfileAvatar(root); +} \ No newline at end of file diff --git a/protocols/SkypeWeb/src/skype_proto.h b/protocols/SkypeWeb/src/skype_proto.h index a94fa3ae6a..8e963de84e 100644 --- a/protocols/SkypeWeb/src/skype_proto.h +++ b/protocols/SkypeWeb/src/skype_proto.h @@ -118,6 +118,28 @@ private: void OnLoginSecond(const NETLIBHTTPREQUEST *response); + // profile + void UpdateProfileFirstName(JSONNODE *root, MCONTACT hContact = NULL); + void UpdateProfileLastName(JSONNODE *root, MCONTACT hContact = NULL); + void UpdateProfileDisplayName(JSONNODE *root, MCONTACT hContact = NULL); + void UpdateProfileGender(JSONNODE *root, MCONTACT hContact = NULL); + void UpdateProfileBirthday(JSONNODE *root, MCONTACT hContact = NULL); + void UpdateProfileCountry(JSONNODE *node, MCONTACT hContact = NULL); + void UpdateProfileState(JSONNODE *node, MCONTACT hContact = NULL); + void UpdateProfileCity(JSONNODE *node, MCONTACT hContact = NULL); + void UpdateProfileLanguage(JSONNODE *root, MCONTACT hContact = NULL); + void UpdateProfileHomepage(JSONNODE *root, MCONTACT hContact = NULL); + void UpdateProfileAbout(JSONNODE *node, MCONTACT hContact = NULL); + void UpdateProfileEmails(JSONNODE *root, MCONTACT hContact = NULL); + void UpdateProfilePhoneMobile(JSONNODE *root, MCONTACT hContact = NULL); + void UpdateProfilePhoneHome(JSONNODE *root, MCONTACT hContact = NULL); + void UpdateProfilePhoneOffice(JSONNODE *root, MCONTACT hContact = NULL); + void UpdateProfileStatusMessage(JSONNODE *root, MCONTACT hContact = NULL); + void UpdateProfileXStatusMessage(JSONNODE *root, MCONTACT hContact = NULL); + void UpdateProfileAvatar(JSONNODE *root, MCONTACT hContact = NULL); + + void LoadProfile(const NETLIBHTTPREQUEST *response); + // contacts WORD GetContactStatus(MCONTACT hContact); void SetContactStatus(MCONTACT hContact, WORD status); @@ -129,8 +151,8 @@ private: MCONTACT GetContactFromAuthEvent(MEVENT hEvent); - void LoadProfiles(const NETLIBHTTPREQUEST *response); - void LoadContacts(const NETLIBHTTPREQUEST *response); + void LoadContactsInfo(const NETLIBHTTPREQUEST *response); + void LoadContactList(const NETLIBHTTPREQUEST *response); INT_PTR __cdecl OnRequestAuth(WPARAM hContact, LPARAM lParam); INT_PTR __cdecl OnGrantAuth(WPARAM hContact, LPARAM); -- cgit v1.2.3