diff -r 526d3e411736 -r 13702105c5ee tweetcast/gevent/server/tweetcast.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tweetcast/gevent/server/tweetcast.py Wed Oct 12 18:11:19 2011 +0200 @@ -0,0 +1,212 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from gevent import monkey; monkey.patch_all() +# Importer d'abord, sinon exception +import anyjson, gevent, psycopg2 +from sqlalchemy import (Boolean, Column, BigInteger, Integer, String, + ForeignKey, DateTime, create_engine, desc, func) +from sqlalchemy.orm import backref, relationship, sessionmaker +from sqlalchemy.ext.declarative import declarative_base +from gevent.pywsgi import WSGIServer +from urlparse import parse_qs + +annotation_keywords = { + "positive" : '++', + "negative" : '--', + "reference" : '==', + "question" : '??' +} + +Base = declarative_base() +engine = create_engine('postgresql://postgres:doiteshimashite@localhost/tweet_live') +Session = sessionmaker(bind=engine) + +class EntityType(Base): + __tablename__ = "tweet_entity_type" + id = Column(Integer, primary_key=True, autoincrement=True) + label = Column(String) + +class Entity(Base): + __tablename__ = "tweet_entity" + id = Column(Integer, primary_key=True) + tweet_id = Column(BigInteger, ForeignKey('tweet_tweet.id')) + type = Column(String) + entity_type_id = Column(Integer, ForeignKey('tweet_entity_type.id'), nullable=False) + entity_type = relationship("EntityType", backref="entities") + indice_start = Column(Integer) + indice_end = Column(Integer) + source = Column(String) + __mapper_args__ = {'polymorphic_on': type, 'polymorphic_identity': 'entity_entity', 'with_polymorphic':'*'} + + def jsondict(self): + return { + "indice_start" : self.indice_start, + "indice_end" : self.indice_end, + "type" : self.type + } + +class Tweet(Base): + __tablename__ = 'tweet_tweet' + + id = Column(BigInteger, primary_key=True, autoincrement=False) + created_at = Column(DateTime) + text = Column(String) + user_id = Column(Integer, ForeignKey('tweet_user.id')) + user = relationship("User", backref="tweets") + entity_list = relationship(Entity, backref='tweet') + + def annotations(self): + aa = [] + for a in annotation_keywords: + n = self.text.count(annotation_keywords[a]) + if n: + aa.append({ + "name" : a, + "text" : annotation_keywords[a], + "count" : n + }) + return aa + + def jsondict(self): + return { + "id" : str(self.id), + "created_at" : str(self.created_at), + "text" : self.text, + "user" : self.user.jsondict(), + "entities" : [en.jsondict() for en in self.entity_list], + "annotations" : self.annotations() + } + +class User(Base): + __tablename__ = "tweet_user" + + id = Column(BigInteger, primary_key=True, autoincrement=False) + screen_name = Column(String, index=True) + profile_image_url = Column(String) + + def jsondict(self): + return { + "id" : str(self.id), + "screen_name" : self.screen_name, + "profile_image_url" : self.profile_image_url + } + +class Hashtag(Base): + __tablename__ = "tweet_hashtag" + id = Column(Integer, primary_key=True) + text = Column(String, unique=True, index=True) + + def jsondict(self): + return { + "text" : self.text + } + +class Url(Base): + __tablename__ = "tweet_url" + id = Column(Integer, primary_key=True) + url = Column(String, unique=True) + expanded_url = Column(String) + + def jsondict(self): + return { + "url" : self.url, + "expanded_url" : self.expanded_url + } + +class Media(Base): + __tablename__ = "tweet_media" + id = Column(BigInteger, primary_key=True, autoincrement=False) + url = Column(String) + expanded_url = Column(String) + + def jsondict(self): + return { + "url" : self.url, + "expanded_url" : self.expanded_url + } + +class EntityHashtag(Entity): + __tablename__ = "tweet_entity_hashtag" + __mapper_args__ = {'polymorphic_identity': 'entity_hashtag'} + id = Column(Integer, ForeignKey('tweet_entity.id'), primary_key=True) + hashtag_id = Column(Integer, ForeignKey("tweet_hashtag.id")) + hashtag = relationship(Hashtag, primaryjoin=hashtag_id == Hashtag.id) + + def jsondict(self): + d = super(EntityHashtag, self).jsondict() + d['entity'] = self.hashtag.jsondict() + return d + +class EntityUrl(Entity): + __tablename__ = "tweet_entity_url" + __mapper_args__ = {'polymorphic_identity': 'entity_url'} + id = Column(Integer, ForeignKey('tweet_entity.id'), primary_key=True) + url_id = Column(Integer, ForeignKey("tweet_url.id")) + url = relationship(Url, primaryjoin=url_id == Url.id) + + def jsondict(self): + d = super(EntityUrl, self).jsondict() + d['entity'] = self.url.jsondict() + return d + +class EntityUser(Entity): + __tablename__ = "tweet_entity_user" + __mapper_args__ = {'polymorphic_identity': 'entity_user'} + id = Column(Integer, ForeignKey('tweet_entity.id'), primary_key=True) + user_id = Column(BigInteger, ForeignKey('tweet_user.id')) + user = relationship(User, primaryjoin=(user_id == User.id)) + + def jsondict(self): + d = super(EntityUser, self).jsondict() + d['entity'] = self.user.jsondict() + return d + +class EntityMedia(Entity): + __tablename__ = "tweet_entity_media" + __mapper_args__ = {'polymorphic_identity': 'entity_media'} + id = Column(Integer, ForeignKey('tweet_entity.id'), primary_key=True) + media_id = Column(BigInteger, ForeignKey('tweet_media.id')) + media = relationship(Media, primaryjoin=(media_id == Media.id)) + + def jsondict(self): + d = super(EntityMedia, self).jsondict() + d['entity'] = self.media.jsondict() + return d + +# ranges = [] +# lastid = 0L +# +# def define_ranges: +# + +def webserver(env, start_response): + if env['PATH_INFO'] == '/': + httpquery = parse_qs(env['QUERY_STRING']) + print "serving tweets to", env['REMOTE_ADDR'], httpquery + query = session.query(Tweet) + if "since_id" in httpquery: + query = query.filter(Tweet.id >= long(httpquery["since_id"][0])) + if "after_id" in httpquery: + query = query.filter(Tweet.id > long(httpquery["after_id"][0])) + if "max_id" in httpquery: + query = query.filter(Tweet.id <= long(httpquery["max_id"][0])) + if "before_id" in httpquery: + query = query.filter(Tweet.id < long(httpquery["before_id"][0])) + query = query.order_by(desc(Tweet.id)) + if "limit" in httpquery: + result = query[:int(httpquery["limit"][0])] + else: + result = query[:200] + start_response('200 OK', [('Content-Type', 'application/javascript' if "callback" in httpquery else 'application/json' )]) + return ["%s%s%s"%( + "%s("%httpquery["callback"][0] if "callback" in httpquery else "", + anyjson.serialize({"tweets" : [t.jsondict() for t in result]}), + ")" if "callback" in httpquery else "" + )] + else: + start_response('404 Not Found', [('Content-Type', 'text/html')]) + return ['

Not Found

'] + +session = Session() +WSGIServer(('', 8888), webserver).serve_forever() \ No newline at end of file