/src/adhoc.py

http://pyaimt.googlecode.com/ · Python · 169 lines · 134 code · 30 blank · 5 comment · 28 complexity · d7dae7c61fd1fcea0efc6664684f57fb MD5 · raw file

  1. # Copyright 2004-2006 Daniel Henninger <jadestorm@nc.rr.com>
  2. # Licensed for distribution under the GPL version 2, check COPYING for details
  3. import utils
  4. from twisted.words.xish.domish import Element
  5. from twisted.words.protocols.jabber.jid import internJID
  6. import config
  7. import lang
  8. from debug import LogEvent, INFO, WARN, ERROR
  9. import globals
  10. class AdHocCommands:
  11. def __init__(self, pytrans):
  12. self.pytrans = pytrans
  13. self.pytrans.disco.addFeature(globals.COMMANDS, self.incomingIq, config.jid)
  14. self.pytrans.disco.addNode(globals.COMMANDS, self.sendCommandList, "command_CommandList", config.jid, True)
  15. self.commands = {} # Dict of handlers indexed by node
  16. self.commandNames = {} # Dict of names indexed by node
  17. def addCommand(self, command, handler, name):
  18. self.commands[command] = handler
  19. self.commandNames[command] = name
  20. self.pytrans.disco.addNode(command, self.incomingIq, name, config.jid, False)
  21. def incomingIq(self, el):
  22. itype = el.getAttribute("type")
  23. fro = el.getAttribute("from")
  24. froj = internJID(fro)
  25. to = el.getAttribute("to")
  26. ID = el.getAttribute("id")
  27. ulang = utils.getLang(el)
  28. LogEvent(INFO, msg="Looking for handler")
  29. node = None
  30. for child in el.elements():
  31. xmlns = child.uri
  32. node = child.getAttribute("node")
  33. handled = False
  34. if child.name == "query" and xmlns == globals.DISCO_INFO:
  35. if node and self.commands.has_key(node) and itype == "get":
  36. self.sendCommandInfoResponse(to=fro, ID=ID, node=node, ulang=ulang)
  37. handled = True
  38. elif child.name == "query" and xmlns == globals.DISCO_ITEMS:
  39. if node and self.commands.has_key(node) and itype == "get":
  40. self.sendCommandItemsResponse(to=fro, ID=ID, node=node, ulang=ulang)
  41. handled = True
  42. elif child.name == "command" and xmlns == globals.COMMANDS:
  43. if node and self.commands.has_key(node) and (itype == "set" or itype == "error"):
  44. self.commands[node](el)
  45. handled = True
  46. if not handled:
  47. LogEvent(WARN, msg="Unknown Ad-Hoc command received")
  48. self.pytrans.iq.sendIqError(to=fro, fro=config.jid, ID=ID, xmlns=xmlns, etype="cancel", condition="feature-not-implemented")
  49. def sendCommandList(self, el):
  50. to = el.getAttribute("from")
  51. ID = el.getAttribute("id")
  52. ulang = utils.getLang(el)
  53. iq = Element((None, "iq"))
  54. iq.attributes["to"] = to
  55. iq.attributes["from"] = config.jid
  56. if ID:
  57. iq.attributes["id"] = ID
  58. iq.attributes["type"] = "result"
  59. query = iq.addElement("query")
  60. query.attributes["xmlns"] = globals.DISCO_ITEMS
  61. query.attributes["node"] = globals.COMMANDS
  62. for command in self.commands:
  63. item = query.addElement("item")
  64. item.attributes["jid"] = config.jid
  65. item.attributes["node"] = command
  66. item.attributes["name"] = lang.get(self.commandNames[command], ulang)
  67. self.pytrans.send(iq)
  68. def sendCommandInfoResponse(self, to, ID, node, ulang):
  69. LogEvent(INFO, msg="Replying to disco#info")
  70. iq = Element((None, "iq"))
  71. iq.attributes["type"] = "result"
  72. iq.attributes["from"] = config.jid
  73. iq.attributes["to"] = to
  74. if ID: iq.attributes["id"] = ID
  75. query = iq.addElement("query")
  76. query.attributes["xmlns"] = globals.DISCO_INFO
  77. # Add identity
  78. identity = query.addElement("identity")
  79. identity.attributes["name"] = lang.get(self.commandNames[node], ulang)
  80. identity.attributes["category"] = "automation"
  81. identity.attributes["type"] = "command-node"
  82. # Add supported feature
  83. feature = query.addElement("feature")
  84. feature.attributes["var"] = globals.COMMANDS
  85. # Add supported feature
  86. feature = query.addElement("feature")
  87. feature.attributes["var"] = globals.XDATA
  88. self.pytrans.send(iq)
  89. def sendCommandItemsResponse(self, to, ID, node, ulang):
  90. LogEvent(INFO, msg="Replying to disco#items")
  91. iq = Element((None, "iq"))
  92. iq.attributes["type"] = "result"
  93. iq.attributes["from"] = config.jid
  94. iq.attributes["to"] = to
  95. if ID: iq.attributes["id"] = ID
  96. query = iq.addElement("query")
  97. query.attributes["xmlns"] = globals.DISCO_ITEMS
  98. self.pytrans.send(iq)
  99. def sendCancellation(self, node, el, sessionid=None):
  100. to = el.getAttribute("from")
  101. ID = el.getAttribute("id")
  102. ulang = utils.getLang(el)
  103. iq = Element((None, "iq"))
  104. iq.attributes["to"] = to
  105. iq.attributes["from"] = config.jid
  106. if ID:
  107. iq.attributes["id"] = ID
  108. iq.attributes["type"] = "result"
  109. command = iq.addElement("command")
  110. if sessionid:
  111. command.attributes["sessionid"] = sessionid
  112. else:
  113. command.attributes["sessionid"] = self.pytrans.makeMessageID()
  114. command.attributes["node"] = node
  115. command.attributes["xmlns"] = globals.COMMANDS
  116. command.attributes["status"] = "canceled"
  117. self.pytrans.send(iq)
  118. def sendError(self, node, el, errormsg, sessionid=None):
  119. to = el.getAttribute("from")
  120. ID = el.getAttribute("id")
  121. ulang = utils.getLang(el)
  122. iq = Element((None, "iq"))
  123. iq.attributes["to"] = to
  124. iq.attributes["from"] = config.jid
  125. if ID:
  126. iq.attributes["id"] = ID
  127. iq.attributes["type"] = "result"
  128. command = iq.addElement("command")
  129. if sessionid:
  130. command.attributes["sessionid"] = sessionid
  131. else:
  132. command.attributes["sessionid"] = self.pytrans.makeMessageID()
  133. command.attributes["node"] = node
  134. command.attributes["xmlns"] = globals.COMMANDS
  135. command.attributes["status"] = "completed"
  136. note = command.addElement("note")
  137. note.attributes["type"] = "error"
  138. note.addContent(errormsg)
  139. self.pytrans.send(iq)