thirdparty/google_appengine/google/appengine/ext/webapp/xmpp_handlers.py
changeset 2864 2e0b0af889be
equal deleted inserted replaced
2862:27971a13089f 2864:2e0b0af889be
       
     1 #!/usr/bin/env python
       
     2 #
       
     3 # Copyright 2007 Google Inc.
       
     4 #
       
     5 # Licensed under the Apache License, Version 2.0 (the "License");
       
     6 # you may not use this file except in compliance with the License.
       
     7 # You may obtain a copy of the License at
       
     8 #
       
     9 #     http://www.apache.org/licenses/LICENSE-2.0
       
    10 #
       
    11 # Unless required by applicable law or agreed to in writing, software
       
    12 # distributed under the License is distributed on an "AS IS" BASIS,
       
    13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
       
    14 # See the License for the specific language governing permissions and
       
    15 # limitations under the License.
       
    16 #
       
    17 
       
    18 """XMPP webapp handler classes.
       
    19 
       
    20 This module provides handler classes for XMPP bots, including both basic
       
    21 messaging functionality and a command handler for commands such as "/foo bar"
       
    22 """
       
    23 
       
    24 
       
    25 
       
    26 import logging
       
    27 from google.appengine.api import xmpp
       
    28 from google.appengine.ext import webapp
       
    29 
       
    30 
       
    31 class BaseHandler(webapp.RequestHandler):
       
    32   """A webapp baseclass for XMPP handlers.
       
    33 
       
    34   Implements a straightforward message delivery pattern. When a message is
       
    35   received, message_received is called with a Message object that encapsulates
       
    36   the relevant details. Users can reply using the standard XMPP API, or the
       
    37   convenient .reply() method on the Message object.
       
    38   """
       
    39 
       
    40   def message_received(self, message):
       
    41     """Called when a message is sent to the XMPP bot.
       
    42 
       
    43     Args:
       
    44       message: Message: The message that was sent by the user.
       
    45     """
       
    46     raise NotImplementedError()
       
    47 
       
    48   def handle_exception(self, exception, debug_mode):
       
    49     """Called if this handler throws an exception during execution.
       
    50 
       
    51     Args:
       
    52       exception: the exception that was thrown
       
    53       debug_mode: True if the web application is running in debug mode
       
    54     """
       
    55     super(BaseHandler, self).handle_exception(exception, debug_mode)
       
    56     if self.xmpp_message:
       
    57       self.xmpp_message.reply('Oops. Something went wrong.')
       
    58 
       
    59   def post(self):
       
    60     try:
       
    61       self.xmpp_message = xmpp.Message(self.request.POST)
       
    62     except xmpp.InvalidMessageError, e:
       
    63       logging.error("Invalid XMPP request: Missing required field %s", e[0])
       
    64       return
       
    65     self.message_received(self.xmpp_message)
       
    66 
       
    67 
       
    68 class CommandHandlerMixin(object):
       
    69   """A command handler for XMPP bots.
       
    70 
       
    71   Implements a command handler pattern. XMPP messages are processed by calling
       
    72   message_received. Message objects handled by this class are annotated with
       
    73   'command' and 'arg' fields. On receipt of a message starting with a forward
       
    74   or backward slash, the handler calls a method named after the command - eg,
       
    75   if the user sends "/foo bar", the handler will call foo_command(message).
       
    76   If no handler method matches, unhandled_command is called. The default behaviour
       
    77   of unhandled_command is to send the message "Unknown command" back to
       
    78   the sender.
       
    79 
       
    80   If the user sends a message not prefixed with a slash,
       
    81   text_message(message) is called.
       
    82   """
       
    83 
       
    84   def unhandled_command(self, message):
       
    85     """Called when an unknown command is sent to the XMPP bot.
       
    86 
       
    87     Args:
       
    88       message: Message: The message that was sent by the user.
       
    89     """
       
    90     message.reply('Unknown command')
       
    91 
       
    92   def text_message(self, message):
       
    93     """Called when a message not prefixed by a /command is sent to the XMPP bot.
       
    94 
       
    95     Args:
       
    96       message: Message: The message that was sent by the user.
       
    97     """
       
    98     pass
       
    99 
       
   100   def message_received(self, message):
       
   101     """Called when a message is sent to the XMPP bot.
       
   102 
       
   103     Args:
       
   104       message: Message: The message that was sent by the user.
       
   105     """
       
   106     if message.command:
       
   107       handler_name = '%s_command' % (message.command,)
       
   108       handler = getattr(self, handler_name, None)
       
   109       if handler:
       
   110         handler(message)
       
   111       else:
       
   112         self.unhandled_command(message)
       
   113     else:
       
   114       self.text_message(message)
       
   115 
       
   116 
       
   117 class CommandHandler(CommandHandlerMixin, BaseHandler):
       
   118   """A webapp implementation of CommandHandlerMixin."""
       
   119   pass