tweetcast/server/tweetcast-gevent.py
changeset 311 13702105c5ee
parent 310 526d3e411736
child 312 f8336354d107
child 314 0f1e6ce19b6d
equal deleted inserted replaced
310:526d3e411736 311:13702105c5ee
     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 jsondict(self):
       
    28 		return {
       
    29 			"id" : str(self.id),
       
    30 			"created_at" : str(self.created_at),
       
    31 			"text" : self.text,
       
    32 			"user" : self.user.jsondict()
       
    33 		}
       
    34 	
       
    35 	def __repr__(self):
       
    36 		return anyjson.serialize(self.jsondict())
       
    37 
       
    38 class User(Base):
       
    39 	__tablename__ = "tweet_user"
       
    40 	
       
    41 	id = Column(BigInteger, primary_key=True, autoincrement=False)
       
    42 	screen_name = Column(String, index=True)
       
    43 	profile_image_url = Column(String)
       
    44 	
       
    45 	def jsondict(self):
       
    46 		return {
       
    47 			"id" : str(self.id),
       
    48 			"screen_name" : self.screen_name,
       
    49 			"profile_image_url" : self.profile_image_url
       
    50 		}
       
    51 	
       
    52 	def __repr__(self):
       
    53 		return anyjson.serialize(self.jsondict())
       
    54 
       
    55 class TweetCast(object):
       
    56 	
       
    57 	def __init__(self):
       
    58 		self.session = Session()
       
    59 		a = self.session.query(func.max(Tweet.id))
       
    60 		self.lastid = long(a[0][0])
       
    61 		print self.lastid
       
    62 		self.tweets = []
       
    63 		self.clients = []
       
    64 		self.clientpos = []
       
    65 		print "__init__"
       
    66 		gevent.spawn_later(1,self.getLastTweets)
       
    67 
       
    68 	def getLastTweets(self):
       
    69 		result = self.session.query(Tweet).filter(Tweet.id > self.lastid).all()
       
    70 		if result:
       
    71 			self.lastid = result[len(result)-1].id
       
    72 			for tweet in result:
       
    73 				self.tweets.append(tweet)
       
    74 		print "getLastTweets - LastId = %d"%self.lastid
       
    75 		gevent.spawn_later(1,self.getLastTweets)
       
    76 
       
    77 	def webserver(self, env, start_response):
       
    78 		print env
       
    79 		if env['PATH_INFO'] == '/':
       
    80 			query = parse_qs(env['QUERY_STRING'])
       
    81 			start_response('200 OK', [('Content-Type', 'text/html')])
       
    82 			cookie = env['HTTP_COOKIE']
       
    83 			if cookie not in self.clients:
       
    84 				self.clients.append(cookie)
       
    85 				self.clientpos.append(0)
       
    86 			clientid = self.clients.index(cookie)
       
    87 			pos = self.clientpos[clientid]
       
    88 			self.clientpos[clientid] = len(self.tweets)
       
    89 			return ["%s[%s]%s"%(
       
    90 				"%s("%query["callback"][0] if "callback" in query else "",
       
    91 				",".join([str(tweet) for tweet in self.tweets[pos:]]),
       
    92 				")" if "callback" in query else ""
       
    93 			)]
       
    94 		else:
       
    95 			start_response('404 Not Found', [('Content-Type', 'text/html')])
       
    96 			return ['<h1>Not Found</h1>']
       
    97 
       
    98 tc = TweetCast()
       
    99 WSGIServer(('', 8000), tc.webserver).serve_forever()