From a7f77b72a8e11b0b22d030479e3365885aca517a Mon Sep 17 00:00:00 2001 From: Jan Kaluza Date: Thu, 2 Jun 2011 09:54:57 +0200 Subject: [PATCH] Working VCards --- backends/libpurple/main.cpp | 97 ++++++++++++++++++++++++- include/transport/networkplugin.h | 4 + include/transport/networkpluginserver.h | 1 + src/networkplugin.cpp | 29 ++++++++ src/networkpluginserver.cpp | 19 +++++ src/vcardresponder.cpp | 9 ++- 6 files changed, 155 insertions(+), 4 deletions(-) diff --git a/backends/libpurple/main.cpp b/backends/libpurple/main.cpp index 1eb2c06d..e61c9743 100644 --- a/backends/libpurple/main.cpp +++ b/backends/libpurple/main.cpp @@ -118,8 +118,17 @@ class SpectrumNetworkPlugin : public NetworkPlugin { } } + virtual void handleVCardRequest(const std::string &user, const std::string &legacyName, unsigned int id) { + PurpleAccount *account = m_sessions[user]; + if (account) { + serv_get_info(purple_account_get_connection(account), legacyName.c_str()); + m_vcards[user + legacyName] = id; + } + } + std::map m_sessions; std::map m_accounts; + std::map m_vcards; private: Config *config; }; @@ -344,11 +353,97 @@ static PurpleConnectionUiOps conn_ui_ops = NULL }; +static void *notify_user_info(PurpleConnection *gc, const char *who, PurpleNotifyUserInfo *user_info) { + std::string name(who); + PurpleAccount *account = purple_connection_get_account(gc); + GList *vcardEntries = purple_notify_user_info_get_entries(user_info); + PurpleNotifyUserInfoEntry *vcardEntry; + std::string firstName; + std::string lastName; + std::string fullName; + std::string nickname; + std::string header; + std::string label; + Swift::ByteArray photo; + + while (vcardEntries) { + vcardEntry = (PurpleNotifyUserInfoEntry *)(vcardEntries->data); + if (purple_notify_user_info_entry_get_label(vcardEntry) && purple_notify_user_info_entry_get_value(vcardEntry)){ + label = purple_notify_user_info_entry_get_label(vcardEntry); + if (label == "Given Name"){ + firstName = purple_notify_user_info_entry_get_value(vcardEntry); + } + else if (label == "Family Name"){ + lastName = purple_notify_user_info_entry_get_value(vcardEntry); + } + else if (label=="Nickname"){ + nickname = purple_notify_user_info_entry_get_value(vcardEntry); + } + else if (label=="Full Name"){ + fullName = purple_notify_user_info_entry_get_value(vcardEntry); + } + } + vcardEntries = vcardEntries->next; + } + + if ((!firstName.empty() || !lastName.empty()) && fullName.empty()) + fullName = firstName + " " + lastName; + + PurpleBuddy *buddy = purple_find_buddy(purple_connection_get_account(gc), who); + if (buddy) { + gsize len; + PurpleBuddyIcon *icon = NULL; + icon = purple_buddy_icons_find(purple_connection_get_account(gc), name.c_str()); + if (icon) { + const gchar * data = (gchar*)purple_buddy_icon_get_data(icon, &len); + // Sometimes libpurple returns really broken pointers here + // They weren't able to do anything with that and I don't know what to do too, + // so it's better to hack through it by not trying to forward really broken things... + if (len < 300000 && data) { + photo = Swift::ByteArray(data, len); +// const gchar *ext = (gchar*)purple_buddy_icon_get_extension(icon); +// if (ext) { +// std::string extension(ext); +// if (extension != "icon") { +// if (extension == "jpg") { +// extension = "jpeg"; +// } +// photo->addChild( new Tag("TYPE", "image/" + extension) ); +// } +// } + } + } + } + + + np->handleVCard(np->m_accounts[account], np->m_vcards[np->m_accounts[account] + name], name, fullName, nickname, photo.toString()); + np->m_vcards.erase(np->m_accounts[account] + name); + + return NULL; +} + +static PurpleNotifyUiOps notifyUiOps = +{ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + notify_user_info, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL +}; + static void transport_core_ui_init(void) { purple_blist_set_ui_ops(&blistUiOps); // purple_accounts_set_ui_ops(&accountUiOps); -// purple_notify_set_ui_ops(¬ifyUiOps); + purple_notify_set_ui_ops(¬ifyUiOps); // purple_request_set_ui_ops(&requestUiOps); // purple_xfers_set_ui_ops(getXferUiOps()); purple_connections_set_ui_ops(&conn_ui_ops); diff --git a/include/transport/networkplugin.h b/include/transport/networkplugin.h index 291d5d37..025f9a3c 100644 --- a/include/transport/networkplugin.h +++ b/include/transport/networkplugin.h @@ -54,9 +54,12 @@ class NetworkPlugin { void handleRoomChanged(const std::string &user, const std::string &room, const std::string &nickname); + void handleVCard(const std::string &user, unsigned int id, const std::string &legacyName, const std::string &fullName, const std::string &nickname, const std::string &photo); + virtual void handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password) = 0; virtual void handleLogoutRequest(const std::string &user, const std::string &legacyName) = 0; virtual void handleMessageSendRequest(const std::string &user, const std::string &legacyName, const std::string &message) = 0; + virtual void handleVCardRequest(const std::string &/*user*/, const std::string &/*legacyName*/, unsigned int /*id*/) {} virtual void handleJoinRoomRequest(const std::string &/*user*/, const std::string &/*room*/, const std::string &/*nickname*/, const std::string &/*pasword*/) {} virtual void handleLeaveRoomRequest(const std::string &/*user*/, const std::string &/*room*/) {} @@ -68,6 +71,7 @@ class NetworkPlugin { void handleConvMessagePayload(const std::string &payload); void handleJoinRoomPayload(const std::string &payload); void handleLeaveRoomPayload(const std::string &payload); + void handleVCardPayload(const std::string &payload); void handleDataRead(const Swift::ByteArray&); void handleConnected(bool error); void handleDisconnected(); diff --git a/include/transport/networkpluginserver.h b/include/transport/networkpluginserver.h index d8a3e843..40fd8087 100644 --- a/include/transport/networkpluginserver.h +++ b/include/transport/networkpluginserver.h @@ -65,6 +65,7 @@ class NetworkPluginServer { void handleConvMessagePayload(const std::string &payload, bool subject = false); void handleParticipantChangedPayload(const std::string &payload); void handleRoomChangedPayload(const std::string &payload); + void handleVCardPayload(const std::string &payload); void handleUserCreated(User *user); void handleRoomJoined(User *user, const std::string &room, const std::string &nickname, const std::string &password); diff --git a/src/networkplugin.cpp b/src/networkplugin.cpp index 947bfd2d..d25f60b1 100644 --- a/src/networkplugin.cpp +++ b/src/networkplugin.cpp @@ -72,6 +72,22 @@ void NetworkPlugin::handleMessage(const std::string &user, const std::string &le send(message); } +void NetworkPlugin::handleVCard(const std::string &user, unsigned int id, const std::string &legacyName, const std::string &fullName, const std::string &nickname, const std::string &photo) { + pbnetwork::VCard vcard; + vcard.set_username(user); + vcard.set_buddyname(legacyName); + vcard.set_id(id); + vcard.set_fullname(fullName); + vcard.set_nickname(nickname); + vcard.set_photo(photo); + + std::string message; + vcard.SerializeToString(&message); + + WRAP(message, pbnetwork::WrapperMessage_Type_TYPE_VCARD); + send(message); +} + void NetworkPlugin::handleSubject(const std::string &user, const std::string &legacyName, const std::string &msg, const std::string &nickname) { pbnetwork::ConversationMessage m; m.set_username(user); @@ -226,6 +242,16 @@ void NetworkPlugin::handleLeaveRoomPayload(const std::string &data) { handleLeaveRoomRequest(payload.username(), payload.room()); } +void NetworkPlugin::handleVCardPayload(const std::string &data) { + pbnetwork::VCard payload; + if (payload.ParseFromString(data) == false) { + // TODO: ERROR + return; + } + + handleVCardRequest(payload.username(), payload.buddyname(), payload.id()); +} + void NetworkPlugin::handleDataRead(const Swift::ByteArray &data) { long expected_size = 0; m_data += data.toString(); @@ -269,6 +295,9 @@ void NetworkPlugin::handleDataRead(const Swift::ByteArray &data) { case pbnetwork::WrapperMessage_Type_TYPE_LEAVE_ROOM: handleLeaveRoomPayload(wrapper.payload()); break; + case pbnetwork::WrapperMessage_Type_TYPE_VCARD: + handleVCardPayload(wrapper.payload()); + break; default: return; } diff --git a/src/networkpluginserver.cpp b/src/networkpluginserver.cpp index e3a825ac..42aaf9b8 100644 --- a/src/networkpluginserver.cpp +++ b/src/networkpluginserver.cpp @@ -191,6 +191,22 @@ void NetworkPluginServer::handleDisconnectedPayload(const std::string &data) { user->handleDisconnected(payload.message()); } +void NetworkPluginServer::handleVCardPayload(const std::string &data) { + pbnetwork::VCard payload; + if (payload.ParseFromString(data) == false) { + std::cout << "PARSING ERROR\n"; + // TODO: ERROR + return; + } + std::cout << "OMG?\n"; + boost::shared_ptr vcard(new Swift::VCard()); + vcard->setFullName(payload.fullname()); + vcard->setPhoto(Swift::ByteArray(payload.photo())); + vcard->setNickname(payload.nickname()); + + m_vcardResponder->sendVCard(payload.id(), vcard); +} + void NetworkPluginServer::handleBuddyChangedPayload(const std::string &data) { pbnetwork::Buddy payload; if (payload.ParseFromString(data) == false) { @@ -343,6 +359,9 @@ void NetworkPluginServer::handleDataRead(Client *c, const Swift::ByteArray &data case pbnetwork::WrapperMessage_Type_TYPE_ROOM_NICKNAME_CHANGED: handleRoomChangedPayload(wrapper.payload()); break; + case pbnetwork::WrapperMessage_Type_TYPE_VCARD: + handleVCardPayload(wrapper.payload()); + break; default: return; } diff --git a/src/vcardresponder.cpp b/src/vcardresponder.cpp index c65603fa..72e820c4 100644 --- a/src/vcardresponder.cpp +++ b/src/vcardresponder.cpp @@ -42,10 +42,13 @@ VCardResponder::~VCardResponder() { } void VCardResponder::sendVCard(unsigned int id, boost::shared_ptr vcard) { - if (m_queries.find(id) == m_queries.end()) + std::cout << "RECEIVED VCARD FROM BACKEND\n"; + if (m_queries.find(id) == m_queries.end()) { + std::cout << "ERROR\n"; return; - - sendResponse(m_queries[id].to, m_queries[id].from, m_queries[id].id, vcard); + } + std::cout << "SENT " << m_queries[id].to << " " << m_queries[id].from << " " << m_queries[id].id << "\n"; + sendResponse(m_queries[id].from, m_queries[id].to, m_queries[id].id, vcard); m_queries.erase(id); }