Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

adding so it randomly picks a funny background image

  • Loading branch information...
commit 876d6a6dfc9e4a17f5e28e54645badf57a2189c3 1 parent 12a2820
@peterbe authored
View
6 app.py
@@ -27,7 +27,7 @@ def __init__(self, database_name=None):
try:
if issubclass(thing, tornado.web.UIModule):
ui_modules_map[name] = thing
- except TypeError:
+ except TypeError: # pragma: no cover
# most likely a builtin class or something
pass
@@ -48,7 +48,7 @@ def __init__(self, database_name=None):
settings.REDIS_PORT)
from models import connection
- self.db = connection[settings.DATABASE_NAME]
+ self.db = connection[database_name or settings.DATABASE_NAME]
@@ -63,5 +63,5 @@ def main(): # pragma: no cover
pass
-if __name__ == "__main__":
+if __name__ == "__main__": # pragma: no cover
main()
View
213 handlers.py
@@ -1,5 +1,6 @@
import re
import datetime
+import random
import os
import logging
from pprint import pprint, pformat
@@ -41,6 +42,20 @@ def redis(self):
def db(self):
return self.application.db
+ def save_following(self, source_username, dest_username, result):
+ assert isinstance(result, bool)
+ following = (self.db.Following
+ .find_one({'user': source_username,
+ 'follows': dest_username}))
+ if not following:
+ following = self.db.Following()
+ following['user'] = source_username
+ following['follows'] = dest_username
+
+ if result != following['following']:
+ following['following'] = result
+ following.save()
+
def save_tweeter_user(self, user):
user_id = user['id']
tweeter = self.db.Tweeter.find_one({'user_id': user_id})
@@ -88,6 +103,21 @@ def parse_status_date(dstr):
if _save:
tweeter.save()
+ return tweeter
+
+ BACKGROUND_IMAGES = [
+ '/static/images/chuck.jpg',
+ '/static/images/rock.jpg',
+ ]
+
+ def render(self, template, **options):
+ background_image = self.redis.get('background_image')
+ if not background_image:
+ background_image = random.choice(self.BACKGROUND_IMAGES)
+ self.redis.setex('background_image', background_image, 60)
+ options['background_image'] = background_image
+ return tornado.web.RequestHandler.render(self, template, **options)
+
@route('/')
class HomeHandler(BaseHandler):
@@ -246,6 +276,8 @@ def _on_lookup(self, result, this_username, data):
data[each['screen_name']] = False
key = 'follows:%s:%s' % (this_username, each['screen_name'])
self.redis.setex(key, int(data[each['screen_name']]), 60 * 5)
+ self.save_following(each['screen_name'], this_username,
+ bool(data[each['screen_name']]))
if self.jsonp:
self.write_jsonp(self.jsonp, data)
@@ -260,6 +292,7 @@ def _on_show(self, result, this_username, username, data):
key = 'follows:%s:%s' % (this_username, username)
if target_follows is not None:
self.redis.setex(key, int(bool(target_follows)), 60)
+ self.save_following(username, this_username, bool(target_follows))
data[username] = target_follows
if self.jsonp:
self.write_jsonp(self.jsonp, data)
@@ -345,8 +378,10 @@ class FollowingHandler(BaseHandler, tornado.auth.TwitterMixin):
@tornado.web.asynchronous
@tornado.gen.engine
def get(self, username):
- options = {'username': username}
- #this_username = self.get_current_user()
+ options = {
+ 'username': username,
+ 'compared_to': None
+ }
current_user = self.get_current_user()
if not current_user:
self.redirect(self.reverse_url('auth_twitter'))
@@ -363,6 +398,9 @@ def get(self, username):
source_screen_name=this_username,
target_screen_name=username,
access_token=access_token)
+ if result and 'relationship' in result:
+ value = result['relationship']['target']['following']
+ self.save_following(username, this_username, value)
else:
result = bool(int(value))
key = None
@@ -378,7 +416,6 @@ def _on_friendship(self, result, key, options):
if isinstance(result, bool):
value = result
else:
- logging.info("Result (%r): %r" % (key, result))
if result and 'relationship' in result:
value = result['relationship']['target']['following']
if key and value is not None:
@@ -406,9 +443,7 @@ def _fetch_info(self, options, username=None):
else:
result = json_decode(value)
key = None
- self._on_info(result, key, options, username)
- def _on_info(self, result, key, options, username):
if result is None:
options['error'] = "Unable to look up info for %s" % username
self._render(options)
@@ -444,13 +479,170 @@ def _set_ratio(self, options, key):
following = options['info'][value]['friends_count']
ratio = 1.0 * followers / max(following, 1)
options['info'][value]['ratio'] = '%.1f' % ratio
- self.redis.sadd('allusernames', value)
key = 'ratios'
- self.redis.zadd(key, **{value: ratio})
- _usernames = self.redis.zrange(key, 0, -1, withscores=False)
- _usernames.reverse()
- options['info'][value]['rank'] = _usernames.index(value)
+ tweeter = self.db.Tweeter.find_one({'username': value})
+ assert tweeter
+ rank = tweeter.get('ratio_rank', None)
+ # This should be re-calculated periodically
+ if rank is None:
+ rank = 0
+ for each in (self.db.Tweeter
+ .find(fields=('username',))
+ .sort('ratio', -1)):
+ rank += 1
+ if each['username'] == value:
+ tweeter['ratio_rank'] = rank
+ tweeter.save()
+ break
+ options['info'][value]['rank'] = rank
+
+
+@route('/following/suggest_tweet.json', name='suggest_tweet')
+class SuggestTweetHandler(BaseHandler):
+
+ def get(self):
+ username = self.get_argument('username')
+ current_user = self.get_current_user()
+ if not current_user:
+ raise HTTPError(403, "Not logged in")
+ compared_to = current_user['username']
+
+ tweeter = self.db.Tweeter.find_one({'username': username})
+ if not tweeter:
+ raise HTTPError(400, "Unknown tweeter %r" % username)
+ compared_tweeter = self.db.Tweeter.find_one({'username': compared_to})
+ if not tweeter:
+ raise HTTPError(400, "Unknown tweeter %r" % compared_to)
+
+ def make_message(include_hashtag=False, include_fullname=False):
+ if include_fullname:
+ name = '@%s (%s)' % (username, fullname)
+ else:
+ name = '@%s' % username
+ tweet = "Apparently "
+ if abs(a - b) < 1.0:
+ tweet += "%s is " % name
+ tweet += "as cool as me"
+ elif b > a:
+ tweet += "I am "
+ tweet += "%s times cooler than %s" % (get_times(a, b), name)
+ elif a > b:
+ tweet += "%s is " % name
+ tweet += "%s times cooler than me" % get_times(a, b)
+
+ hashtag = "#toocool"
+ if include_hashtag:
+ tweet += " %s" % hashtag
+
+ return tweet
+
+ def get_times(*numbers):
+ small = min(numbers)
+ big = max(numbers)
+ bigger = round(big / small)
+ if int(bigger) == 2:
+ return "two"
+ if int(bigger) == 3:
+ return "three"
+ return "about %s" % int(bigger)
+
+ a, b = tweeter['ratio'], compared_tweeter['ratio']
+ fullname = tweeter['name']
+
+ tweet = make_message(include_hashtag=False, include_fullname=True)
+ if len(tweet) > 140:
+ tweet = make_message(include_hashtag=False, include_fullname=False)
+ if len(tweet) > 140:
+ tweet = make_message(include_hashtag=False,
+ include_fullname=False)
+
+ base_url = self.request.host
+ perm_url = self.reverse_url('following_compared',
+ username,
+ compared_to)
+ url = 'http://%s%s' % (base_url, perm_url)
+
+ #self.write_json({'tweet': tweet})
+ self.write_json({'text': tweet, 'url': url})
+
+
+@route('/following/(\w+)/vs/(\w+)', name='following_compared')
+class FollowingComparedtoHandler(FollowingHandler):
+ @tornado.web.asynchronous
+ @tornado.gen.engine
+ def get(self, username, compared_to):
+ options = {'compared_to': compared_to}
+ tweeter = self.db.Tweeter.find_one({'username': username})
+ compared_tweeter = self.db.Tweeter.find_one({'username': compared_to})
+
+ current_user = self.get_current_user()
+ if current_user:
+ # if we don't have tweeter info on any of them, fetch it
+ if not tweeter:
+ # fetch it
+ result = yield tornado.gen.Task(self.twitter_request,
+ "/users/show",
+ screen_name=username,
+ access_token=current_user['access_token'])
+ tweeter = self.save_tweeter_user(result)
+ if not compared_tweeter:
+ result = yield tornado.gen.Task(self.twitter_request,
+ "/users/show",
+ screen_name=compared_to,
+ access_token=current_user['access_token'])
+ compared_tweeter = self.save_tweeter_user(result)
+
+ elif not tweeter and not compared_tweeter:
+ options = {
+ 'page_title': 'Comparing %s to %s' % (username, compared_to)
+ }
+ options['missing_info'] = []
+ if not tweeter:
+ options['missing_info'].append(username)
+ if not compared_tweeter:
+ options['missing_info'].append(compared_to)
+ options['next_url'] = self.request.path
+ self.render('following_compared_missing.html', **options)
+ return
+
+ key = 'follows:%s:%s' % (compared_to, username)
+ value = self.redis.get(key)
+ if value is None:
+ following = (self.db.Following
+ .find_one({'user': tweeter['_id'],
+ 'follows': compared_tweeter['_id']}))
+ if following:
+ options['follows'] = following['following']
+ else:
+ options['follows'] = False
+ else:
+ value = bool(int(value))
+ options['follows'] = value
+
+ if options['follows']:
+ options['page_title'] = ('%s follows %s' %
+ (username, compared_to))
+ else:
+ options['page_title'] = ('%s is too cool for %s' %
+ (username, compared_to))
+
+ options['info'] = {
+ username: {
+ 'followers_count': tweeter['followers'],
+ 'friends_count': tweeter['following'],
+ },
+ compared_to: {
+ 'followers_count': compared_tweeter['followers'],
+ 'friends_count': compared_tweeter['following'],
+ }
+ }
+ options['username'] = username
+ options['this_username'] = compared_to
+ self._set_ratio(options, 'username')
+ self._set_ratio(options, 'this_username')
+ options['compared_to'] = compared_to
+ self.render('following.html', **options)
@route(r'/coolest', name='coolest')
@@ -613,6 +805,7 @@ def get(self):
options.update(self.get_lookups())
self.render('lookups.html', **options)
+
@route('/lookups.json', name='lookups_json')
class LookupsJSONHandler(LookupsHandler):
View
14 models.py
@@ -1,4 +1,5 @@
import datetime
+from pymongo.objectid import ObjectId
from mongolite import Connection, Document
connection = Connection()
@@ -47,3 +48,16 @@ class Tweeter(BaseDocument):
def set_ratio(self):
self['ratio'] = 1.0 * self['followers'] / max(self['following'], 1)
+
+# def calculate_ratio_rank(self, db):
+
+
+
+@connection.register
+class Following(BaseDocument):
+ __collection__ = 'following'
+ skeleton = {
+ 'user': unicode,
+ 'follows': unicode,
+ 'following': bool,
+ }
View
2  static/css/style.css
@@ -1,7 +1,7 @@
body {
font-family: sans-serif;
background-attachment: fixed;
-background-image: url("/static/images/rock.jpg");
+/*background-image: url("/static/images/rock.jpg");*/
background-repeat: no-repeat;
background-position: bottom right;
margin-left: 40px;
View
BIN  static/images/chuck.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  static/images/rock.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
5 templates/base.html
@@ -6,6 +6,11 @@
<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
<meta name="description" content="Find out who on Twitter follows you back (and who is just too cool for you)">
<link href='http://fonts.googleapis.com/css?family=Permanent+Marker' rel='stylesheet' type='text/css'>
+ <style>
+ {% block body_style %}
+ body{ background-image: url("/static/images/chuck.jpg"); }
+ {% end %}
+ </style>
<link href="/static/css/style.css" rel="stylesheet" type="text/css">
{% block extra_head %}{% end %}
</head>
View
27 templates/following.html
@@ -18,10 +18,12 @@
<a href="https://twitter.com/#!{{ username }}"
><img src="http://api.twitter.com/1/users/profile_image/{{ username }}.png?size=bigger"></a>
<strong>{{ username }}</strong>
-{% if follows %}<span class="followsyou">follows me!</span>
+{% if follows %}<span class="followsyou">follows
+{% if compared_to %}<strong>{{ compared_to }}</strong>{% else %}me{% end %}!</span>
{% else %}
{% if follows is not None %}
- <span class="followsyounot">is too cool for me</span>
+ <span class="followsyounot">is too cool for
+ {% if compared_to %}<strong>{{ compared_to }}</strong>{% else %}me{% end %}</span>
{% else %}
<em>couldn't even be looked up on Twitter</em>
{% end %}
@@ -33,7 +35,11 @@
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load("visualization", "1", {packages:["corechart"]});
- google.setOnLoadCallback(drawChart);
+ google.load("jquery", "1.6.4");
+ google.setOnLoadCallback(function() {
+ drawChart();
+ addTweetButton();
+ });
function drawChart() {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Year');
@@ -43,7 +49,7 @@
data.setValue(0, 0, '{{ username }}');
data.setValue(0, 1, {{ info[username]['followers_count'] }});
data.setValue(0, 2, {{ info[username]['friends_count'] }});
- data.setValue(1, 0, 'you');
+ data.setValue(1, 0, {% if compared_to %}'{{ compared_to }}'{% else %}'you'{% end %});
data.setValue(1, 1, {{ info[this_username]['followers_count'] }});
data.setValue(1, 2, {{ info[this_username]['friends_count'] }});
var chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));
@@ -53,6 +59,19 @@
hAxis: {title: 'cool people have bigger \'followers\' than \'following\''}
});
}
+
+ function addTweetButton() {
+
+ $.getJSON('/following/suggest_tweet.json', {username: '{{ username }}'}, function(response) {
+ $('<a href="https://twitter.com/share" class="twitter-share-button">')
+ .attr('data-url', response.url)
+ .attr('data-text', response.text)
+ .attr('data-count', 'horizontal')
+ .text('Tweet')
+ .appendTo($('<div>').prependTo('#content'));
+ $('#content').prepend($('<script>').attr('src', '//platform.twitter.com/widgets.js'));
+ });
+ }
</script>
<table>
View
22 templates/following_compared_missing.html
@@ -0,0 +1,22 @@
+{% extends "base.html" %}
+
+{% block content %}
+
+<h2>Sorry, don't have <strike>Twitter</strike> coolness stats about
+<strong>{{ ' or '.join(missing_info) }}</strong>
+</h2>
+
+<p class="login">
+ <a href="{{ reverse_url('auth_twitter') }}?next={{ next_url }}" class="twitter-login">
+ <img src="/static/images/twitter-small.png" alt="twitter bird">
+ <span class="text">Login with Twitter to fetch that missing information</span>
+ </a>
+ <span class="readonly">&laquo; <strong>Read-only authorisation</strong>,
+ we cannot post to your account.
+ </span>
+</p>
+<p>Once you have logged in we can pick up the necessary information to
+see who's <strike>got the most Twitter followers</strike> coolest.</p>
+
+
+{% end %}
View
5 templates/home.html
@@ -24,11 +24,12 @@
<!-- NON-LOGGED IN BLOCK -->
<p class="description">Ever wanted to know who in your twitter feed actually follows you back? <strong>Too Cool For Me</strong> is a simple tool which tells you quickly and easily who is and isn't following you back in your twitter feed. Try it out - login to your twitter account to start.</p>
<p class="login">
- <a href="/auth/twitter/" class="twitter-login">
+ <a href="{{ reverse_url('auth_twitter') }}" class="twitter-login">
<img src="/static/images/twitter-small.png" alt="twitter bird">
<span class="text">Login with Twitter to start</span>
</a>
- <span class="readonly">&laquo; Read-only authorisation, we cannot post to your account.
+ <span class="readonly">&laquo; <strong>Read-only authorisation</strong>,
+ we cannot post to your account.
<br>Once you're logged in, we'll show you what to do.</span>
</p>
<!-- END NON-LOGGED IN BLOCK -->
View
2  tests/base.py
@@ -19,6 +19,7 @@ class DatabaseTestCaseMixin(object):
def setup_connection(self):
if not self._once:
self._once = True
+ assert 'test' in self.db.name
self._emptyCollections()
def teardown_connection(self):
@@ -43,7 +44,6 @@ def tearDown(self):
class BaseHTTPTestCase(BaseAsyncTestCase, HTTPClientMixin):
- #_once = False
def setUp(self):
super(BaseHTTPTestCase, self).setUp()
View
206 tests/test_handlers.py
@@ -10,7 +10,6 @@ class HandlersTestCase(BaseHTTPTestCase):
def setUp(self):
super(HandlersTestCase, self).setUp()
-
TwitterAuthHandler.authenticate_redirect = \
twitter_authenticate_redirect
@@ -68,7 +67,7 @@ def _login(self, username=u'peterbe', name=u'Peter Bengtsson',
'email': email,
'access_token': {'key': '0123456789',
'secret': 'xxx'},
- 'id': 9876543210,
+ 'id': 9999999999,
'followers_count': 333,
'friends_count': 222,
}
@@ -212,6 +211,10 @@ def test_jsonp(self):
self.assertEqual(int(self.redis.get('lookups:username:peterbe')), 2)
self.assertEqual(int(self.redis.get('lookups:usernames')), 2)
+ self.assertEqual(self.db.Following
+ .find_one({'user': 'obama'})['following'],
+ False)
+
def test_jsonp(self):
url = self.reverse_url('jsonp')
response = self.client.get(url, {'username': 'obama'})
@@ -255,6 +258,13 @@ def test_following_none_cached(self):
self.assertEqual(struct['stephenfry'], False)
self.assertEqual(struct['fox2mike'], True)
+ self.assertEqual(self.db.Following
+ .find_one({'user': 'stephenfry'})['following'],
+ False)
+ self.assertEqual(self.db.Following
+ .find_one({'user': 'fox2mike'})['following'],
+ True)
+
FollowsHandler.twitter_request = \
make_mock_twitter_request({u'relationship': {
u'target': {u'followed_by': True,
@@ -269,6 +279,16 @@ def test_following_none_cached(self):
self.assertEqual(struct['fox2mike'], True)
self.assertEqual(struct['ashley'], True)
+ self.assertEqual(self.db.Following
+ .find_one({'user': 'stephenfry'})['following'],
+ False)
+ self.assertEqual(self.db.Following
+ .find_one({'user': 'fox2mike'})['following'],
+ True)
+ self.assertEqual(self.db.Following
+ .find_one({'user': 'ashley'})['following'],
+ True)
+
def test_following(self):
url = self.reverse_url('following', 'obama')
response = self.client.get(url)
@@ -306,6 +326,14 @@ def test_following(self):
self.assertTrue('%.1f' % (41700.0/1300) in response.body)
self.assertTrue('%.1f' % (417.0/330) in response.body)
+ following = self.db.Following.find_one({'user': 'obama'})
+ assert following
+ self.assertEqual(following,
+ self.db.Following.find_one({'user': 'obama',
+ 'follows': 'peterbe'}))
+ self.assertTrue(not following['following'])
+ self.assertTrue(not self.db.Following.find_one({'user': 'peterbe'}))
+
# same URL but different remote data should yield the same result
# because of temporary caching
FollowingHandler.twitter_request = \
@@ -337,6 +365,11 @@ def test_following(self):
self.assertTrue('%.1f' % (41700.0/1300) in response.body)
self.assertTrue('%.1f' % (417.0/330) in response.body)
+ following = self.db.Following.find_one({'user': 'obama'})
+ assert following
+ self.assertTrue(not following['following'])
+ self.assertTrue(not self.db.Following.find_one({'user': 'peterbe'}))
+
url = self.reverse_url('following', 'chris')
FollowingHandler.twitter_request = \
make_mock_twitter_request({
@@ -358,6 +391,16 @@ def test_following(self):
self.assertTrue('%.1f' % (400.0/1000) in response.body)
self.assertTrue('%.1f' % (417.0/330) in response.body)
+ following = self.db.Following.find_one({'user': 'chris'})
+ assert following
+ self.assertTrue(following['following'])
+ self.assertTrue(not self.db.Following.find_one({'user': 'peterbe'}))
+################################################################################
+ self.assertEqual(following,
+ self.db.Following.find_one({'user': 'chris',
+ 'follows': 'peterbe'}))
+
+
def test_following_temporary_glitch_on_info(self):
url = self.reverse_url('following', 'obama')
response = self.client.get(url)
@@ -562,6 +605,163 @@ def test_lookups(self):
self.assertTrue('>2,222<' in response.body)
self.assertTrue('>666<' in response.body)
+ def test_everyone(self):
+ url = self.reverse_url('everyone')
+ response = self.client.get(url)
+ self.assertEqual(response.code, 302)
+
+ self._login()
+ response = self.client.get(url)
+ self.assertEqual(response.code, 200)
+
+ def test_following_compared_to_not_logged_in(self):
+ url = self.reverse_url('following_compared', 'obama', 'peterbe')
+ response = self.client.get(url)
+ self.assertEqual(response.code, 200)
+ self.assertTrue('Sorry' in response.body)
+
+ login_url = self.reverse_url('auth_twitter')
+ self.assertTrue('href="%s?next=%s"' % (login_url, url)
+ in response.body)
+
+ def test_following_compared_logged_in_self(self):
+ url = self.reverse_url('following_compared', 'obama', 'peterbe')
+ self._login()
+
+ FollowingHandler.twitter_request = \
+ make_mock_twitter_request({
+ "/friendships/show": {u'relationship': {
+ u'target': {u'followed_by': False,
+ u'following': False,
+ u'screen_name': u'obama'}}},
+ "/users/show?screen_name=obama": {u'followers_count': 41700,
+ u'following': False,
+ u'friends_count': 1300,
+ u'name': u'Barak',
+ u'screen_name': u'obama',
+ 'id': 9876543210,
+ },
+ "/users/show?screen_name=peterbe": {
+ u'followers_count': 417,
+ u'following': False,
+ u'friends_count': 330,
+ u'name': u'Peter Bengtsson',
+ u'screen_name': u'peterbe',
+ 'id': 123456789,
+ }
+ })
+
+ response = self.client.get(url)
+ self.assertEqual(response.code, 200)
+
+ self.assertTrue('is too cool for peterbe' in response.body)
+ self.assertTrue('<title>obama is too cool for peterbe'
+ in response.body)
+
+ def test_following_compared_logged_in_different(self):
+ url = self.reverse_url('following_compared', 'obama', 'kimk')
+ self._login()
+
+ FollowingHandler.twitter_request = \
+ make_mock_twitter_request({
+ "/friendships/show": {u'relationship': {
+ u'target': {u'followed_by': False,
+ u'following': False,
+ u'screen_name': u'obama'}}},
+ "/users/show?screen_name=obama": {u'followers_count': 41700,
+ u'following': False,
+ u'friends_count': 1300,
+ u'name': u'Barak',
+ u'screen_name': u'obama',
+ 'id': 9876543210,
+ },
+ "/users/show?screen_name=kimk": {
+ u'followers_count': 40117,
+ u'following': False,
+ u'friends_count': 200,
+ u'name': u'Kim Kardashian',
+ u'screen_name': u'kimk',
+ 'id': 123456789,
+ }
+ })
+
+ response = self.client.get(url)
+ self.assertEqual(response.code, 200)
+
+ self.assertTrue('is too cool for kimk' in response.body)
+ self.assertTrue('<title>obama is too cool for kimk'
+ in response.body)
+
+ obama = self.db.Tweeter.find_one({'username': 'obama'})
+ self.assertEqual(obama['ratio'], 41700.0 / 1300)
+ self.assertEqual(obama['ratio_rank'], 2)
+
+ kimk = self.db.Tweeter.find_one({'username': 'kimk'})
+ self.assertEqual(kimk['ratio'], 40117.0 / 200)
+ self.assertEqual(kimk['ratio_rank'], 1)
+
+ def test_suggest_tweet(self):
+ url = self.reverse_url('suggest_tweet')
+ response = self.client.get(url)
+ self.assertEqual(response.code, 400)
+
+ response = self.client.get(url, {'username': 'obama'})
+ self.assertEqual(response.code, 403)
+
+ self._login()
+ obama = self.db.Tweeter()
+ obama['username'] = u'obama'
+ obama['name'] = u'Barak Obama'
+ obama['user_id'] = 123456789
+ obama['followers'] = 98765
+ obama['following'] = 1000
+ obama.set_ratio()
+ obama.save()
+
+ response = self.client.get(url, {'username': 'obama'})
+ self.assertEqual(response.code, 200)
+
+ struct = json.loads(response.body)
+ self.assertTrue(len(struct['tweet']) <= 140)
+ self.assertTrue(struct['tweet'].endswith('#toocool'))
+ self.assertTrue('@obama' in struct['tweet'])
+ self.assertTrue('66 times cooler' in struct['tweet'])
+
+ billy = self.db.Tweeter()
+ billy['username'] = u'Mr_Billy_Nomates'
+ billy['name'] = u'Billy Nomates von Longname'
+ billy['user_id'] = 333334444
+ billy['followers'] = 45
+ billy['following'] = 100
+ billy.set_ratio()
+ billy.save()
+
+ response = self.client.get(url, {'username': 'Mr_Billy_Nomates'})
+ self.assertEqual(response.code, 200)
+
+ struct = json.loads(response.body)
+ self.assertTrue(len(struct['tweet']) <= 140)
+ self.assertTrue(struct['tweet'].endswith('#toocool'))
+ self.assertTrue('@Mr_Billy_Nomates' in struct['tweet'])
+
+ peterbe = self.db.Tweeter.find_one({'username': 'peterbe'})
+ twin = self.db.Tweeter()
+ twin['username'] = u'peterbestwin'
+ twin['name'] = u'Someone Likeme'
+ twin['user_id'] = 111112222
+ twin['followers'] = peterbe['followers'] + 1
+ twin['following'] = peterbe['following'] - 1
+ twin.set_ratio()
+ twin.save()
+
+ response = self.client.get(url, {'username': 'peterbestwin'})
+ self.assertEqual(response.code, 200)
+
+ struct = json.loads(response.body)
+ self.assertTrue(len(struct['tweet']) <= 140)
+ self.assertTrue(struct['tweet'].endswith('#toocool'))
+ self.assertTrue('@peterbestwin' in struct['tweet'])
+
def make_twitter_get_authenticated_user_callback(struct):
def twitter_get_authenticated_user(self, callback, **kw):
callback(struct)
@@ -573,7 +773,7 @@ def twitter_get_authenticated_user(self, callback, **kw):
'username': u'peterbe',
'email': None,
'access_token': {'key': '0123456789', 'secret': 'xxx'},
- 'id': 123456789,
+ 'id': 1111111111,
'screen_name': u'peterbe',
'followers_count': 300,
'friends_count': 255,
Please sign in to comment.
Something went wrong with that request. Please try again.