full text search
This commit is contained in:
parent
1886654ff9
commit
8a27076ae4
|
@ -28,3 +28,5 @@ class EditForm(Form):
|
||||||
class PostForm(Form):
|
class PostForm(Form):
|
||||||
post = TextField('post', validators = [Required()])
|
post = TextField('post', validators = [Required()])
|
||||||
|
|
||||||
|
class SearchForm(Form):
|
||||||
|
search = TextField('search', validators = [Required()])
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
from hashlib import md5
|
from hashlib import md5
|
||||||
from app import db
|
from app import db
|
||||||
|
from app import app
|
||||||
|
import flask.ext.whooshalchemy as whooshalchemy
|
||||||
|
|
||||||
ROLE_USER = 0
|
ROLE_USER = 0
|
||||||
ROLE_ADMIN = 1
|
ROLE_ADMIN = 1
|
||||||
|
@ -71,10 +73,14 @@ class User(db.Model):
|
||||||
return '<User %r>' % (self.nickname)
|
return '<User %r>' % (self.nickname)
|
||||||
|
|
||||||
class Post(db.Model):
|
class Post(db.Model):
|
||||||
|
__searchable__ = ['body']
|
||||||
|
|
||||||
id = db.Column(db.Integer, primary_key = True)
|
id = db.Column(db.Integer, primary_key = True)
|
||||||
body = db.Column(db.String(140))
|
body = db.Column(db.String(140))
|
||||||
timestamp = db.Column(db.DateTime)
|
timestamp = db.Column(db.DateTime)
|
||||||
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
|
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return '<Post %r>' % (self.text)
|
return '<Post %r>' % (self.body)
|
||||||
|
|
||||||
|
whooshalchemy.whoosh_index(app, Post)
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
<a href="{{ url_for('index') }}">Home</a>
|
<a href="{{ url_for('index') }}">Home</a>
|
||||||
{% if g.user.is_authenticated() %}
|
{% if g.user.is_authenticated() %}
|
||||||
| <a href="{{ url_for('user', nickname = g.user.nickname) }}">Your Profile</a>
|
| <a href="{{ url_for('user', nickname = g.user.nickname) }}">Your Profile</a>
|
||||||
|
| <form style="display: inline;" action="{{url_for('search')}}" method="post" name="search">{{g.search_form.hidden_tag()}}{{g.search_form.search(size=20)}}<input type="submit" value="Search"></form>
|
||||||
| <a href="{{ url_for('logout') }}">Logout</a>
|
| <a href="{{ url_for('logout') }}">Logout</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
<!-- extend base layout -->
|
||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h1>Search results for "{{query}}":</h1>
|
||||||
|
{% for post in results %}
|
||||||
|
{% include 'post.html' %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endblock %}
|
23
app/views.py
23
app/views.py
|
@ -1,10 +1,10 @@
|
||||||
from flask import render_template, flash, redirect, session, url_for, request, g
|
from flask import render_template, flash, redirect, session, url_for, request, g
|
||||||
from flask.ext.login import login_user, logout_user, current_user, login_required
|
from flask.ext.login import login_user, logout_user, current_user, login_required
|
||||||
from app import app, db, lm, oid
|
from app import app, db, lm, oid
|
||||||
from forms import LoginForm, EditForm, PostForm
|
from forms import LoginForm, EditForm, PostForm, SearchForm
|
||||||
from models import User, ROLE_USER, ROLE_ADMIN, Post
|
from models import User, ROLE_USER, ROLE_ADMIN, Post
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from config import POSTS_PER_PAGE
|
from config import POSTS_PER_PAGE, MAX_SEARCH_RESULTS
|
||||||
|
|
||||||
@lm.user_loader
|
@lm.user_loader
|
||||||
def load_user(id):
|
def load_user(id):
|
||||||
|
@ -17,6 +17,7 @@ def before_request():
|
||||||
g.user.last_seen = datetime.utcnow()
|
g.user.last_seen = datetime.utcnow()
|
||||||
db.session.add(g.user)
|
db.session.add(g.user)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
g.search_form = SearchForm()
|
||||||
|
|
||||||
@app.errorhandler(404)
|
@app.errorhandler(404)
|
||||||
def internal_error(error):
|
def internal_error(error):
|
||||||
|
@ -118,6 +119,7 @@ def edit():
|
||||||
form = form)
|
form = form)
|
||||||
|
|
||||||
@app.route('/follow/<nickname>')
|
@app.route('/follow/<nickname>')
|
||||||
|
@login_required
|
||||||
def follow(nickname):
|
def follow(nickname):
|
||||||
user = User.query.filter_by(nickname = nickname).first()
|
user = User.query.filter_by(nickname = nickname).first()
|
||||||
if user == None:
|
if user == None:
|
||||||
|
@ -136,6 +138,7 @@ def follow(nickname):
|
||||||
return redirect(url_for('user', nickname = nickname))
|
return redirect(url_for('user', nickname = nickname))
|
||||||
|
|
||||||
@app.route('/unfollow/<nickname>')
|
@app.route('/unfollow/<nickname>')
|
||||||
|
@login_required
|
||||||
def unfollow(nickname):
|
def unfollow(nickname):
|
||||||
user = User.query.filter_by(nickname = nickname).first()
|
user = User.query.filter_by(nickname = nickname).first()
|
||||||
if user == None:
|
if user == None:
|
||||||
|
@ -152,3 +155,19 @@ def unfollow(nickname):
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
flash('You have stopped following ' + nickname + '.')
|
flash('You have stopped following ' + nickname + '.')
|
||||||
return redirect(url_for('user', nickname = nickname))
|
return redirect(url_for('user', nickname = nickname))
|
||||||
|
|
||||||
|
@app.route('/search', methods = ['POST'])
|
||||||
|
@login_required
|
||||||
|
def search():
|
||||||
|
if not g.search_form.validate_on_submit():
|
||||||
|
return redirect(url_for('index'))
|
||||||
|
return redirect(url_for('search_results', query = g.search_form.search.data))
|
||||||
|
|
||||||
|
@app.route('/search_results/<query>')
|
||||||
|
@login_required
|
||||||
|
def search_results(query):
|
||||||
|
results = Post.query.whoosh_search(query, MAX_SEARCH_RESULTS).all()
|
||||||
|
return render_template('search_results.html',
|
||||||
|
query = query,
|
||||||
|
results = results)
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@ OPENID_PROVIDERS = [
|
||||||
|
|
||||||
SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'app.db')
|
SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'app.db')
|
||||||
SQLALCHEMY_MIGRATE_REPO = os.path.join(basedir, 'db_repository')
|
SQLALCHEMY_MIGRATE_REPO = os.path.join(basedir, 'db_repository')
|
||||||
|
WHOOSH_BASE = os.path.join(basedir, 'search.db')
|
||||||
|
|
||||||
# mail server settings
|
# mail server settings
|
||||||
MAIL_SERVER = 'localhost'
|
MAIL_SERVER = 'localhost'
|
||||||
|
@ -25,4 +26,4 @@ ADMINS = ['you@example.com']
|
||||||
|
|
||||||
# pagination
|
# pagination
|
||||||
POSTS_PER_PAGE = 3
|
POSTS_PER_PAGE = 3
|
||||||
|
MAX_SEARCH_RESULTS = 50
|
||||||
|
|
Loading…
Reference in New Issue