soc.2009.transport: 7ec6bcf4: clean code
hanzz at soc.pidgin.im
hanzz at soc.pidgin.im
Sun Jul 26 12:45:46 EDT 2009
-----------------------------------------------------------------
Revision: 7ec6bcf44deaaa86605398cf212074ba4f48f50c
Ancestor: e57dbfc55599f243a2185a268826f080d6a62bfc
Author: hanzz at soc.pidgin.im
Date: 2009-07-26T14:58:09
Branch: im.pidgin.soc.2009.transport
URL: http://d.pidgin.im/viewmtn/revision/info/7ec6bcf44deaaa86605398cf212074ba4f48f50c
Modified files:
adhochandler.cpp adhochandler.h adhocrepeater.cpp
adhocrepeater.h adhocsettings.h main.cpp
ChangeLog:
clean code
-------------- next part --------------
============================================================
--- adhochandler.cpp a5cd707dc7750bd7b8ee2d2071d9cc6a1d03d6a4
+++ adhochandler.cpp 66e5364e945316b7efcce4a3bb0d4f8de8c84b16
@@ -51,69 +51,77 @@ StringList GlooxAdhocHandler::handleDisc
return features;
}
+/*
+ * Returns ItemList which contains list of available commands
+ */
Disco::ItemList GlooxAdhocHandler::handleDiscoNodeItems( const JID &_from, const JID &_to, const std::string& node ) {
Disco::ItemList lst;
std::string from = _from.bare();
std::string to = _to.bare();
Log().Get("GlooxAdhocHandler") << "items" << from << to;
-// if (node.empty()) {
-// lst.push_back( new Disco::Item( main->jid(), XMLNS_ADHOC_COMMANDS, "Ad-Hoc Commands" ) );
-// }
-// else if (node == XMLNS_ADHOC_COMMANDS) {
- if (to == main->jid()) {
- User *user = main->userManager()->getUserByJID(from);
- if (user) {
- for(std::map<std::string, adhocCommand>::iterator u = m_handlers.begin(); u != m_handlers.end() ; u++) {
- lst.push_back( new Disco::Item( main->jid(), (*u).first, (std::string) tr(user->getLang(), (*u).second.name) ) );
- }
- if (user->isConnected() && purple_account_get_connection(user->account())) {
- PurpleConnection *gc = purple_account_get_connection(user->account());
- PurplePlugin *plugin = gc && PURPLE_CONNECTION_IS_CONNECTED(gc) ? gc->prpl : NULL;
- if (plugin && PURPLE_PLUGIN_HAS_ACTIONS(plugin)) {
- PurplePluginAction *action = NULL;
- GList *actions, *l;
- actions = PURPLE_PLUGIN_ACTIONS(plugin, gc);
+ // it's adhoc request for transport
+ if (to == main->jid()) {
+ User *user = main->userManager()->getUserByJID(from);
+ if (user) {
+ // add internal commands from m_handlers
+ for(std::map<std::string, adhocCommand>::iterator u = m_handlers.begin(); u != m_handlers.end() ; u++) {
+ lst.push_back( new Disco::Item( main->jid(), (*u).first, (std::string) tr(user->getLang(), (*u).second.name) ) );
+ }
+ // add commands from libpurple
+ if (user->isConnected() && purple_account_get_connection(user->account())) {
+ PurpleConnection *gc = purple_account_get_connection(user->account());
+ PurplePlugin *plugin = gc && PURPLE_CONNECTION_IS_CONNECTED(gc) ? gc->prpl : NULL;
+ if (plugin && PURPLE_PLUGIN_HAS_ACTIONS(plugin)) {
+ PurplePluginAction *action = NULL;
+ GList *actions, *l;
- for (l = actions; l != NULL; l = l->next) {
- if (l->data) {
- action = (PurplePluginAction *) l->data;
- lst.push_back( new Disco::Item( main->jid(), "transport_" + (std::string) action->label,(std::string) tr(user->getLang(), action->label) ) );
- purple_plugin_action_free(action);
- }
+ actions = PURPLE_PLUGIN_ACTIONS(plugin, gc);
+
+ for (l = actions; l != NULL; l = l->next) {
+ if (l->data) {
+ action = (PurplePluginAction *) l->data;
+ // we are using "transport_" prefix here to identify command in disco#info handler
+ // it's ugly and we're bastards, but it's the easy solution
+ lst.push_back( new Disco::Item( main->jid(), "transport_" + (std::string) action->label,(std::string) tr(user->getLang(), action->label) ) );
+ purple_plugin_action_free(action);
}
}
}
}
}
- else {
- 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;
- PurplePluginProtocolInfo *prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(plugin);
+ }
+ // it's request for some PurpleBuddy
+ else {
+ 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;
+ PurplePluginProtocolInfo *prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(plugin);
- 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());
+ 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());
- 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(), "transport_" + (std::string) action->label, (std::string) tr(user->getLang(), action->label) ) );
- purple_menu_action_free(action);
- }
+ 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(), "transport_" + (std::string) action->label, (std::string) tr(user->getLang(), action->label) ) );
+ purple_menu_action_free(action);
}
}
}
-// }
+ }
return lst;
}
+/*
+ * Returns IdentityList (copied from Gloox :) )
+ */
Disco::IdentityList GlooxAdhocHandler::handleDiscoNodeIdentities( const JID& jid, const std::string& node ) {
Disco::IdentityList l;
l.push_back( new Disco::Identity( "automation",node == XMLNS_ADHOC_COMMANDS ? "command-list" : "command-node",node == XMLNS_ADHOC_COMMANDS ? "Ad-Hoc Commands" : "") );
@@ -136,8 +144,10 @@ bool GlooxAdhocHandler::handleIq( const
User *user = main->userManager()->getUserByJID(from);
if (user) {
+ // check if we have existing session for this jid
if (hasSession(stanza.from().full())) {
if( m_sessions[stanza.from().full()]->handleIq(stanza) ) {
+ // AdhocCommandHandler returned true, so we should remove it
std::string jid = stanza.from().full();
delete m_sessions[jid];
unregisterSession(jid);
@@ -145,12 +155,14 @@ bool GlooxAdhocHandler::handleIq( const
delete stanzaTag;
return true;
}
+ // check if we have registered handler for this node and create AdhocCommandHandler class
else if (m_handlers.find(node) != m_handlers.end()) {
AdhocCommandHandler *handler = m_handlers[node].createHandler(main, user, stanza.from().full(), stanza.id());
registerSession(stanza.from().full(), handler);
delete stanzaTag;
return true;
}
+ // if it's PurpleAction, so we don't have handler for it, we have to execute the action here.
if (user->isConnected() && purple_account_get_connection(user->account())) {
if (to == main->jid()) {
PurpleConnection *gc = purple_account_get_connection(user->account());
@@ -229,8 +241,7 @@ bool GlooxAdhocHandler::hasSession(const
return false;
}
-void GlooxAdhocHandler::handleIqID( const IQ &iq, int context ) {
-}
+void GlooxAdhocHandler::handleIqID( const IQ &iq, int context ) {}
void GlooxAdhocHandler::handleDiscoInfo(const JID &jid, const Disco::Info &info, int context) {
Log().Get("handle disco info adhoc") << jid.full();
============================================================
--- adhochandler.h 0949f16231e286dc210d600ade72a82478a1bf8e
+++ adhochandler.h c234c51fe7c0baf9199404acfae5efeca82b17f0
@@ -31,8 +31,13 @@ class AdhocRepeater;
class GlooxMessageHandler;
class AdhocRepeater;
+
+/*
+ * Structure used for registering Ad-Hoc command
+ */
struct adhocCommand {
- std::string name;
+ std::string name; // command's name
+ // function which creates AdhocCommandHandler class which will be used as handler for this command
AdhocCommandHandler * (*createHandler)(GlooxMessageHandler *m, User *user, const std::string &from, const std::string &id);
};
@@ -54,9 +59,9 @@ class GlooxAdhocHandler : public DiscoNo
bool hasSession(const std::string &jid);
private:
- GlooxMessageHandler *main;
- std::map<std::string, AdhocCommandHandler *> m_sessions;
- std::map<std::string, adhocCommand> m_handlers; // m_handlers[node] = handler
+ GlooxMessageHandler *main; // client
+ std::map<std::string, AdhocCommandHandler *> m_sessions; // sessions (m_sessions[full_jid] = handler)
+ std::map<std::string, adhocCommand> m_handlers; // handlers (m_handlers[node] = handler)
};
============================================================
--- adhocrepeater.cpp 8f90c89c1588aed6da5e9a12cb07ded9d4e759b0
+++ adhocrepeater.cpp 14e2b6616e967f4e72d66083111c7036d417cbc2
@@ -22,7 +22,7 @@
#include "gloox/stanza.h"
#include "log.h"
#include "dataforms.h"
-
+
static gboolean removeRepeater(gpointer data){
AdhocRepeater *repeater = (AdhocRepeater*) data;
purple_request_close(repeater->type(),repeater);
@@ -42,6 +42,7 @@ AdhocRepeater::AdhocRepeater(GlooxMessag
setType(PURPLE_REQUEST_INPUT);
setRequestType(CALLER_ADHOC);
+ // generate IQ-result for IQ-get (that IQ-get is handled in AdhocHandler class)
IQ _response(IQ::Result, data.from, data.id);
Tag *response = _response.tag();
response->addAttribute("from",main->jid());
@@ -63,7 +64,6 @@ AdhocRepeater::AdhocRepeater(GlooxMessag
response->addChild(c);
main->j->send(response);
-
}
AdhocRepeater::AdhocRepeater(GlooxMessageHandler *m, User *user, const std::string &title, const std::string &primaryString, const std::string &secondaryString, int default_action, void * user_data, size_t action_count, va_list acts) {
@@ -86,6 +86,7 @@ AdhocRepeater::AdhocRepeater(GlooxMessag
// <option label='None'><value>none</value></option>
// </field>
+ // generate IQ-result for IQ-get (that IQ-get is handled in AdhocHandler class)
IQ _response(IQ::Result, data.from, data.id);
Tag *response = _response.tag();
response->addAttribute("from",main->jid());
@@ -101,6 +102,7 @@ AdhocRepeater::AdhocRepeater(GlooxMessag
actions->addChild(new Tag("complete"));
c->addChild(actions);
+ // save action to m_actions; only keys will be saved
for (unsigned int i = 0; i < action_count; i++)
m_actions[i] = va_arg(acts, GCallback);
@@ -122,6 +124,7 @@ AdhocRepeater::AdhocRepeater(GlooxMessag
m_from = data.from;
setRequestType(CALLER_ADHOC);
+ // generate IQ-result for IQ-get (that IQ-get is handled in AdhocHandler class)
IQ _response(IQ::Result, data.from, data.id);
Tag *response = _response.tag();
response->addAttribute("from",main->jid());
@@ -148,6 +151,8 @@ bool AdhocRepeater::handleIq(const IQ &s
Tag *stanzaTag = stanza.tag();
if (!stanzaTag) return false;
Tag *tag = stanzaTag->findChild( "command" );
+
+ // check if user canceled request
if (tag->hasAttribute("action","cancel")){
IQ _response(IQ::Result, stanza.from().full(), stanza.id());
_response.setFrom(main->jid());
============================================================
--- adhocrepeater.h 40b068f03ab1792cd7fd1455490a55bba621949f
+++ adhocrepeater.h 2f89a14d0aecad181b05da74b7a3fd22f16e7c34
@@ -31,6 +31,9 @@ class User;
class GlooxMessageHandler;
class User;
+/*
+ * Handler for PURPLE_REQUESTs. It handles different requests and resends them as Ad-Hoc commands.
+ */
class AdhocRepeater : public AdhocCommandHandler
{
public:
@@ -42,21 +45,22 @@ class AdhocRepeater : public AdhocComman
AdhocRepeater(GlooxMessageHandler *m, User *user, const std::string &title, const std::string &primaryString, const std::string &secondaryString, PurpleRequestFields *fields, GCallback ok_cb, GCallback cancel_cb, void * user_data);
~AdhocRepeater();
bool handleIq(const IQ &iq);
+
void setType(PurpleRequestType t) { m_type = t; }
PurpleRequestType type() { return m_type; }
std::string & from() { return m_from; }
private:
- GlooxMessageHandler *main;
- User *m_user;
- void *m_requestData;
- GCallback m_ok_cb;
- GCallback m_cancel_cb;
- PurpleRequestType m_type;
- std::string m_from;
- std::map<int, GCallback> m_actions;
- PurpleRequestFields *m_fields;
- std::string m_defaultString;
+ GlooxMessageHandler *main; // client
+ User *m_user; // User to which Ad-Hoc are sent
+ void *m_requestData; // user_data from PURPLE_REQUEST
+ GCallback m_ok_cb; // callback which is called when user accepts the dialog
+ GCallback m_cancel_cb; // callback which is called when user rejects the dialog
+ PurpleRequestType m_type; // type of request
+ std::string m_from; // full jid from which initial IQ-get was sent
+ std::map<int, GCallback> m_actions; // callbacks for PURPLE_REQUEST_ACTION
+ PurpleRequestFields *m_fields; // fields for PURPLE_REQUEST_FIELDS
+ std::string m_defaultString; // default value of PURPLE_REQUEST_INPUT
};
#endif
============================================================
--- adhocsettings.h 7440af0914d36c4159d6a102869c842914d004e6
+++ adhocsettings.h 42682d946fff5fbe3d29e84fcb4e1f826c142d98
@@ -31,6 +31,9 @@ class User;
class GlooxMessageHandler;
class User;
+/*
+ * AdhocCommandHandler for Transport Settings node
+ */
class AdhocSettings : public AdhocCommandHandler
{
public:
@@ -40,9 +43,9 @@ class AdhocSettings : public AdhocComman
std::string & from() { return m_from; }
private:
- GlooxMessageHandler *main;
- std::string m_from;
- User *m_user;
+ GlooxMessageHandler *main; // client
+ std::string m_from; // full jid
+ User *m_user; // User class
};
#endif
============================================================
--- main.cpp 9d69471f3c73c3017421205f7951fc56c4ba3a6d
+++ main.cpp 9b77fd795f12e2a59252ac0c0426133f5cf07340
@@ -48,58 +48,50 @@ namespace gloox {
#include <gloox/compressionbase.h>
namespace gloox {
- class HiComponent : public Component {
- public:
- HiComponent(const std::string & ns, const std::string & server,
- const std::string & component, const std::string & password,
- int port = 5347)
- : Component(ns, server, component, password, port)
- {
- };
+ class HiComponent : public Component {
+ public:
+ HiComponent(const std::string & ns, const std::string & server, const std::string & component, const std::string & password, int port = 5347) : Component(ns, server, component, password, port) {};
- virtual ~HiComponent() {};
+ virtual ~HiComponent() {};
- virtual void send(Tag *tag) // unfortunately we can't override const std::string variant
- {
- std::string tagxml;
- std::string outxml;
- if (!tag)
- return;
+ // unfortunately we can't override const std::string variant
+ virtual void send(Tag *tag) {
+ std::string tagxml;
+ std::string outxml;
+ if (!tag)
+ return;
- try {
- tagxml = tag->xml();
- outxml.resize(tagxml.size(), 0);
+ try {
+ tagxml = tag->xml();
+ outxml.resize(tagxml.size(), 0);
- // replace invalid utf-8 characters
- utf8::replace_invalid(tagxml.begin(), tagxml.end(), outxml.begin(), '?');
+ // replace invalid utf-8 characters
+ utf8::replace_invalid(tagxml.begin(), tagxml.end(), outxml.begin(), '?');
- // replace invalid xml characters
- for (std::string::iterator it = outxml.begin(); it != outxml.end(); ++it) {
- if (((unsigned char)*it) < 0x20 && (*it != 0x09 && *it != 0x0A && *it != 0x0D)) {
- *it = '?';
- }
- }
-// std::cout << outxml << "\n\n";
- send(outxml);
- } catch (...) { // replace_invalid can throw exception? wtf!
- }
+ // replace invalid xml characters
+ for (std::string::iterator it = outxml.begin(); it != outxml.end(); ++it) {
+ if (((unsigned char)*it) < 0x20 && (*it != 0x09 && *it != 0x0A && *it != 0x0D)) {
+ *it = '?';
+ }
+ }
+ send(outxml);
+ } catch (...) { // replace_invalid can throw exception? wtf!
+ }
- delete tag;
- }
- protected:
- void send( const std::string & xml) // copied from ClientBase::send(std::string), why have private function which handles protected data ??
- {
- if( m_connection && m_connection->state() == StateConnected )
- {
- if( m_compression && m_compressionActive )
- m_compression->compress( xml );
- else if( m_encryption && m_encryptionActive )
- m_encryption->encrypt( xml );
- else
- m_connection->send( xml );
- }
- }
- };
+ delete tag;
+ }
+ protected:
+ void send( const std::string & xml) { // copied from ClientBase::send(std::string), why have private function which handles protected data ??
+ if( m_connection && m_connection->state() == StateConnected ) {
+ if( m_compression && m_compressionActive )
+ m_compression->compress( xml );
+ else if( m_encryption && m_encryptionActive )
+ m_encryption->encrypt( xml );
+ else
+ m_connection->send( xml );
+ }
+ }
+ };
};
/*
@@ -111,17 +103,23 @@ static void newMessageReceived(PurpleAcc
}
/*
- * Called when message from legacy network arrived (we have to resend message)
+ * Called when libpurple wants to write some message to Chat
*/
static void conv_write_im(PurpleConversation *conv, const char *who, const char *message, PurpleMessageFlags flags, time_t mtime)
{
GlooxMessageHandler::instance()->purpleConversationWriteIM(conv,who,message,flags,mtime);
}
+/*
+ * Called when libpurple wants to write some message to Groupchat
+ */
static void conv_write_chat(PurpleConversation *conv, const char *who, const char *message, PurpleMessageFlags flags, time_t mtime) {
GlooxMessageHandler::instance()->purpleConversationWriteChat(conv,who,message,flags,mtime);
}
+/*
+ * Called when libpurple wants to write some message to Conversation
+ */
static void conv_write_conv(PurpleConversation *conv, const char *who, const char *alias,const char *message, PurpleMessageFlags flags, time_t mtime) {
if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
conv_write_im(conv, who, message, flags, mtime);
@@ -131,18 +129,30 @@ static void conv_write_conv(PurpleConver
}
}
+/*
+ * Called when chat topic was changed
+ */
static void conv_chat_topic_changed(PurpleConversation *chat, const char *who, const char *topic) {
GlooxMessageHandler::instance()->purpleChatTopicChanged(chat, who, topic);
}
+/*
+ * Called when there are new users added
+ */
static void conv_chat_add_users(PurpleConversation *conv, GList *cbuddies, gboolean new_arrivals) {
GlooxMessageHandler::instance()->purpleChatAddUsers(conv, cbuddies, new_arrivals);
}
+/*
+ * Called when user is renamed
+ */
static void conv_chat_rename_user(PurpleConversation *conv, const char *old_name, const char *new_name, const char *new_alias) {
GlooxMessageHandler::instance()->purpleChatRenameUser(conv, old_name, new_name, new_alias);
}
+/*
+ * Called when there are is removed
+ */
static void conv_chat_remove_users(PurpleConversation *conv, GList *users) {
GlooxMessageHandler::instance()->purpleChatRemoveUsers(conv, users);
}
@@ -184,15 +194,16 @@ void connection_report_disconnect(Purple
}
/*
- * Called when purple wants to some input from transport. Showed as input box in Pidgin.
+ * Called when purple wants to some input from transport.
*/
static void * requestInput(const char *title, const char *primary,const char *secondary, const char *default_value,gboolean multiline, gboolean masked, gchar *hint,const char *ok_text, GCallback ok_cb,const char *cancel_text, GCallback cancel_cb,PurpleAccount *account, const char *who,PurpleConversation *conv, void *user_data){
Log().Get("purple") << "new requestInput";
- if (primary){
+ if (primary) {
std::string primaryString(primary);
Log().Get("purple") << "primary string: " << primaryString;
User *user = GlooxMessageHandler::instance()->userManager()->getUserByAccount(account);
if (!user) return NULL;
+ // Check if there is some adhocData. If it's there, this request will be handled by some handler registered to this data.
if (!user->adhocData().id.empty()) {
if (user->adhocData().callerType == CALLER_ADHOC) {
AdhocRepeater *repeater = new AdhocRepeater(GlooxMessageHandler::instance(), user, title ? std::string(title):std::string(), primaryString, secondary ? std::string(secondary):std::string(), default_value ? std::string(default_value):std::string(), multiline, masked, ok_cb, cancel_cb, user_data);
@@ -210,8 +221,8 @@ static void * requestInput(const char *t
// user->setAdhocData(data);
return repeater;
}
-
}
+ // emit protocol signal
GlooxMessageHandler::instance()->protocol()->onPurpleRequestInput(user, title, primary, secondary, default_value, multiline, masked, hint, ok_text, ok_cb, cancel_text, cancel_cb, account, who, conv, user_data);
}
return NULL;
@@ -228,6 +239,7 @@ static void * notifySearchResults(Purple
user->setAdhocData(data);
}
}
+
return NULL;
}
@@ -356,6 +368,9 @@ static void * notifyMessage(PurpleNotify
}
static void * notifyMessage(PurpleNotifyMsgType type, const char *title, const char *primary, const char *secondary) {
+ // TODO: We have to patch libpurple to be able to identify from which account the message came from...
+ // without this the function is quite useles...
+
// User *user = GlooxMessageHandler::instance()->userManager()->getUserByAccount(account);
// if (user && !user->adhocData().id.empty()) {
// AdhocRepeater *repeater = new AdhocRepeater(GlooxMessageHandler::instance(), user, title ? std::string(title):std::string(), primary ? std::string(primary):std::string(), secondary ? std::string(secondary):std::string(), default_action, user_data, action_count, actions);
More information about the Commits
mailing list