Commits

Yang Zhang committed f85a863

make crawler works, delete server_push stuff(will implement again)

Comments (0)

Files changed (13)

 from flask import Flask,request,render_template,session,g,redirect,url_for,Response,make_response,send_file,abort
 import sqlite3
 from mysignal import defer_process
-from serverpush import sphapp,message_collection, Message
+#from serverpush import sphapp,message_collection, Message
 from news import User, Post, Comment,Activity
 from functools import wraps
 from server_session import SqliteSessionInterface
 app.secret_key = '\x1e*\xa7\xe0\xab\x10\xab\xfcxU|4\xect\xbe\xb3\x8d?B\x99e\xd1\xf0\xe5'
 app.register_blueprint(userapp, url_prefix='/useraction')
 app.register_blueprint(pybookapp, url_prefix='/pybook')
-app.register_blueprint(sphapp, url_prefix='/serverpush')
+#app.register_blueprint(sphapp, url_prefix='/serverpush')
 #app.register_blueprint(adminapp, url_prefix='/admin')
 #mail = Mail(app)
 
         user = User(email,nickname,password)
         if(user.is_valid()):
             session['user'] = user
-            message_collection.append(Message('Login Success'))
+            #message_collection.append(Message('Login Success'))
             return redirect(request.form['to_url'])
         else:
-            message_collection.append(Message('The email or password is wrong!', 'alert-error'))
+            #message_collection.append(Message('The email or password is wrong!', 'alert-error'))
             return redirect('/login')
         #return render_template('login.html', message="The email or password is wrong!", to_url = request.form['to_url'])
 
 
 
 if __name__ == '__main__':
+    app.debug = True
+    app.run(port = 5555)
     import werkzeug.serving
     @werkzeug.serving.run_with_reloader
     def run_gevent_server():
         global app
         from werkzeug.debug import DebuggedApplication
         app.debug = True
-        app = DebuggedApplication(app, True)
+        #app = DebuggedApplication(app, True)
         http_server = WSGIServer(('',5555), app, handler_class=WebSocketHandler)
         http_server.serve_forever()
 
     #run_gevent_server()
-    #app.debug = True
-    #app.run(port = 5555)
 
 
 
 
 
 
+

crawler/__init__.py

-#from .crawler import crawler
+from .crawler import process

crawler/crawler.py

                 continue
             url = p.eq(i).find('a').attr('href')
             if(text.lower().find('python')!=-1 and url.startswith('http')):
-                print text,url
+                yield text,url
 
 if(__name__ == '__main__'):
     linker = "https://news.ycombinator.com/"
     con.cursor().executescript(open('crawler/crawler.sql','r').read())
     con.commit()
     con.close()
-    
+
 @manager.command
 def run_crawler():
     "run crawler, it will grab python news"
-    pass
-    
+    from crawler import process
+    import datetime
+    results = process()
+    import sqlite3
+    con = sqlite3.connect('db')
+    c = con.cursor()
+    for result in results:
+        title,linker = result
+        linker = linker.strip()
+        if(not linker.startswith('http')):
+            linker = 'http://' + linker
+        c.execute("SELECT id FROM post WHERE title=:title and link=:link",\
+                                {"title":title, 'link':linker})
+        if(c.fetchone is not None):
+            continue
+        c.execute("INSERT INTO post(title,link,post_date,posterid) VALUES (?,?,?,?)",\
+                                (title,linker,datetime.datetime.now(),0))
+    con.commit()
+    con.close()
+
 @manager.command
 def admin():
     'create admin'
-    
+
 @manager.command
 def run_gevent_server():
     'run gevent server'
 
 @quick_connect('require_user_login')
 def require_user_login(*sender):
-    message_collection.append(Message("You need to login first",'alert-error'))
+    #message_collection.append(Message("You need to login first",'alert-error'))
+    pass
 
 @quick_connect('init_cache')
 def init_cache(sender):
-# -*- coding: utf-8 *-*
    def __init__(self,email,nickname,password):
        self.id = None
        self.email = email
        self.nickname = nickname
        self.avatar = None
        self.password = not password or hashlib.sha224(password).hexdigest()
        self.create_date = None
        self.reputation = None
    def get_nickname(self):
        c = g.db.cursor()
        c.execute("SELECT nickname FROM user WHERE email=:email",\
                                {'email':self.email})
        return c.fetchone()['nickname']
    @staticmethod
    def get_avatar_by_id(id):
        c = g.db.cursor()
        c.execute("SELECT avatar FROM user WHERE id=:id",\
                                {'id':id})
        return c.fetchone()['avatar']
    @staticmethod
    def get_user_by_id(id):
        c = g.db.cursor()
        c.execute("SELECT * FROM user WHERE id=:id",\
                                {'id':id})
        result = c.fetchone()
        tempuser = User(result['email'],result['nickname'],None)
        tempuser.avatar = result['avatar']
        tempuser.create_date = result['create_date']
        tempuser.reputation = result['reputation']
        return tempuser
    @staticmethod
    def change_avatar_by_id(id,avatar):
        c = g.db.cursor()
        c.execute("UPDATE user SET avatar = :avatar WHERE id=:id",\
                                {'id':id,'avatar':avatar})
        g.db.commit()
    def is_valid(self):
        c = g.db.cursor()
        c.execute("SELECT * FROM user WHERE email=:email AND password=:password",\
                                {'email':self.email,'password':self.password})
        tempuser = c.fetchone()
        if(not tempuser):
            return False
        self.id = tempuser['id']
        self.email = tempuser['email']
        self.nickname = tempuser['nickname']
        self.avatar = tempuser['avatar']
        self.create_date = tempuser['create_date']
        self.reputation = tempuser['reputation']
        return True
    def is_email_exsit(self):
        c = g.db.cursor()
        c.execute("SELECT nickname FROM user WHERE email=:email",\
                                {'email':self.email})
        if(not c.fetchone()):
            return False
        return True
    def is_nickname_exsit(self):
        c = g.db.cursor()
        c.execute("SELECT nickname FROM user WHERE nickname=:nickname",\
                                {'nickname':self.nickname})
        if(not c.fetchone()):
            return False
        return True
    def is_exist(self):
        c = g.db.cursor()
        c.execute("SELECT nickname FROM user WHERE email=:email or nickname=:nickname",\
                                {'email':self.email,'nickname':self.nickname})
        if(not c.fetchone()):
            return False
        return True
    def update(self):
        c = g.db.cursor()
        self.create_date = datetime.datetime.now()
        c.execute("UPDATE user SET nickname =:nickname, email =:email,\
                   avatar =:avatar, reputation=:reputation WHERE id=:id",\
                                {"nickname":self.nickname,"email":self.email,"avatar":self.avatar,"reputation":self.reputation,"id":self.id})
        g.db.commit()
    def save(self):
        c = g.db.cursor()
        self.create_date = datetime.datetime.now()
        self.reputation = 0
        c.execute("INSERT INTO user(nickname,email,password,create_date,reputation) VALUES (?,?,?,?,?)",\
                                (self.nickname,self.email,self.password,self.create_date,self.reputation))
        self.id = c.lastrowid
        g.db.commit()
    def vote_for(self,postid):
        c = g.db.cursor()
        if(self.reputation is None):
            c.execute("SELECT reputation FROM user WHERE id=:id",{'id':self.id})
            self.reputation = c.fetchone()['reputation']
        import math
        score = 0
        if(self.reputation > 2):
            score = int(math.log(self.reputation , 2))
        c.execute("INSERT OR REPLACE INTO vote(userid, postid, popularity) VALUES (?,?,?)",(self.id,postid,score))
        g.db.commit()
    @staticmethod
    def password_generate(size=8, chars=string.ascii_letters + string.digits):
        return ''.join(random.choice(chars) for x in range(size))
    @staticmethod
    def reset_password_for(email):
        c = g.db.cursor()
        c.execute("SELECT nickname FROM user WHERE email=:email",\
                                {'email':email})
        if(not c.fetchone()):
            return None
        password = User.password_generate()
        md5pw = hashlib.sha224(password).hexdigest()
        c.execute("UPDATE user SET password =:password WHERE email=:email",\
                                {'email':email,'password':md5pw})
        g.db.commit()
        return password
        
    def create_post_activity(self, points, postid):
        info = "<span>You post a post and gain 2 point</span>"
        tempac = Activity(info,self.id)
        tempac.save()
    def __init__(self, title, link, des, post_date = None):
        self.id = None
        self.title = title
        self.link = link
        self.des = des
        self.post_date = post_date
        self.posterid = None
        self.poster = None
    @staticmethod
    def get_post_byid(id):
        c = g.db.cursor()
        c.execute("SELECT * FROM post WHERE id=:id",\
                                {"id":id})
        post = c.fetchone()
        if(post is None):
            return None
        temppost = Post(post['title'], post['link'],post['des'],post['post_date'])
        temppost.id = post['id']
        temppost.posterid = post['posterid']
        return temppost
        
    @staticmethod
    def is_exist(id):
        c = g.db.cursor()
        c.execute("SELECT id FROM post WHERE id=:id",\
                                {"id":id})
        return  c.fetchone() is not None
    def init_post_poster(self):
        c = g.db.cursor()
        c.execute("SELECT nickname, id,reputation FROM user where id=:id",\
                                {"id":self.posterid})
        tempresult = c.fetchone()
        user = User(None,tempresult['nickname'],None)
        user.reputation = tempresult['reputation']
        user.id = tempresult['id']
        self.poster = user
    @staticmethod
    def get_posts_by_postdate(limit = configure.POSTNUMBER_PER_PAGE, offset =0):
        c = g.db.cursor()
        c.execute("SELECT * FROM post WHERE posterid is not NULL ORDER BY post_date DESC LIMIT :limit OFFSET :offset ",\
                                {"limit":limit,"offset":offset*limit})
        result = c.fetchall()
        posts = []
        for post in result:
            temppost = Post(post['title'], post['link'],post['des'],post['post_date'])
            temppost.id = post['id']
            temppost.posterid = post['posterid']
            c.execute("SELECT nickname, id,reputation FROM user where id=:id",\
                                {"id":temppost.posterid})
            tempresult = c.fetchone()
            user = User(None,tempresult['nickname'],None)
            user.reputation = tempresult['reputation']
            user.id = tempresult['id']
            temppost.poster = user
            posts.append(temppost)
        return posts
    @staticmethod
    def get_hot_posts(limit = configure.POSTNUMBER_PER_PAGE, offset =0):
        c = g.db.cursor()
        c.execute("SELECT * FROM post WHERE julianday('now') - julianday(post_date) <= :save_post_days AND posterid is not NULL\
                   LIMIT :limit OFFSET :offset",\
                                {"limit":limit,"offset":offset*limit,'save_post_days':configure.POST_SAVE})
        result = c.fetchall()
        posts = []
        for post in result:
            temppost = Post(post['title'], post['link'],post['des'],post['post_date'])
            temppost.id = post['id']
            temppost.posterid = post['posterid']
            c.execute("SELECT nickname, id,reputation FROM user where id=:id",\
                                {"id":temppost.posterid})
            tempresult = c.fetchone()
            user = User(None,tempresult['nickname'],None)
            user.reputation = tempresult['reputation']
            user.id = tempresult['id']
            temppost.poster = user
            posts.append(temppost)
        return posts
    @staticmethod
    def get_deadpool_posts(limit = configure.POSTNUMBER_PER_PAGE, offset =0):
        c = g.db.cursor()
        c.execute("SELECT * FROM post WHERE julianday('now') - julianday(post_date) > :save_post_days AND posterid is not NULL\
                    ORDER BY post_date DESC LIMIT :limit OFFSET :offset",\
                                {"limit":limit,"offset":offset*limit,'save_post_days':configure.POST_SAVE})
        result = c.fetchall()
        posts = []
        for post in result:
            temppost = Post(post['title'], post['link'],post['des'],post['post_date'])
            temppost.id = post['id']
            temppost.posterid = post['posterid']
            c.execute("SELECT nickname, id,reputation FROM user where id=:id",\
                                {"id":temppost.posterid})
            tempresult = c.fetchone()
            user = User(None,tempresult['nickname'],None)
            user.reputation = tempresult['reputation']
            user.id = tempresult['id']
            temppost.poster = user
            posts.append(temppost)
        return posts
    @staticmethod
    def delete_byid(id):
        c = g.db.cursor()
        c.execute("DELETE FROM post WHERE id=:id",\
                                {'id':id})
        g.db.commit()
    def save(self):
        c = g.db.cursor()
        self.link = self.link.strip()
        if(not self.link.startswith('http://')):
            self.link = 'http://' + self.link
        c.execute("INSERT INTO post(title,link,des,post_date,posterid) VALUES (?,?,?,?,?)",\
                                (self.title,self.link,self.des,datetime.datetime.now(),session['user'].id))
        self.id = c.lastrowid
        g.db.commit()
        
    def special_save(self):
        c = g.db.cursor()
        self.link = self.link.strip()
        c.execute("INSERT INTO post(title,link,post_date) VALUES (?,?,?)",\
                                (self.title,self.link,datetime.datetime.now()))
        self.id = c.lastrowid
        g.db.commit()
    @property
    def domain(self):
        import urlparse
        rv = urlparse.urlparse(self.link).netloc
        if rv.startswith("www."):
            rv = rv[4:]
        return rv
    @property
    def score(self):
        c = g.db.cursor()
        c.execute("SELECT popularity FROM vote WHERE postid=:id",{'id':self.id})
        scores = [x['popularity'] for x in c.fetchall()]
        return sum(scores)
    @property
    def comments_number(self):
        c = g.db.cursor()
        c.execute("SELECT COUNT(*) AS number FROM comment WHERE postid=:id",{'id':self.id})
        result = c.fetchone()
        number = result['number'] if result else 0
        return number
    def __init__(self, userid, posterid, popularity = 0):
        self.userid = userid
        self.postid = postid
        self.popularity = popularity
    def __init__(self, postid, content, userid, parentid = None):
        self.id = None
        self.postid = postid
        self.content = content
        self.userid = userid
        self.poster =None
        self.parentid = parentid
        self.create_date =None
        self.children = []
    def save(self):
        c = g.db.cursor()
        self.create_date = datetime.datetime.now()
        c.execute("INSERT INTO comment(postid,content,userid,parentid,create_date) VALUES (?,?,?,?,?)",\
                                (self.postid,self.content,self.userid,self.parentid,self.create_date))
        self.id = c.lastrowid
        g.db.commit()
    @staticmethod
    def get_comments_by_postid(postid):
        c = g.db.cursor()
        c.execute("SELECT * FROM comment WHERE postid=:id AND parentid is NULL ORDER BY create_date",{'id':postid})
        result = c.fetchall()
        comments = []
        for tempvalue in result:
            tempcomment = Comment(tempvalue['postid'],tempvalue['content'],tempvalue['userid'],tempvalue['parentid'])
            tempcomment.id = tempvalue['id']
            tempcomment.create_date = tempvalue['create_date']
            tempcomment.init_comment_poster()
            tempcomment.init_children()
            comments.append(tempcomment)
        return comments
    def init_comment_poster(self):
        self.poster = User.get_user_by_id(self.userid)
    def init_children(self):
        c = g.db.cursor()
        c.execute("SELECT * FROM comment WHERE parentid=:id ORDER BY create_date",{'id':self.id})
        result = c.fetchall()
        for tempvalue in result:
            if(tempvalue['parentid'] == tempvalue['postid']):
                break
            tempcomment = Comment(tempvalue['postid'],tempvalue['content'],tempvalue['userid'],tempvalue['parentid'])
            tempcomment.id = tempvalue['id']
            tempcomment.create_date = tempvalue['create_date']
            tempcomment.init_comment_poster()
            tempcomment.init_children()
            self.children.append(tempcomment)
    def save_to_parent(self):
        pass
    def __init__(self, info, userid):
        self.info = info
        self.userid = userid
        self.create_date = None
    def save(self):
        c = g.db.cursor()
        self.create_date = datetime.datetime.now()
        c.execute("INSERT INTO activity(info,create_date,userid) VALUES (?,?,?)",\
                                (self.info, self.create_date,self.userid))
        self.id = c.lastrowid
        g.db.commit()
    @staticmethod
    def get_activities_byuserid(id, limit = configure.ActivityNUMBER_PER_PAGE, offset = 0):
        c = g.db.cursor()
        c.execute("SELECT * FROM activity ORDER BY create_date DESC LIMIT :limit OFFSET :offset",\
                                {"limit":limit,"offset":offset*limit})
        result = c.fetchall()
        activities = []
        for activity in result:
            tempac = Activity(activity['info'], activity['userid'])
            tempac.create_date = activity['create_date']
            tempac.id = activity['id']
            activities.append(tempac)
        return activities
        
    
        
        
        
        
+# -*- coding: utf-8 *-*
    def __init__(self,email,nickname,password):
        self.id = None
        self.email = email
        self.nickname = nickname
        self.avatar = None
        self.password = not password or hashlib.sha224(password).hexdigest()
        self.create_date = None
        self.reputation = None
    def get_nickname(self):
        c = g.db.cursor()
        c.execute("SELECT nickname FROM user WHERE email=:email",\
                                {'email':self.email})
        return c.fetchone()['nickname']
    @staticmethod
    def get_avatar_by_id(id):
        c = g.db.cursor()
        c.execute("SELECT avatar FROM user WHERE id=:id",\
                                {'id':id})
        return c.fetchone()['avatar']
    @staticmethod
    def get_user_by_id(id):
        c = g.db.cursor()
        c.execute("SELECT * FROM user WHERE id=:id",\
                                {'id':id})
        result = c.fetchone()
        tempuser = User(result['email'],result['nickname'],None)
        tempuser.avatar = result['avatar']
        tempuser.create_date = result['create_date']
        tempuser.reputation = result['reputation']
        return tempuser
    @staticmethod
    def change_avatar_by_id(id,avatar):
        c = g.db.cursor()
        c.execute("UPDATE user SET avatar = :avatar WHERE id=:id",\
                                {'id':id,'avatar':avatar})
        g.db.commit()
    def is_valid(self):
        c = g.db.cursor()
        c.execute("SELECT * FROM user WHERE email=:email AND password=:password",\
                                {'email':self.email,'password':self.password})
        tempuser = c.fetchone()
        if(not tempuser):
            return False
        self.id = tempuser['id']
        self.email = tempuser['email']
        self.nickname = tempuser['nickname']
        self.avatar = tempuser['avatar']
        self.create_date = tempuser['create_date']
        self.reputation = tempuser['reputation']
        return True
    def is_email_exsit(self):
        c = g.db.cursor()
        c.execute("SELECT nickname FROM user WHERE email=:email",\
                                {'email':self.email})
        if(not c.fetchone()):
            return False
        return True
    def is_nickname_exsit(self):
        c = g.db.cursor()
        c.execute("SELECT nickname FROM user WHERE nickname=:nickname",\
                                {'nickname':self.nickname})
        if(not c.fetchone()):
            return False
        return True
    def is_exist(self):
        c = g.db.cursor()
        c.execute("SELECT nickname FROM user WHERE email=:email or nickname=:nickname",\
                                {'email':self.email,'nickname':self.nickname})
        if(not c.fetchone()):
            return False
        return True
    def update(self):
        c = g.db.cursor()
        self.create_date = datetime.datetime.now()
        c.execute("UPDATE user SET nickname =:nickname, email =:email,\
                   avatar =:avatar, reputation=:reputation WHERE id=:id",\
                                {"nickname":self.nickname,"email":self.email,"avatar":self.avatar,"reputation":self.reputation,"id":self.id})
        g.db.commit()
    def save(self):
        c = g.db.cursor()
        self.create_date = datetime.datetime.now()
        self.reputation = 0
        c.execute("INSERT INTO user(nickname,email,password,create_date,reputation) VALUES (?,?,?,?,?)",\
                                (self.nickname,self.email,self.password,self.create_date,self.reputation))
        self.id = c.lastrowid
        g.db.commit()
    def vote_for(self,postid):
        c = g.db.cursor()
        if(self.reputation is None):
            c.execute("SELECT reputation FROM user WHERE id=:id",{'id':self.id})
            self.reputation = c.fetchone()['reputation']
        import math
        score = 0
        if(self.reputation > 2):
            score = int(math.log(self.reputation , 2))
        c.execute("INSERT OR REPLACE INTO vote(userid, postid, popularity) VALUES (?,?,?)",(self.id,postid,score))
        g.db.commit()
    @staticmethod
    def password_generate(size=8, chars=string.ascii_letters + string.digits):
        return ''.join(random.choice(chars) for x in range(size))
    @staticmethod
    def reset_password_for(email):
        c = g.db.cursor()
        c.execute("SELECT nickname FROM user WHERE email=:email",\
                                {'email':email})
        if(not c.fetchone()):
            return None
        password = User.password_generate()
        md5pw = hashlib.sha224(password).hexdigest()
        c.execute("UPDATE user SET password =:password WHERE email=:email",\
                                {'email':email,'password':md5pw})
        g.db.commit()
        return password
        
    def create_post_activity(self, points, postid):
        info = "<span>You post a post and gain 2 point</span>"
        tempac = Activity(info,self.id)
        tempac.save()
    def __init__(self, title, link, des, post_date = None):
        self.id = None
        self.title = title
        self.link = link
        self.des = des
        self.post_date = post_date
        self.posterid = None
        self.poster = None
    @staticmethod
    def get_post_byid(id):
        c = g.db.cursor()
        c.execute("SELECT * FROM post WHERE id=:id",\
                                {"id":id})
        post = c.fetchone()
        if(post is None):
            return None
        temppost = Post(post['title'], post['link'],post['des'],post['post_date'])
        temppost.id = post['id']
        temppost.posterid = post['posterid']
        return temppost
        
    @staticmethod
    def is_exist(id):
        c = g.db.cursor()
        c.execute("SELECT id FROM post WHERE id=:id",\
                                {"id":id})
        return  c.fetchone() is not None
    def init_post_poster(self):
        c = g.db.cursor()
        c.execute("SELECT nickname, id,reputation FROM user where id=:id",\
                                {"id":self.posterid})
        tempresult = c.fetchone()
        user = User(None,tempresult['nickname'],None)
        user.reputation = tempresult['reputation']
        user.id = tempresult['id']
        self.poster = user
    @staticmethod
    def get_posts_by_postdate(limit = configure.POSTNUMBER_PER_PAGE, offset =0):
        c = g.db.cursor()
        c.execute("SELECT * FROM post WHERE posterid is not NULL ORDER BY post_date DESC LIMIT :limit OFFSET :offset ",\
                                {"limit":limit,"offset":offset*limit})
        result = c.fetchall()
        posts = []
        for post in result:
            temppost = Post(post['title'], post['link'],post['des'],post['post_date'])
            temppost.id = post['id']
            temppost.posterid = post['posterid']
            c.execute("SELECT nickname, id,reputation FROM user where id=:id",\
                                {"id":temppost.posterid})
            tempresult = c.fetchone()
            user = User(None,tempresult['nickname'],None)
            user.reputation = tempresult['reputation']
            user.id = tempresult['id']
            temppost.poster = user
            posts.append(temppost)
        return posts
    @staticmethod
    def get_hot_posts(limit = configure.POSTNUMBER_PER_PAGE, offset =0):
        c = g.db.cursor()
        c.execute("SELECT * FROM post WHERE julianday('now') - julianday(post_date) <= :save_post_days AND posterid is not NULL\
                   LIMIT :limit OFFSET :offset",\
                                {"limit":limit,"offset":offset*limit,'save_post_days':configure.POST_SAVE})
        result = c.fetchall()
        posts = []
        for post in result:
            temppost = Post(post['title'], post['link'],post['des'],post['post_date'])
            temppost.id = post['id']
            temppost.posterid = post['posterid']
            c.execute("SELECT nickname, id,reputation FROM user where id=:id",\
                                {"id":temppost.posterid})
            tempresult = c.fetchone()
            user = User(None,tempresult['nickname'],None)
            user.reputation = tempresult['reputation']
            user.id = tempresult['id']
            temppost.poster = user
            posts.append(temppost)
        return posts
    @staticmethod
    def get_deadpool_posts(limit = configure.POSTNUMBER_PER_PAGE, offset =0):
        c = g.db.cursor()
        c.execute("SELECT * FROM post WHERE julianday('now') - julianday(post_date) > :save_post_days AND posterid is not NULL\
                    ORDER BY post_date DESC LIMIT :limit OFFSET :offset",\
                                {"limit":limit,"offset":offset*limit,'save_post_days':configure.POST_SAVE})
        result = c.fetchall()
        posts = []
        for post in result:
            temppost = Post(post['title'], post['link'],post['des'],post['post_date'])
            temppost.id = post['id']
            temppost.posterid = post['posterid']
            c.execute("SELECT nickname, id,reputation FROM user where id=:id",\
                                {"id":temppost.posterid})
            tempresult = c.fetchone()
            user = User(None,tempresult['nickname'],None)
            user.reputation = tempresult['reputation']
            user.id = tempresult['id']
            temppost.poster = user
            posts.append(temppost)
        return posts
    @staticmethod
    def delete_byid(id):
        c = g.db.cursor()
        c.execute("DELETE FROM post WHERE id=:id",\
                                {'id':id})
        g.db.commit()
    def save(self):
        c = g.db.cursor()
        self.link = self.link.strip()
        if(not self.link.startswith('http')):
            self.link = 'http://' + self.link
        c.execute("INSERT INTO post(title,link,des,post_date,posterid) VALUES (?,?,?,?,?)",\
                                (self.title,self.link,self.des,datetime.datetime.now(),session['user'].id))
        self.id = c.lastrowid
        g.db.commit()
        
    def special_save(self):
        c = g.db.cursor()
        self.link = self.link.strip()
        c.execute("INSERT INTO post(title,link,post_date) VALUES (?,?,?)",\
                                (self.title,self.link,datetime.datetime.now()))
        self.id = c.lastrowid
        g.db.commit()
    @property
    def domain(self):
        import urlparse
        rv = urlparse.urlparse(self.link).netloc
        if rv.startswith("www."):
            rv = rv[4:]
        return rv
    @property
    def score(self):
        c = g.db.cursor()
        c.execute("SELECT popularity FROM vote WHERE postid=:id",{'id':self.id})
        scores = [x['popularity'] for x in c.fetchall()]
        return sum(scores)
    @property
    def comments_number(self):
        c = g.db.cursor()
        c.execute("SELECT COUNT(*) AS number FROM comment WHERE postid=:id",{'id':self.id})
        result = c.fetchone()
        number = result['number'] if result else 0
        return number
    def __init__(self, userid, posterid, popularity = 0):
        self.userid = userid
        self.postid = postid
        self.popularity = popularity
    def __init__(self, postid, content, userid, parentid = None):
        self.id = None
        self.postid = postid
        self.content = content
        self.userid = userid
        self.poster =None
        self.parentid = parentid
        self.create_date =None
        self.children = []
    def save(self):
        c = g.db.cursor()
        self.create_date = datetime.datetime.now()
        c.execute("INSERT INTO comment(postid,content,userid,parentid,create_date) VALUES (?,?,?,?,?)",\
                                (self.postid,self.content,self.userid,self.parentid,self.create_date))
        self.id = c.lastrowid
        g.db.commit()
    @staticmethod
    def get_comments_by_postid(postid):
        c = g.db.cursor()
        c.execute("SELECT * FROM comment WHERE postid=:id AND parentid is NULL ORDER BY create_date",{'id':postid})
        result = c.fetchall()
        comments = []
        for tempvalue in result:
            tempcomment = Comment(tempvalue['postid'],tempvalue['content'],tempvalue['userid'],tempvalue['parentid'])
            tempcomment.id = tempvalue['id']
            tempcomment.create_date = tempvalue['create_date']
            tempcomment.init_comment_poster()
            tempcomment.init_children()
            comments.append(tempcomment)
        return comments
    def init_comment_poster(self):
        self.poster = User.get_user_by_id(self.userid)
    def init_children(self):
        c = g.db.cursor()
        c.execute("SELECT * FROM comment WHERE parentid=:id ORDER BY create_date",{'id':self.id})
        result = c.fetchall()
        for tempvalue in result:
            if(tempvalue['parentid'] == tempvalue['postid']):
                break
            tempcomment = Comment(tempvalue['postid'],tempvalue['content'],tempvalue['userid'],tempvalue['parentid'])
            tempcomment.id = tempvalue['id']
            tempcomment.create_date = tempvalue['create_date']
            tempcomment.init_comment_poster()
            tempcomment.init_children()
            self.children.append(tempcomment)
    def save_to_parent(self):
        pass
    def __init__(self, info, userid):
        self.info = info
        self.userid = userid
        self.create_date = None
    def save(self):
        c = g.db.cursor()
        self.create_date = datetime.datetime.now()
        c.execute("INSERT INTO activity(info,create_date,userid) VALUES (?,?,?)",\
                                (self.info, self.create_date,self.userid))
        self.id = c.lastrowid
        g.db.commit()
    @staticmethod
    def get_activities_byuserid(id, limit = configure.ActivityNUMBER_PER_PAGE, offset = 0):
        c = g.db.cursor()
        c.execute("SELECT * FROM activity ORDER BY create_date DESC LIMIT :limit OFFSET :offset",\
                                {"limit":limit,"offset":offset*limit})
        result = c.fetchall()
        activities = []
        for activity in result:
            tempac = Activity(activity['info'], activity['userid'])
            tempac.create_date = activity['create_date']
            tempac.id = activity['id']
            activities.append(tempac)
        return activities
        
    
        
        
        
        

pybook/templates/booklist.html

 padding: 20px 0;
 }
 .reporterror{
-margin-left: 7px;
+margin-left: 15px;
 }
 </style>
 <table id='booklist'>
                 <table>
                     <tr>
                         <td style='width:88px;'>书名:</td>
-                        <td style='width:488px;'><a href='showbook?id={{book.id}}'>{{book.title}}</a></td>
+                        <td style='width:488px;'>
+                            <span class='span5'><a href='showbook?id={{book.id}}'>{{book.title}}</a></span>
+                            <span class='span1'><a class="btn btn-small" href=""><i class="icon-star"></i></a></span>
+                        </td>
                     </tr>
                     <tr>
                         <td>作者:</td>
-                        <td>{{book.author}}</td>
+                        <td><span class='span5'>{{book.author}}</span></td>
                     </tr>
                     {%if book.subtitle%}
                     <tr>
                 </table>
                 </div>
         <td style='border:none'>
-            <p><a href='download?id={{book.id}}' class='btn btn-primary btn-large'>Download</a></p>
+            <p><a href='download?id={{book.id}}' class='btn btn-primary btn-large'><i class='icon-download-alt icon-white'></i> Download</a></p>
             <a href='report?id={{book.id}}' class='btn btn-danger btn-small reporterror'>Report Error</a>
         </td>
 
 
 <div class="pagination pagination-centered">
   <ul>
-    {%if currentpage==1%} 
+    {%if currentpage==1%}
         <li  class="disabled"><a>Prev</a></li>
     {%else%}
         <li ><a href='./{{currentpage-1}}'>Prev</a></li>
     {%endif%}
-    
+
     {%for i in pages%}
         {%if i == currentpage%}
             <li class="active"><a>{{i}}</a></li>
             <li><a href="./{{i}}">{{i}}</a></li>
         {%endif%}
     {%endfor%}
-    {%if currentpage==9%} 
+    {%if currentpage==9%}
          <li class="disabled"><a >Next</a></li>
     {%else%}
          <li><a href="./{{currentpage+1}}">Next</a></li>
     {%endif%}
-    
-    
-   
+
+
+
   </ul>
 </div>
 {% endblock %}
 
+{% block extra_info %}
+<span class='span4 offset3' style='margin-top:10px'>
+<a href='' class ='text-warning'>下载文件出错解决办法</a>
+</span>
+
+{% endblock %}
+
 {% block script %}
 $(document).ready(function(){
      $("#nav_book").addClass("active");

pybook/templates/showbook.html

             <table>
                 <tr>
                     <td style='width:88px;'>书名:</td>
-                    <td style='width:488px;'>{{book.title}}</td>
+                    <td style='width:488px;'>                            
+                        <span class='span5'><a href='showbook?id={{book.id}}'>{{book.title}}</a></span>
+                        <span class='span1'><a class="btn btn-small" href=""><i class="icon-star"></i></a></span>
+                    
+                    </td>
                 </tr>
                 <tr>
                     <td>作者:</td>

templates/base.html

           <button type="button" class="close" data-dismiss="alert">×</button>
           <label id="alertmassage"></label>
         </div>
+        {% block extra_info %}{% endblock %}
+        
         </div>
     {% block content %}{% endblock %}
     </div>

templates/news.html

 <style type="text/css">
 #posts li {
 margin: 10px 0;
+padding-bottom: 40px;
+}
+.span0{
+margin: 10px -5px 0 25px;
 }
 </style>
+<div class="btn-toolbar offset1">
+  <div class="btn-group">
+    <a class="btn" href="#"><i class="icon-align-left"></i></a>
+    <a class="btn" href="#"><i class="icon-align-center"></i></a>
+    <a class="btn" href="#"><i class="icon-align-right"></i></a>
+    <a class="btn" href="#"><i class="icon-align-justify"></i></a>
+  </div>
+</div>
+
+
 <ul id="posts" class='unstyled'>
     {%for post in posts%}
-        {%if post.des=="" %}
-            <li>
-            
-            <a class="arrow-top" href='/useraction/vote?postid={{post.id}}'></a>
+        <li>
+        <span class ='span0'><i class="icon-thumbs-up"></i></span>
+        {%if not post.des %}
+
+        <div class = 'span11'>
             <div><a href="{{post.link}}" class="public">{{post.title}}</a>
                 {%if post.domain !="" %}
-                    <span class="domain">→ {{post.domain}}</span>
+                    <span class="domain muted" >→ {{post.domain}}</span>
                 {%endif%}
             </div>
-            <span class="post-info">
-                <a href="/showpost?id={{post.id}}">Comments ({{post.comments_number}})</a> | 
-                Score <span id="score-1">{{post.score}}</span> | 
-                Posted {{post.post_date|timesince}} by 
-                <a href="/user?id={{post.poster.id}}">{{post.poster.nickname}}</a> 
-            </span>    
-            </li>
+
         {%else%}
-            <li>
-                <a class="arrow-top" href='/useraction/vote?postid={{post.id}}'></a>
                 <div><a href="/showpost?id={{post.id}}" class="public">{{post.title}}</a></div>
-                <span class="post-info">
-                <a href="/showpost?id={{post.id}}">Comments ({{post.comments_number}})</a> | 
-                Score <span id="score-1">{{post.score}}</span> | 
-                Posted {{post.post_date|timesince}} by 
-                <a href="/user?id={{post.poster.id}}">{{post.poster.nickname}}</a> 
-                </span>    
-            </li>
         {%endif%}
+            
+            <small><span class="post-info muted">
+            <a href="/showpost?id={{post.id}}" class='muted'>Comments ({{post.comments_number}})</a> |
+            Score <span id="score-1">{{post.score}}</span> |
+            Posted {{post.post_date|timesince}} by
+            <a href="/user?id={{post.poster.id}}" class='muted'>{{post.poster.nickname}}</a>
+            </span></small>
+        </div>
+        </li>
+
     {%endfor%}
 </ul>
+
 <ul class="pager">
 {%if posts.__len__() == POSTNUMBER_PER_PAGE %}
   <li class="previous">
   </li>
 {%else%}
     <li>
-          <a style="width:100%;">No Any Posts Here</a>
+          <a style="width:100%;">No More Posts</a>
     </li>
 {%endif%}
 </ul>

templates/showpost.html

         <span class='post_poster'>Comments ({{post.comments_number}})</span>
     </small>
     </span></div>
-    <p>{{post.des}}</p>
-
+    {%if post.des%}
+        <p>{{post.des}}</p>
+    {%endif%}
 </div>
 
 <div id='sharepost' class='span8 offset1'>

templates/signup.html

 {% extends "base.html" %}
 {% block content %}
-<div id='signup' class='span4 offset2'>
+<div id='signup' class='span5 offset2'>
     <form id='signup_form' method=post>
     <legend>Sign up to {{TITLE}}</legend>
     <table id='signuptable'>

templates/static_footer.html

 <footer id="footer" class='muted' style="text-align: center;">
     <p>Power By <a href='http://twitter.github.com/bootstrap/'>BootStrap</a> & 
             <a href='http://flask.pocoo.org/'>Flask</a></p>
-    <p><a href="">Code</a> & Design by <a>Yang</a></p>
+    <p><a href="https://bitbucket.org/zhy0216/py4u-opensource">Code</a> & Design by <a>Yang</a></p>
 </footer>