tweetcast/server/tweetcast-gevent.py
author Raphael Velt <raph.velt@gmail.com>
Mon, 10 Oct 2011 15:24:28 +0200
changeset 310 526d3e411736
parent 309 e26d4354b578
permissions -rwxr-xr-x
Merge
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
307
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
     1
#!/usr/bin/env python
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
     2
# -*- coding: utf-8 -*-
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
     3
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
     4
from gevent import monkey; monkey.patch_all()
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
     5
# Importer d'abord, sinon exception
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
     6
import anyjson, gevent, psycopg2
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
     7
from sqlalchemy import (Boolean, Column, BigInteger, Integer, String, 
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
     8
    ForeignKey, DateTime, create_engine, func)
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
     9
from sqlalchemy.orm import relationship, sessionmaker
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    10
from sqlalchemy.ext.declarative import declarative_base
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    11
from gevent.pywsgi import WSGIServer
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    12
from urlparse import parse_qs
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    13
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    14
Base = declarative_base()
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    15
engine = create_engine('postgresql://postgres:doiteshimashite@localhost/tweet_live')
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    16
Session = sessionmaker(bind=engine)
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    17
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    18
class Tweet(Base):
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    19
	__tablename__ = 'tweet_tweet'
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    20
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    21
	id = Column(BigInteger, primary_key=True, autoincrement=False)
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    22
	created_at = Column(DateTime)
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    23
	text = Column(String)
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    24
	user_id = Column(Integer, ForeignKey('tweet_user.id'))
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    25
	user = relationship("User", backref="tweets")
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    26
	
309
e26d4354b578 Modifications mineures
Raphael Velt <raph.velt@gmail.com>
parents: 307
diff changeset
    27
	def jsondict(self):
e26d4354b578 Modifications mineures
Raphael Velt <raph.velt@gmail.com>
parents: 307
diff changeset
    28
		return {
307
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    29
			"id" : str(self.id),
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    30
			"created_at" : str(self.created_at),
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    31
			"text" : self.text,
309
e26d4354b578 Modifications mineures
Raphael Velt <raph.velt@gmail.com>
parents: 307
diff changeset
    32
			"user" : self.user.jsondict()
e26d4354b578 Modifications mineures
Raphael Velt <raph.velt@gmail.com>
parents: 307
diff changeset
    33
		}
e26d4354b578 Modifications mineures
Raphael Velt <raph.velt@gmail.com>
parents: 307
diff changeset
    34
	
e26d4354b578 Modifications mineures
Raphael Velt <raph.velt@gmail.com>
parents: 307
diff changeset
    35
	def __repr__(self):
e26d4354b578 Modifications mineures
Raphael Velt <raph.velt@gmail.com>
parents: 307
diff changeset
    36
		return anyjson.serialize(self.jsondict())
307
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    37
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    38
class User(Base):
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    39
	__tablename__ = "tweet_user"
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    40
	
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    41
	id = Column(BigInteger, primary_key=True, autoincrement=False)
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    42
	screen_name = Column(String, index=True)
309
e26d4354b578 Modifications mineures
Raphael Velt <raph.velt@gmail.com>
parents: 307
diff changeset
    43
	profile_image_url = Column(String)
e26d4354b578 Modifications mineures
Raphael Velt <raph.velt@gmail.com>
parents: 307
diff changeset
    44
	
e26d4354b578 Modifications mineures
Raphael Velt <raph.velt@gmail.com>
parents: 307
diff changeset
    45
	def jsondict(self):
e26d4354b578 Modifications mineures
Raphael Velt <raph.velt@gmail.com>
parents: 307
diff changeset
    46
		return {
e26d4354b578 Modifications mineures
Raphael Velt <raph.velt@gmail.com>
parents: 307
diff changeset
    47
			"id" : str(self.id),
e26d4354b578 Modifications mineures
Raphael Velt <raph.velt@gmail.com>
parents: 307
diff changeset
    48
			"screen_name" : self.screen_name,
e26d4354b578 Modifications mineures
Raphael Velt <raph.velt@gmail.com>
parents: 307
diff changeset
    49
			"profile_image_url" : self.profile_image_url
e26d4354b578 Modifications mineures
Raphael Velt <raph.velt@gmail.com>
parents: 307
diff changeset
    50
		}
e26d4354b578 Modifications mineures
Raphael Velt <raph.velt@gmail.com>
parents: 307
diff changeset
    51
	
e26d4354b578 Modifications mineures
Raphael Velt <raph.velt@gmail.com>
parents: 307
diff changeset
    52
	def __repr__(self):
e26d4354b578 Modifications mineures
Raphael Velt <raph.velt@gmail.com>
parents: 307
diff changeset
    53
		return anyjson.serialize(self.jsondict())
307
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    54
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    55
class TweetCast(object):
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    56
	
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    57
	def __init__(self):
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    58
		self.session = Session()
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    59
		a = self.session.query(func.max(Tweet.id))
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    60
		self.lastid = long(a[0][0])
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    61
		print self.lastid
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    62
		self.tweets = []
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    63
		self.clients = []
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    64
		self.clientpos = []
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    65
		print "__init__"
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    66
		gevent.spawn_later(1,self.getLastTweets)
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    67
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    68
	def getLastTweets(self):
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    69
		result = self.session.query(Tweet).filter(Tweet.id > self.lastid).all()
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    70
		if result:
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    71
			self.lastid = result[len(result)-1].id
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    72
			for tweet in result:
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    73
				self.tweets.append(tweet)
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    74
		print "getLastTweets - LastId = %d"%self.lastid
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    75
		gevent.spawn_later(1,self.getLastTweets)
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    76
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    77
	def webserver(self, env, start_response):
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    78
		print env
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    79
		if env['PATH_INFO'] == '/':
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    80
			query = parse_qs(env['QUERY_STRING'])
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    81
			start_response('200 OK', [('Content-Type', 'text/html')])
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    82
			cookie = env['HTTP_COOKIE']
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    83
			if cookie not in self.clients:
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    84
				self.clients.append(cookie)
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    85
				self.clientpos.append(0)
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    86
			clientid = self.clients.index(cookie)
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    87
			pos = self.clientpos[clientid]
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    88
			self.clientpos[clientid] = len(self.tweets)
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    89
			return ["%s[%s]%s"%(
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    90
				"%s("%query["callback"][0] if "callback" in query else "",
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    91
				",".join([str(tweet) for tweet in self.tweets[pos:]]),
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    92
				")" if "callback" in query else ""
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    93
			)]
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    94
		else:
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    95
			start_response('404 Not Found', [('Content-Type', 'text/html')])
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    96
			return ['<h1>Not Found</h1>']
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    97
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    98
tc = TweetCast()
6872c6aac6d6 Tests de Tweetcast avec GEvent et SQL Alchemy, sans websockets
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    99
WSGIServer(('', 8000), tc.webserver).serve_forever()