Skip to content
Snippets Groups Projects
Commit 38b281c5 authored by Xingchen Zhou's avatar Xingchen Zhou
Browse files

Initial commit

parents
No related branches found
No related tags found
No related merge requests found
Showing
with 286 additions and 0 deletions
.DS_Store 0 → 100644
File added
APP_CONFIG=config.py
# Blog Page
To support the UI, our website is using the template and source code from:
Template:
https://www.free-css.com/free-css-templates/page259/fluffster
Rating:
https://bbbootstrap.com/snippets/bootstrap-rating-star-inputs-using-jquery-22603699
Checksum:
\ No newline at end of file
File added
File added
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager
app = Flask(__name__)
# app.config['SECRET_KEY'] = 'root'
# app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:root@172.17.0.3:3306/blog'
app.config['SECRET_KEY'] = '0002987XGZhy'
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://c2089762:0002987XGZhy@csmysql.cs.cf.ac.uk:3306/c2089762_blog'
db = SQLAlchemy(app)
login_manager = LoginManager()
login_manager.init_app(app)
from blog import routes
from flask_admin import Admin
from blog.views import AdminView
from blog.models import User, Post, Comment
admin = Admin(app,name='Admin panel',template_mode='bootstrap3')
admin.add_view(AdminView(User, db.session))
admin.add_view(AdminView(Post, db.session))
admin.add_view(AdminView(Comment, db.session))
File added
File added
File added
File added
File added
File added
File added
File added
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import DataRequired, Length, Email, EqualTo, ValidationError, InputRequired, Regexp
from blog.models import User
class RegistrationForm(FlaskForm):
username = StringField('Username',validators=[DataRequired(),Length(min=3,max=15)])
email = StringField('Email',validators=[DataRequired(),Email()])
password = PasswordField('Password',validators=[DataRequired(),Regexp('^.{6,8}$',message='Your password should be between 6 and 8 characters long.')])
confirm_password = PasswordField('Confirm Password',validators=[DataRequired(),EqualTo('password', message='Passwords do not match.')])
submit = SubmitField('Register')
def validate_username(self, username):
user = User.query.filter_by(username=username.data).first()
if user is not None:
raise ValidationError('Username already exist. Please choose a different one.')
def validate_email(self,email):
user = User.query.filter_by(email=email.data).first()
if user is not None:
raise ValidationError('Email address is already associated with an account.')
class LoginForm(FlaskForm):
email = StringField('Email',validators=[DataRequired(),Email()])
password = PasswordField('Password',validators=[DataRequired()])
submit = SubmitField('Login')
class CommentForm(FlaskForm):
comment = StringField('Comment',validators=[InputRequired()])
submit = SubmitField('Post comment')
class RateForm(FlaskForm):
rate = StringField('Rate',validators=[InputRequired()])
submit = SubmitField('Rate comment')
class PostForm(FlaskForm):
post = StringField('Post',validators=[InputRequired()])
\ No newline at end of file
from datetime import datetime
from blog import db, login_manager
from werkzeug.security import generate_password_hash, check_password_hash
from flask_login import UserMixin
class Post(db.Model):
id = db.Column(db.Integer, primary_key=True)
date = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
title = db.Column(db.Text, nullable=False)
content = db.Column(db.Text, nullable=False)
image_file = db.Column(db.String(40), nullable=False, default='default.jpg')
author_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
def __repr__(self):
return f"Post('{self.date}', '{self.title}', '{self.content}')"
class User(UserMixin,db.Model):
id=db.Column(db.Integer,primary_key=True)
username=db.Column(db.String(15),unique=True,nullable=False)
email=db.Column(db.String(120),unique=True,nullable=False)
password_hash=db.Column(db.String(128))
password=db.Column(db.String(60),nullable=False)
post=db.relationship('Post',backref='user',lazy=True)
comment=db.relationship('Comment',backref='user',lazy=True)
is_admin=db.Column(db.Boolean,nullable=False,default=False)
def __repr__(self):
return f"User('{self.username}','{self.email}')"
@property
def password(self):
raise AttributeError('password is not a readable attribute')
@password.setter
def password(self,password):
self.password_hash=generate_password_hash(password)
def verify_password(self,password):
return check_password_hash(self.password_hash,password)
@login_manager.user_loader
def load_user(user_id):
return User.query.get(int(user_id))
class Comment(db.Model):
id = db.Column(db.Integer,primary_key=True)
date = db.Column(db.DateTime,nullable=False,default=datetime.utcnow)
content = db.Column(db.Text,nullable=False)
parent_id = db.Column(db.Integer,db.ForeignKey('comment.id'),nullable=True)
post_id = db.Column(db.Integer,db.ForeignKey('post.id'),nullable=False)
author_id = db.Column(db.Integer,db.ForeignKey('user.id'),nullable=False)
parent = db.relationship('Comment',backref='comment_parent',remote_side=id,lazy=True)
def __repr__(self):
return f"Post('{self.date}','{self.content}')"
class Rate(db.Model):
# id = db.Column(db.Integer,primary_key=True)
date = db.Column(db.DateTime,nullable=False,default=datetime.utcnow)
rateValue = db.Column(db.Integer,nullable=False)
post_id = db.Column(db.Integer,db.ForeignKey('post.id'),nullable=False, primary_key=True)
author_id = db.Column(db.Integer,db.ForeignKey('user.id'),nullable=False, primary_key=True)
def __repr__(self):
return f"Post('{self.date}','{self.value}')"
\ No newline at end of file
This diff is collapsed.
from flask import render_template, url_for, request, redirect, flash
from blog import app, db, resetDB
from blog.models import User, Post, Comment, Rate
from blog.forms import RegistrationForm, LoginForm, CommentForm,PostForm, RateForm
from flask_login import login_user, logout_user, login_required, current_user
import re
@app.route("/")
@app.route("/home")
def home():
posts=Post.query.all()
TAG_RE = re.compile(r'<[^>]+>')
for post in posts:
post.shortcontent = TAG_RE.sub('', post.content)
post.shortcontent = post.shortcontent[:100]
return render_template('home.html',posts=posts)
@app.route("/allposts")
def allposts():
sort = request.args.get('sorttype')
search = request.args.get('searchtext')
if not search :
search = ''
if (sort=="asc"):
posts=Post.query.filter(Post.content.contains(search),Post.title.contains(search)).order_by(Post.date.asc())
else :
posts=Post.query.filter(Post.content.contains(search),Post.title.contains(search)).order_by(Post.date.desc())
return render_template('allposts.html',posts=posts)
@app.route("/aboutus")
def aboutus():
return render_template('aboutus.html', title='About')
@app.route("/license")
def license():
return render_template('license.html', title='License')
@app.route("/search",methods=['GET','POST'])
def search():
searchtext = request.form.get('search');
return redirect(url_for('allposts', searchtext=searchtext))
@app.route("/post/<int:post_id>")
def post(post_id):
post = Post.query.get_or_404(post_id)
comments = Comment.query.filter(Comment.post_id==post.id)
form=CommentForm()
rates=Rate.query.filter(Rate.post_id==post.id)
sRate = 0
countRate = 0
for rate in rates :
sRate = sRate + rate.rateValue
countRate = countRate + 1
if countRate == 0 :
sRate = 0
else :
sRate = sRate / countRate
sRate = int(sRate)
return render_template('post.html',post=post,comments=comments,rate=sRate,form=form)
@app.route('/postcomment/<int:post_id>',methods=['GET','POST'])
@login_required
def post_comment(post_id):
post=Post.query.get_or_404(post_id)
form=CommentForm()
if form.validate_on_submit():
db.session.add(Comment(content=form.comment.data,post_id=post.id,author_id=current_user.id))
db.session.commit()
return redirect(f'/post/{post.id}')
comments=Comment.query.filter(Comment.post_id==post.id)
rates=Rate.query.filter(Rate.post_id==post.id)
sRate = 0
countRate = 0
for rate in rates :
sRate = sRate + rate.rateValue
countRate = countRate + 1
if countRate == 0 :
sRate = 0
else :
sRate = sRate / countRate
sRate = int(sRate)
return render_template('post.html',post=post,comments=comments,rate=sRate,form=form)
@app.route('/ratepost/<int:post_id>',methods=['GET','POST'])
@login_required
def post_rate(post_id):
post=Post.query.get_or_404(post_id)
rateValue = request.args.get('rate')
rateObj=Rate.query.filter(Rate.post_id==post_id,Rate.author_id==current_user.id).first()
if rateObj :
rateObj.rateValue=rateValue
else :
db.session.add(Rate(rateValue=rateValue,post_id=post.id,author_id=current_user.id))
db.session.commit()
return "done"
@app.route("/register",methods=['GET','POST'])
def register():
form = RegistrationForm()
if form.validate_on_submit():
user = User(username=form.username.data,email=form.email.data,password=form.password.data)
db.session.add(user)
db.session.commit()
flash('Registration successful!')
return redirect(url_for('home'))
return render_template('register.html',title='Register',form=form)
@app.route("/login",methods=['GET','POST'])
def login():
form = LoginForm()
if form.validate_on_submit():
user = User.query.filter_by(email=form.email.data).first()
if user is not None and user.verify_password(form.password.data):
login_user(user)
flash('Login successful!')
return redirect(url_for('home'))
flash('Invalid email address or password, please try again')
return render_template('login.html',form=form)
return render_template('login.html',title='Login',form=form)
@app.route("/logout")
def logout():
logout_user()
return redirect(url_for('home'))
@app.route("/resetdb")
def resetdb():
resetDB.resetDB(db)
return "done"
\ No newline at end of file
File added
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment