soc.2009.transport: 4cfb3e95: Added initial support for MSN (usernames...
hanzz at soc.pidgin.im
hanzz at soc.pidgin.im
Fri Jun 5 03:05:41 EDT 2009
-----------------------------------------------------------------
Revision: 4cfb3e95b4d7da08c5d2ba1af356d09d31f1d1c9
Ancestor: 72aae753d4a87754326c8b4683e549e8cba01171
Author: hanzz at soc.pidgin.im
Date: 2009-06-05T07:01:42
Branch: im.pidgin.soc.2009.transport
URL: http://d.pidgin.im/viewmtn/revision/info/4cfb3e95b4d7da08c5d2ba1af356d09d31f1d1c9
Added files:
protocols/msn.cpp protocols/msn.h
Modified files:
CMakeLists.txt adhochandler.cpp main.cpp main.h user.cpp
ChangeLog:
Added initial support for MSN (usernames with @ are properly translated to JID). Roster item exchange and chatting should work.
-------------- next part --------------
============================================================
--- protocols/msn.cpp 7579ee98fe809d9a021dd9d4087e8a4198453024
+++ protocols/msn.cpp 7579ee98fe809d9a021dd9d4087e8a4198453024
@@ -0,0 +1,82 @@
+/**
+ * XMPP - libpurple transport
+ *
+ * Copyright (C) 2009, Jan Kaluza <hanzz at soc.pidgin.im>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+ */
+
+#include "msn.h"
+#include "../main.h"
+
+MSNProtocol::MSNProtocol(GlooxMessageHandler *main){
+ m_main = main;
+ m_transportFeatures.push_back("jabber:iq:register");
+ m_transportFeatures.push_back("http://jabber.org/protocol/disco#info");
+ m_transportFeatures.push_back("http://jabber.org/protocol/caps");
+ m_transportFeatures.push_back("http://jabber.org/protocol/chatstates");
+// m_transportFeatures.push_back("http://jabber.org/protocol/activity+notify");
+ m_transportFeatures.push_back("http://jabber.org/protocol/commands");
+
+ m_buddyFeatures.push_back("http://jabber.org/protocol/disco#info");
+ m_buddyFeatures.push_back("http://jabber.org/protocol/caps");
+ m_buddyFeatures.push_back("http://jabber.org/protocol/chatstates");
+ m_buddyFeatures.push_back("http://jabber.org/protocol/commands");
+
+// m_buddyFeatures.push_back("http://jabber.org/protocol/si/profile/file-transfer");
+// m_buddyFeatures.push_back("http://jabber.org/protocol/bytestreams");
+// m_buddyFeatures.push_back("http://jabber.org/protocol/si");
+}
+
+MSNProtocol::~MSNProtocol() {}
+
+std::string MSNProtocol::replace(std::string &str, const char *string_to_replace, const char *new_string)
+{
+ // Find the first string to replace
+ int index = str.find(string_to_replace);
+ // while there is one
+ while(index != (int) std::string::npos)
+ {
+ // Replace it
+ str.replace(index, strlen(string_to_replace), new_string);
+ // Find the next one
+ index = str.find(string_to_replace, index + strlen(new_string));
+ }
+ return str;
+}
+
+std::string MSNProtocol::prepareUserName(std::string &str){
+ str = replace(str," ","");
+ return str;
+}
+
+bool MSNProtocol::isValidUsername(std::string &str){
+ // TODO: check valid email address
+ return true;
+}
+
+std::list<std::string> MSNProtocol::transportFeatures(){
+ return m_transportFeatures;
+}
+
+std::list<std::string> MSNProtocol::buddyFeatures(){
+ return m_buddyFeatures;
+}
+
+std::string MSNProtocol::text(const std::string &key) {
+ if (key == "instructions")
+ return "Enter your GG number and password:";
+ return "not defined";
+}
============================================================
--- protocols/msn.h 976f3ce4eb6c3988f7c1debeabb255c36e481ea5
+++ protocols/msn.h 976f3ce4eb6c3988f7c1debeabb255c36e481ea5
@@ -0,0 +1,52 @@
+/**
+ * XMPP - libpurple transport
+ *
+ * Copyright (C) 2009, Jan Kaluza <hanzz at soc.pidgin.im>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+ */
+
+#ifndef _HI_MSN_PROTOCOL_H
+#define _HI_MSN_PROTOCOL_H
+
+#include "abstractprotocol.h"
+
+class GlooxMessageHandler;
+
+class MSNProtocol : AbstractProtocol
+{
+ public:
+ MSNProtocol(GlooxMessageHandler *main);
+ ~MSNProtocol();
+ std::string gatewayIdentity() { return "msn"; }
+ std::string protocol() { return "prpl-msn"; }
+ bool isValidUsername(std::string &username);
+ std::string prepareUserName(std::string &username);
+ std::list<std::string> transportFeatures();
+ std::list<std::string> buddyFeatures();
+ std::string text(const std::string &key);
+ Tag *getVCardTag(User *user, GList *vcardEntries) { return NULL; }
+
+ std::string replace(std::string &str, const char *string_to_replace, const char *new_string);
+
+ private:
+ GlooxMessageHandler *m_main;
+ std::list<std::string> m_transportFeatures;
+ std::list<std::string> m_buddyFeatures;
+
+};
+
+#endif
+
\ No newline at end of file
============================================================
--- CMakeLists.txt 2264023d914ec1f31267c310e4d9fad4341c754d
+++ CMakeLists.txt b9e02ee4e08479cf3199baf70003bd19b124575e
@@ -92,6 +92,7 @@
protocols/icq.cpp
protocols/facebook.cpp
protocols/gg.cpp
+ protocols/msn.cpp
)
set(hiicq_MOC_HDRS
@@ -121,6 +122,7 @@
protocols/icq.h
protocols/facebook.h
protocols/gg.h
+ protocols/msn.h
)
add_executable(hiicq ${hiicq_SRCS} ${lrelease_outputs})
============================================================
--- adhochandler.cpp e1e945c79db049389c3cb10be8acdb65e73da830
+++ adhochandler.cpp bc806f593d320af689a21f791133d0e9e0e207d5
@@ -67,7 +67,7 @@ Disco::ItemList GlooxAdhocHandler::handl
for (l = actions; l != NULL; l = l->next) {
if (l->data) {
action = (PurplePluginAction *) l->data;
- lst.push_back( new Disco::Item( main->jid(), (std::string) action->label, (std::string) action->label ) );
+ lst.push_back( new Disco::Item( main->jid(), (std::string) tr(user->getLang(), action->label), (std::string) action->label ) );
purple_plugin_action_free(action);
}
}
@@ -79,6 +79,7 @@ Disco::ItemList GlooxAdhocHandler::handl
User *user = main->userManager()->getUserByJID(from);
if (user) {
if (user->isConnected() && purple_account_get_connection(user->account())) {
+ Log().Get("GlooxAdhocHandler") << user->getLang();
GList *l, *ll;
PurpleConnection *gc = purple_account_get_connection(user->account());
PurplePlugin *plugin = gc && PURPLE_CONNECTION_IS_CONNECTED(gc) ? gc->prpl : NULL;
@@ -86,12 +87,13 @@ Disco::ItemList GlooxAdhocHandler::handl
if(!prpl_info || !prpl_info->blist_node_menu)
return lst;
+ std::string name(JID(to).username());
+ std::for_each( name.begin(), name.end(), replaceJidCharacters() );
+ PurpleBuddy *buddy = purple_find_buddy(user->account(), name.c_str());
- PurpleBuddy *buddy = purple_find_buddy(user->account(), JID(to).username().c_str());
-
for(l = ll = prpl_info->blist_node_menu((PurpleBlistNode*)buddy); l; l = l->next) {
PurpleMenuAction *action = (PurpleMenuAction *) l->data;
- lst.push_back( new Disco::Item( _to.bare(), (std::string) action->label, (std::string) action->label ) );
+ lst.push_back( new Disco::Item( _to.bare(), (std::string) tr(user->getLang(), action->label), (std::string) action->label ) );
purple_menu_action_free(action);
}
}
@@ -156,7 +158,9 @@ bool GlooxAdhocHandler::handleIq( const
if(!prpl_info || !prpl_info->blist_node_menu)
return true;
- PurpleBuddy *buddy = purple_find_buddy(user->account(), JID(to).username().c_str());
+ std::string name(JID(to).username());
+ std::for_each( name.begin(), name.end(), replaceJidCharacters() );
+ PurpleBuddy *buddy = purple_find_buddy(user->account(), name.c_str());
for(l = ll = prpl_info->blist_node_menu((PurpleBlistNode*)buddy); l; l = l->next) {
PurpleMenuAction *action = (PurpleMenuAction *) l->data;
============================================================
--- main.cpp 5f10813cc57bf714e62aacbb5af18b261e685554
+++ main.cpp c214ccdf531210b1f87052454c90154e716153f2
@@ -30,6 +30,7 @@
#include "protocols/icq.h"
#include "protocols/facebook.h"
#include "protocols/gg.h"
+#include "protocols/msn.h"
#include "blistsaving.h"
#include <gloox/tlsbase.h>
@@ -259,7 +260,9 @@ static void * notify_user_info(PurpleCon
*/
static void * notify_user_info(PurpleConnection *gc, const char *who, PurpleNotifyUserInfo *user_info)
{
- GlooxMessageHandler::instance()->vcard()->userInfoArrived(gc,(std::string) who,user_info);
+ std::string name(who);
+ std::for_each( name.begin(), name.end(), replaceBadJidCharacters() );
+ GlooxMessageHandler::instance()->vcard()->userInfoArrived(gc, name, user_info);
return NULL;
}
@@ -538,7 +541,8 @@ void GlooxMessageHandler::loadProtocol()
m_protocol = (AbstractProtocol*) new FacebookProtocol(this);
else if (configuration().protocol == "gg")
m_protocol = (AbstractProtocol*) new GGProtocol(this);
-
+ else if (configuration().protocol == "msn")
+ m_protocol = (AbstractProtocol*) new MSNProtocol(this);
// PurplePlugin *plugin = purple_find_prpl(m_protocol->protocol().c_str());
// if (plugin && PURPLE_PLUGIN_HAS_ACTIONS(plugin)) {
// PurplePluginAction *action = NULL;
@@ -581,7 +585,7 @@ void GlooxMessageHandler::purpleConnecti
m_userManager->removeUserTimer(user);
}
else{
- if (user->reconnectCount()==1){
+ if (user->reconnectCount() > 0){
if (text){
Message s(Message::Chat, user->jid(), (std::string)text);
std::string from;
@@ -594,7 +598,7 @@ void GlooxMessageHandler::purpleConnecti
m_userManager->removeUserTimer(user);
}
else{
-
+ user->disconnected();
g_timeout_add(5000,&reconnect,g_strdup(user->jid().c_str()));
}
}
============================================================
--- main.h 7680e2aab97c4c4ba989bd73fa4b31a6476b72b2
+++ main.h 2c3ce2f0d2a657c50f2e9597cffa37f74796c2bb
@@ -102,7 +102,14 @@ struct authData;
struct UserRow;
struct authData;
+struct replaceBadJidCharacters {
+ void operator()(char& c) { if(c == '@') c = '%'; }
+};
+struct replaceJidCharacters {
+ void operator()(char& c) { if(c == '%') c = '@'; }
+};
+
typedef enum { TRANSPORT_FEATURE_TYPING_NOTIFY = 2,
TRANSPORT_FEATURE_AVATARS = 4,
TRANSPORT_MANGLE_STATUS = 8,
============================================================
--- user.cpp 56711e102628e26b93f6f67a926331b0b90ace19
+++ user.cpp e0c887ef00ca7174d9341e5a6ede410883b53f15
@@ -159,6 +159,7 @@ void User::sendRosterX()
while(it != m_subscribeCache.end()) {
PurpleBuddy *buddy = (*it).second;
std::string name(purple_buddy_get_name(buddy));
+ std::for_each( name.begin(), name.end(), replaceBadJidCharacters() );
if (!name.empty()){
RosterRow user;
std::string alias;
@@ -201,7 +202,9 @@ void User::syncContacts()
PurpleBuddy *buddy;
Log().Get(m_jid) << "Syncing contacts with legacy network.";
for(std::map<std::string, RosterRow>::iterator u = m_roster.begin(); u != m_roster.end() ; u++){
- buddy = purple_find_buddy(m_account, (*u).second.uin.c_str());
+ std::string name((*u).second.uin);
+ std::for_each( name.begin(), name.end(), replaceJidCharacters() );
+ buddy = purple_find_buddy(m_account, name.c_str());
// buddy is not in blist, so it's not on server
if (!buddy) {
// add buddy to server
@@ -226,6 +229,7 @@ Tag *User::generatePresenceStanza(Purple
alias = (std::string) purple_buddy_get_alias(buddy);
std::string name(purple_buddy_get_name(buddy));
+ std::for_each( name.begin(), name.end(), replaceBadJidCharacters() );
PurplePresence *pres = purple_buddy_get_presence(buddy);
if (pres==NULL)
return NULL;
@@ -339,6 +343,7 @@ void User::purpleReauthorizeBuddy(Purple
return;
GList *l, *ll;
std::string name(purple_buddy_get_name(buddy));
+ std::for_each( name.begin(), name.end(), replaceBadJidCharacters() );
if (purple_account_get_connection(m_account)){
PurplePluginProtocolInfo *prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_account_get_connection(m_account)->prpl);
if(prpl_info && prpl_info->blist_node_menu){
@@ -373,6 +378,7 @@ void User::purpleBuddyChanged(PurpleBudd
alias = (std::string) purple_buddy_get_alias(buddy);
std::string name(purple_buddy_get_name(buddy));
+ std::for_each( name.begin(), name.end(), replaceBadJidCharacters() );
PurplePresence *pres = purple_buddy_get_presence(buddy);
if (pres==NULL)
return;
@@ -449,6 +455,7 @@ void User::purpleBuddyRemoved(PurpleBudd
void User::purpleBuddyRemoved(PurpleBuddy *buddy) {
// we should remove pointer to buddy from subscribCache
std::string name(purple_buddy_get_name(buddy));
+ std::for_each( name.begin(), name.end(), replaceBadJidCharacters() );
m_subscribeCache.erase(name);
}
@@ -677,7 +684,9 @@ void User::receivedSubscription(const Su
m_authRequests.erase(subscription.to().username());
}
// subscribed user is not in roster, so we must add him/her there.
- PurpleBuddy *buddy = purple_find_buddy(m_account, subscription.to().username().c_str());
+ std::string name(subscription.to().username());
+ std::for_each( name.begin(), name.end(), replaceJidCharacters() );
+ PurpleBuddy *buddy = purple_find_buddy(m_account, name.c_str());
if(!isInRoster(subscription.to().username(),"both")) {
if(!buddy) {
Log().Get(m_jid) << "user is not in legacy network contact lists => nothing to be subscribed";
@@ -713,7 +722,9 @@ void User::receivedSubscription(const Su
return;
}
else if(subscription.subtype() == Subscription::Subscribe) {
- PurpleBuddy *b = purple_find_buddy(m_account, subscription.to().username().c_str());
+ std::string name(subscription.to().username());
+ std::for_each( name.begin(), name.end(), replaceJidCharacters() );
+ PurpleBuddy *b = purple_find_buddy(m_account, name.c_str());
if (b){
purpleReauthorizeBuddy(b);
}
@@ -744,7 +755,9 @@ void User::receivedSubscription(const Su
}
return;
} else if(subscription.subtype() == Subscription::Unsubscribe || subscription.subtype() == Subscription::Unsubscribed) {
- PurpleBuddy *buddy = purple_find_buddy(m_account, subscription.to().username().c_str());
+ std::string name(subscription.to().username());
+ std::for_each( name.begin(), name.end(), replaceJidCharacters() );
+ PurpleBuddy *buddy = purple_find_buddy(m_account, name.c_str());
if(subscription.subtype() == Subscription::Unsubscribed) {
// user respond to auth request from legacy network and deny it
if (hasAuthRequest((std::string)subscription.to().username())){
@@ -793,7 +806,9 @@ void User::receivedPresence(const Presen
// respond to probe presence
if (stanza.subtype() == Presence::Probe && stanza.to().username()!=""){
- PurpleBuddy *buddy = purple_find_buddy(m_account, stanza.to().username().c_str());
+ std::string name(stanza.to().username());
+ std::for_each( name.begin(), name.end(), replaceJidCharacters() );
+ PurpleBuddy *buddy = purple_find_buddy(m_account, name.c_str());
if (buddy){
Tag *probe = generatePresenceStanza(buddy);
if (probe){
@@ -814,11 +829,15 @@ void User::receivedPresence(const Presen
}
if (m_lang == NULL) {
- std::string lang = stanza.xmlLang();
- if (lang == "default")
+ Tag *tag = stanza.tag();
+ std::string lang = tag->findAttribute("xml:lang");
+ Log().Get("LANG") << tag->xml();
+ delete tag;
+ if (lang == "")
lang = "en";
setLang(lang.c_str());
localization.loadLocale(getLang());
+ Log().Get("LANG") << lang << " " << lang.c_str();
}
// this presence is for the transport
More information about the Commits
mailing list