Commits

izp  committed 5c829e1

add all files

  • Participants

Comments (0)

Files changed (8)

File __init__.py

Empty file added.
+# -*- coding: utf-8 -*-
+
+"""
+    config.py
+    ~~~~~~~~~~~
+
+    basic configuration
+
+    :copyright: (c) 2013.
+    :license: BSD, see LICENSE for more details.
+"""
+
+
+DEBUG = True
+
+# configuration page num
+PER_PAGE = 10
+
+# configuration mysql
+SQLALCHEMY_DATABASE_URI = "mysql://%s:%s@%s/%s" % ('root', 'root', '127.0.0.1', 'test')
+
+SECRET_KEY = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'
+USERNAME = 'admin'
+PASSWORD = 'admin'
+
+UPLOAD_FOLDER = '/static/upload/'
+ALLOWED_EXTENSIONS = set(['txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'])
+
+RECAPTCHA_PUBLIC_KEY = '6LeJTt8SAAAAACuSjRrt3a2jgGX-xQBREEAXw9Rs'
+RECAPTCHA_PRIVATE_KEY = '6LeJTt8SAAAAACjz_N65vlf9yuscktZZjOIEISFA'
+# -*- coding: utf-8 -*-
+"""
+    form.py
+    ~~~~~~~~~~~
+
+    comment form
+
+    :copyright: (c) 2013.
+    :license: BSD, see LICENSE for more details.
+"""
+
+from flask.ext.wtf import Form, SubmitField, TextField, required, length, TextAreaField, email, RecaptchaField, HiddenField
+
+
+class CommentForm(Form):
+    author_name = TextField(u'Name', validators=[required(message=u"Need an name"), length(max=50)])
+    author_email = TextField(u"Email", validators=[
+                             required(message=u"Need an email address"),
+                             email(message=u"Need a valid email address")])
+    author_url = TextField(u"Url")
+    content = TextAreaField(u"Content")
+    post_id = TextField()
+    recaptcha = RecaptchaField(u"Copy the words appearing below")
+    submit = SubmitField(u"Save")
+# -*- coding: utf-8 -*-
+"""
+    manager.py
+    ~~~~~~~~~~~
+
+    flask manager script
+
+    :copyright: (c) 2013.
+    :license: BSD, see LICENSE for more details.
+"""
+from flask.ext.script import Server, Manager, prompt_bool
+from myapp import app
+from model import db
+
+manager = Manager(app)
+manager.add_command("runserver", Server('0.0.0.0', port=5000))
+
+
+@manager.command
+def createall():
+    "Creates database tables"
+    db.create_all()
+
+
+@manager.command
+def dropall():
+    "Drops all database tables"
+
+    if prompt_bool("Are you sure ? You will lose all your data !"):
+        db.drop_all()
+
+if __name__ == "__main__":
+    manager.run()
+# -*- coding: utf-8 -*-
+from flask import url_for
+from flask.ext.sqlalchemy import SQLAlchemy, BaseQuery
+from werkzeug import cached_property
+from datetime import datetime
+from myapp import app
+
+db = SQLAlchemy(app)
+
+
+class CategoryQuery(BaseQuery):
+
+    def getall(self):
+        return self.all()
+
+    def getcategory_id(self, id):
+        return self.get(id)
+
+
+class Category(db.Model):
+    __tablename__ = 'category'
+    query_class = CategoryQuery
+    id = db.Column(db.Integer, primary_key=True)
+    category_name = db.Column(db.String(200), unique=True)
+
+    def __init__(self, *args, **kwargs):
+        super(Category, self).__init__(*args, **kwargs)
+
+    def __repr__(self):
+        return '<category name %r>' % self.category_name
+
+
+article_tags = db.Table('tags',
+                        db.Column(
+                            'tag_id', db.Integer, db.ForeignKey('tag.id')),
+                        db.Column(
+                            'post_id', db.Integer, db.ForeignKey('post.id')),
+                        )
+
+
+class TagQuery(BaseQuery):
+
+    def getall(self):
+        return self.all()
+
+    def gettag_id(self, id):
+        return self.get(id)
+
+
+class Tag(db.Model):
+    __tablename__ = 'tag'
+    query_class = TagQuery
+    id = db.Column(db.Integer, primary_key=True)
+    name = db.Column(db.String(50))
+
+    #post = db.relationship('Post', secondary=article_tags)
+
+    def __init__(self, *args, **kwargs):
+        super(Tag, self).__init__(*args, **kwargs)
+
+    def __repr__(self):
+        return '<tag name %r>' % self.name
+
+
+class PostQuery(BaseQuery):
+
+    def getpost_id(self, id):
+        return self.get(id)
+
+    def getall(self):
+        return self.all()
+
+    def getpost_byname(self, name):
+        return self.filter(Post.post_name.ilike(name)).distinct().first()
+
+    def getpost_perpage(self, pageid, per_page):
+        return self.order_by(Post.post_create_time.desc()).paginate(pageid, per_page)
+
+    def hottest(self):
+        return self.order_by(Post.comment_count.desc(), Post.view_num.desc())
+
+    def newpost(self):
+        return self.order_by(Post.post_modified_time.desc())
+
+    def search(self, keywords):
+        criteria = []
+        for keyword in keywords.split():
+            keyword = '%' + keyword + '%'
+            criteria.append(db.or_(Post.post_title.ilike(keyword),
+                                   Post.post_content.ilike(keyword),
+                                   Post.tags_name.ilike(keyword)))
+
+        q = reduce(db.and_, criteria)
+
+        return self.filter(q).distinct()
+
+    def search_tag(self, keywords):
+        criteria = []
+        for keyword in keywords.split():
+            keyword = '%' + keyword + '%'
+            criteria.append(db.or_(Post.tags_name.ilike(keyword)))
+
+        q = reduce(db.and_, criteria)
+
+        return self.filter(q).distinct()
+
+
+class Post(db.Model):
+    __tablename__ = 'post'
+    query_class = PostQuery
+    id = db.Column(db.Integer, primary_key=True)
+    post_content = db.Column(db.Text)
+    post_title = db.Column(db.String(100))
+    post_name = db.Column(db.String(200), unique=True)
+    post_create_time = db.Column(db.DateTime, default=datetime.utcnow)
+    view_num = db.Column(db.Integer, default=0)
+    comment_count = db.Column(db.Integer, default=0)
+    status = db.Column(db.Integer, default=1)
+    author_id = db.Column(db.Integer, default=1)
+    post_modified_time = db.Column(db.DateTime, default=datetime.utcnow)
+    category_id = db.Column(db.Integer, db.ForeignKey('category.id'))
+    categorys = db.relationship('Category', backref=db.backref(
+        'posts', lazy='dynamic'), lazy='select')
+    tags = db.relationship('Tag', secondary=article_tags,
+                           backref=db.backref('posts', lazy='dynamic'))
+    tags_name = db.Column(db.Text)
+
+    def __init__(self, *args, **kwargs):
+        super(Post, self).__init__(*args, **kwargs)
+
+    def __repr__(self):
+        return '<post %r>' % self.post_title
+
+    def _url(self):
+        return url_for('post', name=self.post_name)
+
+    @cached_property
+    def url(self):
+        return self._url()
+
+    @cached_property
+    def comments(self):
+        allcomments = Comment.query.filter(Comment.post_id == self.id).all()
+        return allcomments
+
+
+class CommentQuery(BaseQuery):
+
+    def getall(self):
+        return self.all()
+
+    def getcomment_id(self, id):
+        return self.get(id)
+
+    def newcomment(self):
+        return self.order_by(Comment.comment_create_time.desc())
+
+
+class Comment(db.Model):
+    __tablename__ = 'comment'
+    query_class = CommentQuery
+    id = db.Column(db.Integer, primary_key=True)
+    post_id = db.Column(db.Integer, db.ForeignKey('post.id'))
+    posts = db.relationship('Post', backref=db.backref('comments', lazy='dynamic'))
+    author_name = db.Column(db.String(50))
+    author_email = db.Column(db.String(100))
+    author_url = db.Column(db.String(1024))
+    author_ip = db.Column(db.String(20))
+    comment_create_time = db.Column(db.DateTime, default=datetime.utcnow)
+    content = db.Column(db.Text)
+    isvisible = db.Column(db.Integer, default=1)
+
+    def __init__(self, *args, **kwargs):
+        super(Comment, self).__init__(*args, **kwargs)
+
+    def __repr__(self):
+        return '<comment %r>' % self.content
+
+
+def pageby(obj, pageid, per_page, orderby):
+    return obj.order_by(orderby).paginate(pageid, per_page)
+# -*- coding: utf-8 -*-
+
+from flask import Flask
+app = Flask(__name__)
+app.config.from_object('config')
+from views import *
+if __name__ == '__main__':
+	app.run(host='0.0.0.0', debug=True)
+# -*- coding: utf-8 -*-
+
+"""
+    setup.py
+    ~~~~~~~~~~~
+
+    set up extensions
+
+    :copyright: (c) 2013.
+    :license: BSD, see LICENSE for more details.
+"""
+
+from setuptools import setup
+
+setup(
+    install_requires=[
+        'Flask',
+        'Flask-Cache',
+        'Flask-SQLAlchemy',
+        'Flask-WTF',
+        'Flask-Testing',
+        'Flask-Script',
+        'Flask-Uploads',
+        'sqlalchemy'
+    ]
+
+)
+# -*- coding: utf-8 -*-
+from flask import Flask, render_template, url_for, redirect, request, flash, session, g
+from myapp import app
+from model import article_tags, Category, Post, Tag, Comment, pageby, db
+from werkzeug import secure_filename
+from flask.ext.cache import Cache
+from random import shuffle
+from HTMLParser import HTMLParser
+from re import sub
+from sys import stderr
+from traceback import print_exc
+import os
+import json
+import time
+from form import CommentForm
+
+cache = Cache(app)
+app.config.from_object('config')
+per_page = app.config['PER_PAGE']
+
+
+class _DeHTMLParser(HTMLParser):
+    def __init__(self):
+        HTMLParser.__init__(self)
+        self.__text = []
+
+    def handle_data(self, data):
+        text = data.strip()
+        if len(text) > 0:
+            text = sub('[ \t\r\n]+', ' ', text)
+            self.__text.append(text + ' ')
+
+    def handle_starttag(self, tag, attrs):
+        if tag == 'p':
+            self.__text.append('\n\n')
+        elif tag == 'br':
+            self.__text.append('\n')
+
+    def handle_startendtag(self, tag, attrs):
+        if tag == 'br':
+            self.__text.append('\n\n')
+
+    def text(self):
+        return ''.join(self.__text).strip()
+
+
+def dehtml(text):
+    try:
+        parser = _DeHTMLParser()
+        parser.feed(text)
+        parser.close()
+        return parser.text()
+    except:
+        print_exc(file=stderr)
+        return text
+
+
+def html2textile(html):
+    return dehtml(html)
+
+app.jinja_env.filters['html2textile'] = html2textile
+
+
+def is_chinese(text):
+    if text:
+        for uchar in text:
+            if uchar >= u'\u4e00' and uchar <= u'\u9fa5':
+                return True
+    return False
+
+
+@app.errorhandler(404)
+def page_not_found(e):
+    return render_template('404.html'), 404
+
+
+@app.route('/error/404')
+def error_404():
+    return render_template('404.html'), 404
+
+
+@app.route('/')
+@app.route('/page/<int:pageid>')
+@cache.cached(timeout=300)
+def index(pageid=1):
+    categorys = Category.query.getall()
+
+    p = Post.query.getpost_perpage(pageid, per_page)
+    hot = Post.query.hottest()[:20]
+    new = Post.query.newpost()[:20]
+
+    tag = Tag.query.getall()
+    shuffle(tag)
+    tag = tag[:20]
+
+    comments = Comment.query.newcomment()[:20]
+    articles = p.items
+    if not p.total:
+        pagination = [0]
+    elif p.total % per_page:
+        pagination = range(1, p.total / per_page + 2)
+    else:
+        pagination = range(1, p.total / per_page + 1)
+
+    return render_template('/index.html',
+                           categorys=categorys,
+                           articles=articles,
+                           hotarticles=hot,
+                           newpost=new,
+                           tags=tag,
+                           comments=comments,
+                           pageid=pageid,
+                           pagination=pagination[pageid - 1:pageid + 10],
+                           last_page=pagination[-1],
+                           nav_current="index"
+                           )
+
+
+@app.route('/about')
+@cache.cached(timeout=300)
+def about():
+    categorys = Category.query.getall()
+    hot = Post.query.hottest()[:20]
+    new = Post.query.newpost()[:20]
+
+    tag = Tag.query.getall()
+    shuffle(tag)
+    tag = tag[:20]
+
+    comments = Comment.query.newcomment()[:20]
+
+    return render_template('/about.html',
+                           categorys=categorys,
+                           hotarticles=hot,
+                           newpost=new,
+                           tags=tag,
+                           comments=comments)
+
+
+@app.route('/category/<int:cateid>')
+@app.route('/category/<int:cateid>/page/<int:pageid>')
+@cache.cached(timeout=300)
+def category(cateid=1, pageid=1):
+    categorys = Category.query.getall()
+    hot = Post.query.hottest()[:20]
+    new = Post.query.newpost()[:20]
+    tag = Tag.query.getall()
+    shuffle(tag)
+    tag = tag[:20]
+    comments = Comment.query.newcomment()[:20]
+
+    cate = Category.query.get_or_404(cateid)
+
+    p = pageby(cate.posts, pageid, per_page, Post.post_create_time.desc())
+
+    articles = p.items
+    if not p.total:
+        pagination = [0]
+    elif p.total % per_page:
+        pagination = range(1, p.total / per_page + 2)
+    else:
+        pagination = range(1, p.total / per_page + 1)
+
+    return render_template('/category.html',
+                           id=cateid,
+                           cate=cate,
+                           categorys=categorys,
+                           articles=articles,
+                           hotarticles=hot,
+                           newpost=new,
+                           tags=tag,
+                           comments=comments,
+                           pageid=pageid,
+                           pagination=pagination[pageid - 1:pageid + 10],
+                           last_page=pagination[-1]
+                           )
+
+
+@app.route('/tag/<int:tagid>')
+@app.route('/tag/<int:tagid>/page/<int:pageid>')
+@cache.cached(timeout=300)
+def tag(tagid=1, pageid=1):
+    categorys = Category.query.getall()
+    hot = Post.query.hottest()[:20]
+    new = Post.query.newpost()[:20]
+    tag = Tag.query.getall()
+    shuffle(tag)
+    tag = tag[:20]
+    comments = Comment.query.newcomment()[:20]
+
+    tagall = Tag.query.get_or_404(tagid)
+    name = tagall.name
+    p = Post.query.search_tag(name)
+    p = pageby(p, pageid, per_page, Post.post_create_time.desc())
+
+    articles = p.items
+    if not p.total:
+        pagination = [0]
+    elif p.total % per_page:
+        pagination = range(1, p.total / per_page + 2)
+    else:
+        pagination = range(1, p.total / per_page + 1)
+
+    return render_template('/tag.html',
+                           id=tagid,
+                           tagall=tagall,
+                           categorys=categorys,
+                           articles=articles,
+                           hotarticles=hot,
+                           newpost=new,
+                           tags=tag,
+                           comments=comments,
+                           pageid=pageid,
+                           pagination=pagination[pageid - 1:pageid + 10],
+                           last_page=pagination[-1]
+                           )
+
+
+@app.route('/search')
+@app.route('/search/page/<int:pageid>')
+@cache.cached(timeout=240)
+def search(pageid=1):
+
+    categorys = Category.query.getall()
+    hot = Post.query.hottest()[:20]
+    new = Post.query.newpost()[:20]
+    tag = Tag.query.getall()
+    shuffle(tag)
+    tag = tag[:20]
+    comments = Comment.query.newcomment()[:20]
+
+    searchword = request.args.get('s', '')
+    if not searchword:
+        return redirect(url_for('error_404'))
+
+    searchresult = Post.query.search(searchword)
+
+    p = pageby(searchresult, pageid, per_page, Post.post_create_time.desc())
+
+    articles = p.items
+    if not p.total:
+        pagination = [0]
+    elif p.total % per_page:
+        pagination = range(1, p.total / per_page + 2)
+    else:
+        pagination = range(1, p.total / per_page + 1)
+
+    return render_template('/search.html',
+                           key=searchword,
+                           categorys=categorys,
+                           articles=articles,
+                           hotarticles=hot,
+                           newpost=new,
+                           tags=tag,
+                           comments=comments,
+                           pageid=pageid,
+                           pagination=pagination[pageid - 1:pageid + 10],
+                           last_page=pagination[-1]
+                           )
+
+
+@app.route('/article/<int:postid>')
+@cache.cached(timeout=300)
+def article(postid=5):
+    categorys = Category.query.getall()
+    hot = Post.query.hottest()[:20]
+    new = Post.query.newpost()[:20]
+    tag = Tag.query.getall()
+    shuffle(tag)
+    tag = tag[:20]
+    comments = Comment.query.newcomment()[:20]
+    articles = Post.query.getall()
+    shuffle(articles)
+    articles = articles[:5]
+
+    post = Post.query.get_or_404(postid)
+    form = CommentForm()
+    postcoments = post.comments.all()
+    post.view_num += 1
+    db.session.commit()
+    return render_template('/post.html',
+                           post=post,
+                           articles=articles,
+                           categorys=categorys,
+                           hotarticles=hot,
+                           newpost=new,
+                           tags=tag,
+                           comments=comments,
+                           postcoments=postcoments,
+                           form=form
+                           )
+
+
+@app.route('/<postname>.html')
+@cache.cached(timeout=300)
+def article_byname(postname):
+    categorys = Category.query.getall()
+    hot = Post.query.hottest()[:20]
+    new = Post.query.newpost()[:20]
+    tag = Tag.query.getall()
+    shuffle(tag)
+    tag = tag[:20]
+    comments = Comment.query.getall()[:20]
+    articles = Post.query.getall()
+    shuffle(articles)
+    articles = articles[:5]
+
+    post = Post.query.getpost_byname(postname)
+
+    if not post:
+        return redirect(url_for('error_404'))
+    form = CommentForm()
+    postcoments = post.comments.all()
+    post.view_num += 1
+    db.session.commit()
+
+    return render_template('/post.html',
+                           post=post,
+                           articles=articles,
+                           categorys=categorys,
+                           hotarticles=hot,
+                           newpost=new,
+                           tags=tag,
+                           comments=comments,
+                           postcoments=postcoments,
+                           form=form
+                           )
+
+
+@app.route('/addcomment', methods=['POST'])
+def addcomment():
+    form = CommentForm()
+    error = 'Sorry, Post Comments Error!'
+
+    if form.validate_on_submit():
+        comment = Comment(author_ip=request.environ['HTTP_X_FORWARDED_FOR'])
+        form.populate_obj(comment)
+        db.session.add(comment)
+        post = Post.query.getpost_id(comment.post_id)
+        post.comment_count += 1
+        db.session.commit()
+        return redirect(url_for('article', postid=comment.post_id))
+
+    return render_template('/error.html', content=error)
+
+
+@app.route('/error')
+def error(content='404'):
+    return render_template('/error.html', content=content)
+
+
+@app.route('/login', methods=['GET', 'POST'])
+def login():
+    error = None
+    if request.method == 'POST':
+        if request.form['username'] != app.config['USERNAME']:
+            error = 'Invalid username'
+        elif request.form['password'] != app.config['PASSWORD']:
+            error = 'Invalid password'
+        else:
+            session['logged_in'] = True
+            flash('You were logged in')
+            return redirect(url_for('newpost'))
+    return render_template('login.html')
+
+
+@app.route('/logout')
+def logout():
+    session.pop('logged_in', None)
+    flash('You were logged out')
+    return redirect(url_for('index'))
+
+
+@app.route('/newpost')
+def newpost():
+    categories = Category.query.getall()
+    return render_template('/newpost.html', categories=categories)
+
+
+@app.route('/addpost', methods=['POST'])
+def addpost():
+    if not session.get('logged_in'):
+        abort(401)
+    elif request.method == 'POST':
+        tagtemp = []
+        taglist = request.form['tags'].split(',')
+        for i in taglist:
+            tagtemp.append(Tag(i))
+
+        db.session.add(Post(tagtemp, request.form['content'], request.form['title'], request.form['category'], request.form['postname'], request.form['tags']))
+        db.session.commit()
+
+    return redirect(url_for('newpost'))
+
+
+def allowed_file(filename):
+    return '.' in filename and \
+           filename.rsplit('.', 1)[1] in app.config['ALLOWED_EXTENSIONS']
+
+
+@app.route('/upload', methods=['GET', 'POST'])
+def upload_file():
+    if request.method == 'POST':
+        file = request.files.get('imgFile', None)
+
+        if file and allowed_file(file.filename):
+            filename = str(int(time.time())) + '_' + secure_filename(file.filename)
+            file.save('/home/pythonspace/webapps/pythonpub/htdocs/myblog' + app.config['UPLOAD_FOLDER'] + filename)
+            data = {'error': 0, 'url': app.config['UPLOAD_FOLDER'] + filename}
+            return json.dumps(data)
+    return 'FAIL!'
+
+
+@app.route('/epost', methods=['GET'])
+def epost():
+    num = request.args.get('post', '')
+    if num:
+        p = Post.query.get_or_404(num)
+        return render_template('/editpost.html', p=p)
+    return redirect(url_for('error_404'))
+
+
+@app.route('/apost', methods=['POST'])
+def apost():
+    if not session.get('logged_in'):
+        abort(401)
+    elif request.method == 'POST':
+        p = Post.query.getpost_id(request.form['num'])
+        p.post_title = request.form['title']
+        p.post_name = request.form['postname']
+        p.post_content = request.form['content']
+        db.session.commit()
+    return redirect(url_for('newpost'))