Commits

Konstantine Rybnikov  committed 857d0e3

make pirate_weather better and add runserver_sleek for SleekXMPP

  • Participants
  • Parent commits 95efdb9

Comments (0)

Files changed (3)

File documentation/overview.rst

 Routing
 -------
 
-Routing is pretty much the same as in Flask `http://flask.pocoo.org/docs/quickstart/#routing`_:
+Routing is pretty much the same as in Flask
+`http://flask.pocoo.org/docs/quickstart/#routing <http://flask.pocoo.org/docs/quickstart/#routing>`_:
 
 .. code-block:: python
 

File examples/pirate_weather/pirate_weather.py

 from xmppflask import XmppFlask
 app = XmppFlask(__name__)
 
+weather_dict = {
+    'Kiev': u"+19 raining. ARGH!!",
+    'Amsterdam': u"+23 sunny. ARRRGH!!",
+}
+
 def get_weather_for_city(city):
-	weather = {
-		'Kiev': u"+19 raining. ARGH!!",
-		'Amsterdam': u"+23 sunny. ARRRGH!!",
-	}
-	return weather.get(city, u"Weather for %(city)s unknown. ARHG!!" % dict(city=city))
+	return (
+        weather_dict.get(
+            city,
+            u"Weather for %(city)s unknown. ARHG!!" % dict(city=city)))
+
+def get_weather_cities():
+    return weather_dict.keys()
 
 @app.route('ping')
 def ping():
     return 'pong'
 
+@app.route('help')
+def help():
+    return (u'Type "weather in <city_name>" to get weather in that city.\n'
+            u'Type "cities" to get list of cities.')
+
+@app.route('cities')
+def cities():
+    return u', '.join(get_weather_cities())
+
 @app.route('weather in <city>')
 def weather(city):
 	return get_weather_for_city(city)

File runserver_sleek.py

+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+"""
+    xmpp_wsgi_runner for xmppflask (or just XMPPWSGI)
+    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+    This application is intended to be something like a web server bug for
+    XMPPWSGI and serve XMPPWSGI applications. It is kept simple, but
+    potentially can be rewritten to handle more load. Future plans are also
+    support of gevent-like coroutines, but we will need to try to import
+    gevent's monkey.patch_sockets() to PyPy somehow.
+
+    :copyright: (c) 2011 Kostyantyn Rybnikov <k.bx@ya.ru>
+    :license: BSD.
+"""
+
+import sleekxmpp
+import logging
+
+log = logging.getLogger(__name__)
+logging.basicConfig(level=logging.INFO)
+
+
+class XMPPWSGIConnection(sleekxmpp.ClientXMPP):
+
+    def __init__(self, app, jid, password):
+        sleekxmpp.ClientXMPP.__init__(self, jid, password)
+        self.app = app
+
+        self.add_event_handler('session_start', self.start)
+        self.add_event_handler('message', self.message)
+
+    def start(self, session):
+        self.send_presence()
+        self.get_roster()
+        log.info('> bot started!')
+
+    def message(self, msg):
+        if msg['body']:
+            environ = {
+                'MESSAGE': msg['body'],
+                'XMPP_JID': msg['from'].bare
+            }
+
+            notification_queue = []
+            resp = u"".join(self.app(environ, notification_queue))
+            if resp:
+                self.send_message(mto=msg['from'], mbody=resp)
+            for jid, msg in notification_queue:
+                self.send_message(mto=jid, mbody=msg)
+
+
+def main():
+    import os
+    import sys
+    import argparse
+
+    def load_app_from_configstr(app_str):
+        path, app_varname = app_str.rsplit(u':', 1)
+        path = os.path.abspath(path)
+        if not os.path.exists(path):
+            print u'Path %s does not exist' % path
+            sys.exit(1)
+        if os.path.isdir(path):
+            print u'Path %s is a directory' % path
+            sys.exit(1)
+        dir_ = os.path.dirname(path)
+        filename = os.path.basename(path)
+        sys.path[0:0] = [dir_]
+        module = __import__(filename.rstrip('.py'))
+        app = getattr(module, app_varname)
+        return app
+
+    parser = (
+        argparse.ArgumentParser(
+            description=u'XMPPWSGI server to run XmppFlask apps.'))
+    parser.add_argument(
+        '--jid', type=unicode,
+        help=u'jid of a bot. You might want to register one for your bot.')
+    parser.add_argument(
+        '--password',
+        required=False,
+        type=unicode,
+        help=u'password to that jid.')
+    parser.add_argument(
+        'app',
+        type=unicode,
+        help=(u'a path to application python file and variable in it separated '
+              u'by ":". For example: ./cool_weather/weather.py:app means that '
+              u'application is in file ./cool_weather/weather.py and stored in '
+              u'variable called app'))
+    args = parser.parse_args()
+
+    app = load_app_from_configstr(args.app)
+
+    xmpp = XMPPWSGIConnection(app, args.jid, args.password)
+    xmpp.connect()
+    xmpp.process(threaded=False)
+
+if __name__ == '__main__':
+    main()