From: Ben Darnell Date: Sat, 1 Jun 2013 01:46:53 +0000 (-0400) Subject: Add a simple end-to-end demo of TwitterMixin. X-Git-Tag: v3.1.0~21 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9298756eec8ea5076e123ad38c3b274a285dd317;p=thirdparty%2Ftornado.git Add a simple end-to-end demo of TwitterMixin. --- diff --git a/.gitignore b/.gitignore index c84e747f4..af3cc1bcc 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,5 @@ _auto2to3* /.coverage /htmlcov/ /env/ +# Used in demo apps +secrets.cfg diff --git a/demos/twitter/home.html b/demos/twitter/home.html new file mode 100644 index 000000000..a2c159c58 --- /dev/null +++ b/demos/twitter/home.html @@ -0,0 +1,12 @@ + + + Tornado Twitter Demo + + + + + diff --git a/demos/twitter/twitterdemo.py b/demos/twitter/twitterdemo.py new file mode 100644 index 000000000..3cc23f9ca --- /dev/null +++ b/demos/twitter/twitterdemo.py @@ -0,0 +1,92 @@ +#!/usr/bin/env python +"""A simplistic Twitter viewer to demonstrate the use of TwitterMixin. + +To run this app, you must first register an application with Twitter: + 1) Go to https://dev.twitter.com/apps and create an application. + Your application must have a callback URL registered with Twitter. + It doesn't matter what it is, but it has to be there (Twitter won't + let you use localhost in a registered callback URL, but that won't stop + you from running this demo on localhost). + 2) Create a file called "secrets.cfg" and put your consumer key and + secret (which Twitter gives you when you register an app) in it: + twitter_consumer_key = 'asdf1234' + twitter_consumer_secret = 'qwer5678' + (you could also generate a random value for "cookie_secret" and put it + in the same file, although it's not necessary to run this demo) + 3) Run this program and go to http://localhost:8888 (by default) in your + browser. +""" + +import logging + +from tornado.auth import TwitterMixin +from tornado.escape import json_decode, json_encode +from tornado.ioloop import IOLoop +from tornado import gen +from tornado.options import define, options, parse_command_line, parse_config_file +from tornado.web import Application, RequestHandler, authenticated + +define('port', default=8888, help="port to listen on") +define('config_file', default='secrets.cfg', + help='filename for additional configuration') + +define('debug', default=False, group='application', + help="run in debug mode (with automatic reloading)") +# The following settings should probably be defined in secrets.cfg +define('twitter_consumer_key', type=str, group='application') +define('twitter_consumer_secret', type=str, group='application') +define('cookie_secret', type=str, group='application', + default='__TODO:_GENERATE_YOUR_OWN_RANDOM_VALUE__', + help="signing key for secure cookies") + +class BaseHandler(RequestHandler): + COOKIE_NAME = 'twitterdemo_user' + + def get_current_user(self): + user_json = self.get_secure_cookie(self.COOKIE_NAME) + if not user_json: + return None + return json_decode(user_json) + +class MainHandler(BaseHandler, TwitterMixin): + @authenticated + @gen.coroutine + def get(self): + timeline = yield self.twitter_request( + '/statuses/home_timeline', + access_token=self.current_user['access_token']) + self.render('home.html', timeline=timeline) + +class LoginHandler(BaseHandler, TwitterMixin): + @gen.coroutine + def get(self): + if self.get_argument('oauth_token', None): + user = yield self.get_authenticated_user() + self.set_secure_cookie(self.COOKIE_NAME, json_encode(user)) + self.redirect(self.get_argument('next', '/')) + else: + yield self.authorize_redirect(callback_uri=self.request.full_url()) + +class LogoutHandler(BaseHandler): + def get(self): + self.clear_cookie(self.COOKIE_NAME) + +def main(): + parse_command_line(final=False) + parse_config_file(options.config_file) + + app = Application( + [ + ('/', MainHandler), + ('/login', LoginHandler), + ('/logout', LogoutHandler), + ], + login_url='/login', + **options.group_dict('application')) + app.listen(options.port) + + logging.info('Listening on http://localhost:%d' % options.port) + IOLoop.instance().start() + +if __name__ == '__main__': + main() diff --git a/tornado/auth.py b/tornado/auth.py index 8e1668edb..d210d862c 100644 --- a/tornado/auth.py +++ b/tornado/auth.py @@ -409,7 +409,7 @@ class OAuthMixin(object): def _on_request_token(self, authorize_url, callback_uri, callback, response): if response.error: - raise Exception("Could not get request token") + raise Exception("Could not get request token: %s" % response.error) request_token = _oauth_parse_response(response.body) data = (base64.b64encode(escape.utf8(request_token["key"])) + b"|" + base64.b64encode(escape.utf8(request_token["secret"])))