|
1 #!/usr/bin/env python |
|
2 # -*- coding: utf-8 -*- |
|
3 |
|
4 from gevent import monkey; monkey.patch_all() |
|
5 # Importer d'abord, sinon exception |
|
6 import anyjson, gevent, psycopg2 |
|
7 from sqlalchemy import (Boolean, Column, BigInteger, Integer, String, |
|
8 ForeignKey, DateTime, create_engine, func) |
|
9 from sqlalchemy.orm import relationship, sessionmaker |
|
10 from sqlalchemy.ext.declarative import declarative_base |
|
11 from gevent.pywsgi import WSGIServer |
|
12 from urlparse import parse_qs |
|
13 |
|
14 Base = declarative_base() |
|
15 engine = create_engine('postgresql://postgres:doiteshimashite@localhost/tweet_live') |
|
16 Session = sessionmaker(bind=engine) |
|
17 |
|
18 class Tweet(Base): |
|
19 __tablename__ = 'tweet_tweet' |
|
20 |
|
21 id = Column(BigInteger, primary_key=True, autoincrement=False) |
|
22 created_at = Column(DateTime) |
|
23 text = Column(String) |
|
24 user_id = Column(Integer, ForeignKey('tweet_user.id')) |
|
25 user = relationship("User", backref="tweets") |
|
26 |
|
27 def __repr__(self): |
|
28 return anyjson.serialize({ |
|
29 "id" : str(self.id), |
|
30 "created_at" : str(self.created_at), |
|
31 "text" : self.text, |
|
32 "user_id" : self.user_id, |
|
33 "screen_name" : self.user.screen_name |
|
34 }) |
|
35 |
|
36 class User(Base): |
|
37 __tablename__ = "tweet_user" |
|
38 |
|
39 id = Column(BigInteger, primary_key=True, autoincrement=False) |
|
40 created_at = Column(DateTime) |
|
41 screen_name = Column(String, index=True) |
|
42 |
|
43 class TweetCast(object): |
|
44 |
|
45 def __init__(self): |
|
46 self.session = Session() |
|
47 a = self.session.query(func.max(Tweet.id)) |
|
48 self.lastid = long(a[0][0]) |
|
49 print self.lastid |
|
50 self.tweets = [] |
|
51 self.clients = [] |
|
52 self.clientpos = [] |
|
53 print "__init__" |
|
54 gevent.spawn_later(1,self.getLastTweets) |
|
55 |
|
56 def getLastTweets(self): |
|
57 result = self.session.query(Tweet).filter(Tweet.id > self.lastid).all() |
|
58 if result: |
|
59 self.lastid = result[len(result)-1].id |
|
60 for tweet in result: |
|
61 self.tweets.append(tweet) |
|
62 print "getLastTweets - LastId = %d"%self.lastid |
|
63 gevent.spawn_later(1,self.getLastTweets) |
|
64 |
|
65 def webserver(self, env, start_response): |
|
66 print env |
|
67 if env['PATH_INFO'] == '/': |
|
68 query = parse_qs(env['QUERY_STRING']) |
|
69 start_response('200 OK', [('Content-Type', 'text/html')]) |
|
70 cookie = env['HTTP_COOKIE'] |
|
71 if cookie not in self.clients: |
|
72 self.clients.append(cookie) |
|
73 self.clientpos.append(0) |
|
74 clientid = self.clients.index(cookie) |
|
75 pos = self.clientpos[clientid] |
|
76 self.clientpos[clientid] = len(self.tweets) |
|
77 return ["%s[%s]%s"%( |
|
78 "%s("%query["callback"][0] if "callback" in query else "", |
|
79 ",".join([str(tweet) for tweet in self.tweets[pos:]]), |
|
80 ")" if "callback" in query else "" |
|
81 )] |
|
82 else: |
|
83 start_response('404 Not Found', [('Content-Type', 'text/html')]) |
|
84 return ['<h1>Not Found</h1>'] |
|
85 |
|
86 tc = TweetCast() |
|
87 WSGIServer(('', 8000), tc.webserver).serve_forever() |