Permalink
Browse files

lib/model/mention.py

let's try to sort tweets by languages for added fun
  • Loading branch information...
Lawouach committed Apr 30, 2012
1 parent f45b648 commit cd672d4a6cc36ab20fcaa083c41fba4bcdd982c1
Showing with 95 additions and 27 deletions.
  1. +12 −0 lib/plugin/tweet.py
  2. +46 −11 public/css/twiseless.css
  3. +17 −5 public/js/twiseless.js
  4. +11 −8 template/index.mako
  5. +9 −3 webapp/app.py
View
@@ -1,10 +1,12 @@
# -*- coding: utf-8 -*-
import json
+import re
import cherrypy
from cherrypy.process import wspbus, plugins
import oauth2 as oauth
from dateutil.parser import parse
+from guess_language import guessLanguageTag
from lib.model import Base
from lib.model.user import User
@@ -53,13 +55,23 @@ def fetch_mentions(self):
user.oauth_token,
user.oauth_token_secret).pop()
tweets = json.loads(content)
+ if newest: cherrypy.log("Retrieved %d tweets since %s" % (len(tweets), newest.date))
+ else: cherrypy.log("Retrieved %d tweets" % (len(tweets), ))
for tweet in tweets:
user = tweet.get('user')
if user:
session.add(Mention(username=user['name'],
user_id=user['id'],
tweet=tweet['text'],
tweet_id=tweet['id'],
+ lang=self.guess_language(tweet['text']),
date=parse(tweet['created_at'])))
cherrypy.engine.publish('commit-session')
+
+ def guess_language(self, tweet):
+ # based on the simple idea at:
+ # http://granades.com/2009/04/06/using-regular-expressions-to-match-twitter-users-and-hashtags/
+ tweet = re.sub(r'(\A|\s)@(\w+)', r'\1', tweet)
+ tweet = re.sub(r'(\A|\s)#(\w+)', r'\1', tweet)
+ return guessLanguageTag(tweet.strip()).decode('utf-8')
View
@@ -2,29 +2,42 @@ html, body {
margin:0;
padding:0;
background:#CCCC99;
- font-family: 'Nunito', sans-serif;
+ font-family: Helvetica, "Lucida Grande", sans-serif;
}
#viz {
width: 100%;
- height: 560px;
+ height: 350px;
margin:0 auto;
overflow:hidden;
}
-#tweets {
+.tweet-block {
+ padding-bottom: 20px;
+}
+
+.tweet-lang {
+ font-size: 90%;
+ color:#666633;
+ font-weight:bold;
+ padding-bottom: 5px;
+}
+
+.tweet-info {
+ font-weight:bold;
+ margin-bottom: 20px;
}
.tweet {
- padding-bottom: 10px;
- font-size: 14px;
+ padding-bottom: 5px;
+ font-size: 11px;
}
#container
{
margin: 0 auto;
- width: 600px;
- background:#fff;
+ width: 900px;
+ background: #fff;
}
#header
@@ -35,12 +48,25 @@ html, body {
margin-top: 10px;
}
-#header h1 { margin: 0; }
+#header h1 { font-family: 'Nunito', sans-serif; margin: 0; }
#content
{
clear: left;
- padding: 20px;
+ float: left;
+ width: 440px;
+ padding: 20px 0;
+ margin: 0 0 0 30px;
+ display: inline;
+ min-height: 600px;
+}
+
+#content-container
+{
+ float: left;
+ width: 900px;
+ background: #fff;
+ margin-bottom: 10px;
}
#content h2
@@ -50,13 +76,22 @@ html, body {
margin: 0 0 .5em;
}
+#aside
+{
+ float: right;
+ width: 360px;
+ padding: 20px 0;
+ margin: 0 20px 0 0;
+ display: inline;
+}
+
#footer
{
+ clear: both;
background:#666633;
text-align: right;
padding: 20px;
- height: 100px;
- margin-bottom: 10px;
+ height: 1%;
}
#footer a {
View
@@ -38,14 +38,26 @@
tweets.empty();
tweets.hide();
+ tweets.append($("<div><span>"+node.name+" said:</span></div>").addClass('tweet-info'));
+
$.getJSON("/tweets/" + node.id, function(data) {
- $.each(data, function(i, tweet) {
- tweets.append($("<div />").addClass('tweet').append(tweet));
- });
- tweets.show('slow')
+ for(var lang in data) {
+ var block = $("<div />").addClass('tweet-block');
+ block.append($("<div><span>Language: "+lang+"</span></div>").addClass('tweet-lang'));
+ $.each(data[lang], function(i, tweet) {
+ block.append($("<div />").addClass('tweet').append(tweet.text));
+ });
+ tweets.append(block);
+ }
+ tweets.show('slow');
});
+
+ viz.rotate(node, 'animate', {
+ duration: 1000,
+ transition: $jit.Trans.Quart.easeInOut
+ });
},
- levelDistance: 190,
+ levelDistance: 90,
onCreateLabel: function(domElement, node){
var labels = viz.config.Label.type;
if (labels === 'HTML') {
View
@@ -22,15 +22,18 @@
<div id="header">
<h1>:: Twiseless</h1>
</div>
- <div id="content">
- <div id="viz"></div>
- <div id="tweets">
+ <div id="content-container">
+ <div id="content">
+ <div id="tweets"></div>
</div>
- </div>
- <div id="footer">
- <div id="footer-info">
- &copy; Sylvain Hellegouarch, licensed under a <a href="https://github.com/Lawouach/Twiseless/blob/master/LICENSE">BSD license</a>.
- Layout mostly taken from <a href="http://www.maxdesign.com.au/articles/css-layouts/one-fixed/">maxdesign</a>.
+ <div id="aside">
+ <div id="viz"></div>
+ </div>
+ <div id="footer">
+ <div id="footer-info">
+ &copy; Sylvain Hellegouarch, licensed under a <a href="https://github.com/Lawouach/Twiseless/blob/master/LICENSE">BSD license</a>.
+ Layout mostly taken from <a href="http://www.maxdesign.com.au/articles/css-layouts/two-fixed/">maxdesign</a>.
+ </div>
</div>
</div>
</div>
View
@@ -47,7 +47,7 @@ def mentions(self):
"name": username,
"data": {
"$color": "#666633",
- "$height": 120,
+ "$height": 65,
"$angularWidth": count * 360 / (total * 1.0)
},
"adjacencies": []
@@ -59,9 +59,15 @@ def mentions(self):
@cherrypy.tools.json_out()
def tweets(self, user_id):
db = cherrypy.request.db
- tweets = []
+ tweets = {}
for mention in Mention.tweets(db, int(user_id)):
- tweets.append(mention.tweet)
+ if mention.lang not in tweets:
+ tweets[mention.lang] = []
+
+ tweets[mention.lang].append({
+ 'text': mention.tweet
+ }
+ )
return tweets

0 comments on commit cd672d4

Please sign in to comment.