Implement 'list' ad-hoc command
darcs-hash:20070627060637-86b55-c56b45c11cfd4d264ae5c5f351e1f201c222dff1.gz
This commit is contained in:
@@ -21,9 +21,13 @@
|
||||
##
|
||||
|
||||
from pyxmpp.jabber.disco import DiscoInfo, DiscoItems, DiscoItem, DiscoIdentity
|
||||
from pyxmpp.jabber.dataforms import Form, Field
|
||||
|
||||
import jcl
|
||||
from jcl.jabber import DiscoHandler
|
||||
from jcl.model.account import Account
|
||||
|
||||
COMMAND_NS = "http://jabber.org/protocol/commands"
|
||||
|
||||
class CommandManager(object):
|
||||
"""Handle Ad-Hoc commands"""
|
||||
@@ -62,6 +66,14 @@ class CommandManager(object):
|
||||
else:
|
||||
return disco_info
|
||||
|
||||
def apply_command_action(self, info_query, command, action):
|
||||
"""Apply action on command"""
|
||||
action_command_method = action + "_" + command
|
||||
if hasattr(self, action_command_method):
|
||||
return getattr(self, action_command_method)(info_query)
|
||||
else:
|
||||
return None
|
||||
|
||||
command_manager = CommandManager()
|
||||
|
||||
class JCLCommandManager(CommandManager):
|
||||
@@ -74,13 +86,37 @@ class JCLCommandManager(CommandManager):
|
||||
|
||||
def get_list_info(self, disco_info, lang_class):
|
||||
"""Return infos for 'list' command"""
|
||||
disco_info.add_feature("http://jabber.org/protocol/commands")
|
||||
disco_info.add_feature(COMMAND_NS)
|
||||
DiscoIdentity(disco_info,
|
||||
self.get_command_desc("list", lang_class),
|
||||
"automation",
|
||||
"command-node")
|
||||
return disco_info
|
||||
|
||||
def execute_list(self, info_query):
|
||||
"""Execute command 'list'. List accounts"""
|
||||
response = info_query.make_result_response()
|
||||
command_node = response.set_new_content(COMMAND_NS, "command")
|
||||
command_node.setProp("node", "list")
|
||||
command_node.setProp("status", "completed")
|
||||
#command_node.setProp("sessionid", "????") # TODO
|
||||
result_form = Form(xmlnode_or_type="result",
|
||||
title="Registered account") # TODO : add to Lang
|
||||
result_form.reported_fields.append(Field(name="name",
|
||||
field_type="fixed",
|
||||
label="Account name")) # TODO: add to Lang
|
||||
bare_from_jid = unicode(info_query.get_from().bare())
|
||||
self.account_manager.db_connect()
|
||||
accounts = Account.select(Account.q.user_jid == bare_from_jid)
|
||||
for _account in accounts:
|
||||
fields = [Field(name="name",
|
||||
field_type="fixed",
|
||||
value=_account.name)]
|
||||
result_form.add_item(fields)
|
||||
self.account_manager.db_disconnect()
|
||||
result_form.as_xml(command_node)
|
||||
return [response]
|
||||
|
||||
class CommandDiscoGetInfoHandler(DiscoHandler):
|
||||
"""Handle Ad-Hoc command disco get info requests"""
|
||||
|
||||
|
||||
@@ -200,6 +200,9 @@ class JCLComponent(Component, object):
|
||||
self.stream.set_iq_set_handler("query", "jabber:iq:gateway",
|
||||
self.handle_set_gateway)
|
||||
|
||||
self.stream.set_iq_set_handler("command", command.COMMAND_NS,
|
||||
self.handle_command)
|
||||
|
||||
self.stream.set_presence_handler("available",
|
||||
self.handle_presence_available)
|
||||
|
||||
@@ -568,6 +571,23 @@ class JCLComponent(Component, object):
|
||||
self.apply_registered_behavior(self.msg_handlers, message, False)
|
||||
return 1
|
||||
|
||||
def handle_command(self, info_query):
|
||||
"""
|
||||
Handle command IQ
|
||||
"""
|
||||
self.__logger.debug("COMMAND")
|
||||
_command = info_query.xpath_eval("c:command",
|
||||
{"c": command.COMMAND_NS})[0]
|
||||
command_node = _command.prop("node")
|
||||
action = _command.prop("action")
|
||||
if action is None:
|
||||
action = "execute"
|
||||
result = command.command_manager.apply_command_action(info_query,
|
||||
command_node,
|
||||
action)
|
||||
self.send_stanzas(result)
|
||||
return 1
|
||||
|
||||
###########################################################################
|
||||
# Utils
|
||||
###########################################################################
|
||||
@@ -575,7 +595,6 @@ class JCLComponent(Component, object):
|
||||
""" """
|
||||
self.send_stanzas(self.account_manager.send_error(_account, exception))
|
||||
type, value, stack = sys.exc_info()
|
||||
# TODO : not checking email here
|
||||
self.__logger.debug("Error: %s\n%s"
|
||||
% (exception, "".join(traceback.format_exception
|
||||
(type, value, stack, 5))))
|
||||
@@ -641,7 +660,7 @@ class AccountManager(object):
|
||||
if not node:
|
||||
disco_info = DiscoInfo()
|
||||
disco_info.add_feature("jabber:iq:version")
|
||||
disco_info.add_feature("http://jabber.org/protocol/commands")
|
||||
disco_info.add_feature(command.COMMAND_NS)
|
||||
if not self.has_multiple_account_type:
|
||||
disco_info.add_feature("jabber:iq:register")
|
||||
DiscoIdentity(disco_info, name,
|
||||
|
||||
@@ -73,13 +73,14 @@ class MockStream(object):
|
||||
self.sent.append(iq)
|
||||
|
||||
def set_iq_set_handler(self, iq_type, ns, handler):
|
||||
if not iq_type in ["query"]:
|
||||
if not iq_type in ["query", "command"]:
|
||||
raise Exception("IQ type unknown: " + iq_type)
|
||||
if not ns in ["jabber:iq:version",
|
||||
"jabber:iq:register",
|
||||
"jabber:iq:gateway",
|
||||
"http://jabber.org/protocol/disco#items",
|
||||
"http://jabber.org/protocol/disco#info"]:
|
||||
"http://jabber.org/protocol/disco#info",
|
||||
"http://jabber.org/protocol/commands"]:
|
||||
raise Exception("Unknown namespace: " + ns)
|
||||
if handler is None:
|
||||
raise Exception("Handler must not be None")
|
||||
@@ -2485,6 +2486,45 @@ class JCLComponent_TestCase(unittest.TestCase):
|
||||
self.comp.send_stanzas(None)
|
||||
self.assertEquals(len(self.comp.stream.sent), 0)
|
||||
|
||||
|
||||
###########################################################################
|
||||
# 'handle_command' tests
|
||||
###########################################################################
|
||||
def test_handle_command_execute_list(self):
|
||||
self.comp.stream = MockStream()
|
||||
self.comp.stream_class = MockStream
|
||||
account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL)
|
||||
account11 = ExampleAccount(user_jid="user1@test.com",
|
||||
name="account11",
|
||||
jid="account11@jcl.test.com")
|
||||
account12 = Example2Account(user_jid="user1@test.com",
|
||||
name="account12",
|
||||
jid="account12@jcl.test.com")
|
||||
account2 = ExampleAccount(user_jid="user2@test.com",
|
||||
name="account2",
|
||||
jid="account2@jcl.test.com")
|
||||
del account.hub.threadConnection
|
||||
info_query = Iq(stanza_type="set",
|
||||
from_jid="user1@test.com",
|
||||
to_jid="jcl.test.com")
|
||||
command_node = info_query.set_new_content("http://jabber.org/protocol/commands",
|
||||
"command")
|
||||
command_node.setProp("node", "list")
|
||||
command_node.setProp("action", "execute")
|
||||
self.comp.handle_command(info_query)
|
||||
result = self.comp.stream.sent
|
||||
self.assertNotEquals(result, None)
|
||||
self.assertEquals(len(result), 1)
|
||||
command_result = result[0].xpath_eval("c:command",
|
||||
{"c": "http://jabber.org/protocol/commands"})
|
||||
self.assertEquals(len(command_result), 1)
|
||||
self.assertEquals(command_result[0].prop("status"), "completed")
|
||||
# TODO : test sessionid prop, usage (cf XEP) ?
|
||||
items = result[0].xpath_eval("c:command/data:x/data:item",
|
||||
{"c": "http://jabber.org/protocol/commands",
|
||||
"data": "jabber:x:data"})
|
||||
self.assertEquals(len(items), 2)
|
||||
|
||||
class Handler_TestCase(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.handler = Handler()
|
||||
|
||||
Reference in New Issue
Block a user