From 08df086a299ebeb66561a4d1ce587bbef13210de Mon Sep 17 00:00:00 2001 From: 421281726 <421281726@qq.com> Date: Sat, 5 Dec 2020 23:31:34 +0800 Subject: [PATCH 1/2] 201732120118-ljx improvements --- .gitignore | 1 + service.py | 191 ++++++++++++++++++++++++++-------------- templates/admin.html | 14 +++ templates/donation.html | 13 ++- templates/template.html | 111 +++++++++++------------ 5 files changed, 200 insertions(+), 130 deletions(-) diff --git a/.gitignore b/.gitignore index 2483976..07da734 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ .idea/ __pycache__/ +venv/ diff --git a/service.py b/service.py index af5395e..4f5db90 100644 --- a/service.py +++ b/service.py @@ -1,24 +1,27 @@ from flask_sqlalchemy import SQLAlchemy from sqlalchemy import or_ -import os, uuid ,math, random +import os, uuid, math, random from flask import Flask, flash, request, redirect, url_for, session, jsonify, render_template, send_from_directory from werkzeug.utils import secure_filename from datetime import datetime, timedelta from flask import Flask + basedir = os.path.abspath(os.path.dirname(__file__)) UPLOAD_FOLDER = basedir + '\static\pdf' ALLOWED_EXTENSIONS = set(['pdf']) threshold = 100000 app = Flask(__name__) app.config['MAX_CONTENT_LENGTH'] = 20 * 1024 * 1024 -app.config['UPLOAD_FOLDER'] = os.path.join(basedir+'\static\pdf') -app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///'+os.path.join(basedir+'\database.sqlite') +app.config['UPLOAD_FOLDER'] = os.path.join(basedir + '\static\pdf') +app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + os.path.join(basedir + '\database.sqlite') app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT' app.config['SEND_FILE_MAX_AGE_DEFAULT'] = timedelta(seconds=1) db = SQLAlchemy(app) IP = '168.0.0.10' + + class Author(db.Model): __tablename__ = 'authors' id = db.Column(db.Integer, primary_key=True) @@ -28,6 +31,7 @@ class Author(db.Model): articles = db.relationship('Article', backref='author') comments = db.relationship('Comment', backref='author') + class Subject(db.Model): __tablename__ = 'subjects' id = db.Column(db.Integer, primary_key=True) @@ -36,6 +40,7 @@ class Subject(db.Model): # OneToMany articles = db.relationship('Article', backref='subject') + class Article(db.Model): __tablename__ = 'articles' id = db.Column(db.Integer, primary_key=True) @@ -54,6 +59,7 @@ class Article(db.Model): # OneToMany comments = db.relationship('Comment', backref='article', cascade='all,delete-orphan') + class Comment(db.Model): __tablename__ = 'comments' id = db.Column(db.Integer, primary_key=True) @@ -78,6 +84,7 @@ class Visitor(db.Model): comment_votes = db.relationship('CommentVote', backref='visitor') visit_votes = db.relationship('VisitVote', backref='visitor') + class ArticleVote(db.Model): __tablename__ = 'article_votes' id = db.Column(db.Integer, primary_key=True) @@ -91,17 +98,20 @@ class CommentVote(db.Model): visitor_id = db.Column(db.Integer, db.ForeignKey('visitors.id')) comment_id = db.Column(db.Integer) + class VisitVote(db.Model): _tablename__ = 'visit_votes' id = db.Column(db.Integer, primary_key=True) visitor_id = db.Column(db.Integer, db.ForeignKey('visitors.id')) article_id = db.Column(db.Integer) + class SensitiveWord(db.Model): __tablename__ = 'sensitive_words' id = db.Column(db.Integer, primary_key=True) word = db.Column(db.String(50)) + class Admin(db.Model): def __init__(self, username, password): self.username = username @@ -111,15 +121,18 @@ def __init__(self, username, password): id = db.Column(db.Integer, primary_key=True) email = db.Column(db.String(50), nullable=False) password = db.Column(db.String(50), nullable=False) + + # ============================================================================================== # Tool class include some usual methods # ============================================================================================== class Tool: commentFlag = 0 articleFlag = 0 + @staticmethod def find(subject): - if(subject.pid=='None'): + if (subject.pid == 'None'): print(subject.id) else: subject = Subject.query.filter_by(id=subject.pid).first() @@ -200,6 +213,7 @@ def email_display_filter(email): return display + suf + # ========================================================================================= # like and dislike # ======================================================================================== @@ -223,6 +237,7 @@ def article_upvote(articleID): db.session.delete(articlevote) return jsonify({'upvote': article.upvote}) + @app.route('/article_downvote/') def article_downvote(articleID): # get goal article @@ -244,6 +259,7 @@ def article_downvote(articleID): Tool.articleFlag = -1 return jsonify({'downvote': article.downvote}) + @app.route('/comment_upvote/') def comment_upvote(commentID): # get goal comment @@ -262,6 +278,7 @@ def comment_upvote(commentID): db.session.delete(commentvote) return jsonify({'upvote': comment.upvote}) + @app.route('/comment_downvote/') def comment_downvote(commentID): # get goal comment @@ -278,11 +295,12 @@ def comment_downvote(commentID): db.session.add(comment) Tool.commentFlag = 1 elif commentvote is not None and comment.downvote != 0: - comment.downvote -=1 + comment.downvote -= 1 db.session.delete(commentvote) Tool.commentFlag = -1 return jsonify({'downvote': comment.downvote}) + # ========================================================================================= # check if a email is banned # ======================================================================================== @@ -293,6 +311,7 @@ def check_mail(mail): return jsonify('ok') return jsonify(author.is_banned) + # ================================================================================================== # subject # ================================================================================================== @@ -300,9 +319,9 @@ def check_mail(mail): def get_subject(subjectID): subject = Subject.query.filter_by(id=subjectID).first() url = Tool.subject_url(subject) - page = request.args.get('page', 1, type=int) #Set the default page to page 1 - articles = Article.query.filter_by(subject_id=subject.id, status=1).order_by(Article.time.desc()).paginate(page=page, per_page=20) - + page = request.args.get('page', 1, type=int) # Set the default page to page 1 + articles = Article.query.filter_by(subject_id=subject.id, status=1).order_by(Article.time.desc()).paginate( + page=page, per_page=20) # ================================================== # hot article @@ -316,7 +335,9 @@ def get_subject(subjectID): for x in a: hot_article.append(x) - return render_template('subject.html', url=url, subject_id=subject.id, articles=articles, hot_article=hot_article, Tool=Tool) + return render_template('subject.html', url=url, subject_id=subject.id, articles=articles, hot_article=hot_article, + Tool=Tool) + # ============================================================================================ # before request @@ -352,6 +373,7 @@ def before_request(): db.session.add(visitvote) db.session.add(article) + # ============================================================================================# # index # # ============================================================================================# @@ -359,10 +381,12 @@ def before_request(): def index(): return render_template('io.html') + @app.route('/test') def test_one(): return render_template('test.html') + # ============================================================================================# # used to out new index after new a subcategory. # ============================================================================================# @@ -392,6 +416,7 @@ def find_subjects(subject, count): out.close() return render_template('io.html') + # ================================================================================ # Edit and add subject # ================================================================================ @@ -428,6 +453,8 @@ def add_sub_category(): if request.args.get('add_father') == 'father': subject_id = str(None) return render_template('add_subcategory.html', subject_id=subject_id) + + # ============================================================================================ # edit page # ============================================================================================ @@ -467,7 +494,8 @@ def post_article(): abstract = request.form['abstract'] highlight = request.form['highlight'] time = datetime.now() - article = Article(author_id=author_id, subject_id=subject_id, title=title, abstract=abstract, highlight=highlight, time=time, upvote=0, downvote=0, visit=0) + article = Article(author_id=author_id, subject_id=subject_id, title=title, abstract=abstract, + highlight=highlight, time=time, upvote=0, downvote=0, visit=0) db.session.add(article) db.session.flush() upload_file(article) @@ -478,6 +506,7 @@ def post_article(): subject_id = request.args.get('subject_id') return render_template('post_article.html', email=email, subject_id=subject_id) + # ============================================================================================= # article # ============================================================================================= @@ -493,6 +522,7 @@ def get_article(articleID): comments = article.comments return render_template('article.html', article=article, comments=comments, Tool=Tool) + # ======================================================================== # upload pdf file # ======================================================================== @@ -513,20 +543,25 @@ def upload_file(article): else: return render_template('io.html') + @app.route('/uploads/') def uploaded_file(filename): return send_from_directory(os.path.join(app.config['UPLOAD_FOLDER']), filename) + def allowed_file(filename): return '.' in filename and \ filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS + # =========================================================================== # download pdf file # =========================================================================== @app.route("/download/", methods=['GET']) def download_file(filename): return send_from_directory(os.path.join(app.config['UPLOAD_FOLDER']), filename, as_attachment=True) + + # =========================================================================== # preview pdf file # =========================================================================== @@ -534,6 +569,7 @@ def download_file(filename): def preview_file(filename): return send_from_directory(os.path.join(app.config['UPLOAD_FOLDER']), filename) + # ====================================================================== # post comment # ====================================================================== @@ -560,6 +596,7 @@ def post_comment(articleID): article.metric = Tool.calculate_metric(article) return redirect(url_for('get_article', articleID=articleID)) + # =============================================================================== # donation # =============================================================================== @@ -567,23 +604,25 @@ def post_comment(articleID): def donaton(): return render_template('donation.html') -@app.route('/login',methods=['POST','GET']) + +@app.route('/login', methods=['POST', 'GET']) def login_verfaication(): - #admins login verification function - #fetch the email and password from the html login form + # admins login verification function + # fetch the email and password from the html login form email = request.form['email'] password = request.form['pass'] - #check if it's exists in the database. - validate = db.session.query(Admin).filter_by(email=email,password=password).first() + # check if it's exists in the database. + validate = db.session.query(Admin).filter_by(email=email, password=password).first() - #allow access + # allow access if validate: session['logged_in'] = True return redirect('/admin') else: - #handle error + # handle error error = 'invalid username or password!' - return render_template('login.html',error = error) + return render_template('login.html', error=error) + @app.route('/admin') def admin(): @@ -592,76 +631,95 @@ def admin(): else: articles = Article.query.all() comments = Comment.query.all() - return render_template('admin.html',articles=articles,comments=comments) + visitors = Visitor.query.all() + return render_template('admin.html', articles=articles, comments=comments, visitors=visitors) + @app.route("/logout") def logout(): session['logged_in'] = False return redirect('/') + +@app.route('/banned/') +def banned_visitor(id): + visitor = Visitor.query.filter_by(id=id).first() + try: + if visitor: + visitor.is_banned = not visitor.is_banned + return redirect('/admin') + except: + return 'Error banned / cancel banned visitor!.' + + @app.route('/deletec/') def delete_comment(id): - #delete the comment and its relating records from the database. + # delete the comment and its relating records from the database. comment = Comment.query.filter_by(id=id).first() comment_vote = CommentVote.query.filter_by(comment_id=id).first() - + try: - #delete the comment + # delete the comment if comment: db.session.delete(comment) db.session.commit() - #delete its vote counter + # delete its vote counter if comment_vote: db.session.delete(comment_vote) db.session.commit() return redirect('/admin') except: return 'Error deleting comment!.' + + @app.route('/deletea/') def delete_article(id): - #to delete an article, we have to consider deleting all its relating values - #from the database. so for each article first select the article, then all its related records. - article = Article.query.filter_by(id=id).first() - visit_vote = VisitVote.query.filter_by(article_id=id).first() - article_vote = ArticleVote.query.filter_by(article_id=id).first() - article_comment = Comment.query.filter_by(article_id=id).all() + # to delete an article, we have to consider deleting all its relating values + # from the database. so for each article first select the article, then all its related records. + article = Article.query.filter_by(id=id).first() + visit_vote = VisitVote.query.filter_by(article_id=id).first() + article_vote = ArticleVote.query.filter_by(article_id=id).first() + article_comment = Comment.query.filter_by(article_id=id).all() - #if the article has comments, delete them also - for comment in article_comment: - delete_comment(comment.id) + # if the article has comments, delete them also + for comment in article_comment: + delete_comment(comment.id) + try: + # delete everything related to the article. + if article: + db.session.delete(article) + db.session.delete(visit_vote) + db.session.delete(article_vote) + db.session.commit() + + return redirect('/admin') + except: + return 'Error deleting article!.' + + +@app.route('/article_is_hidden/') +def article_is_hidden(id): + # select the article by its id number + article = Article.query.filter_by(id=id).first() + # if there is an article with the given id number... + if article: try: - #delete everything related to the article. - if article: - db.session.delete(article) - db.session.delete(visit_vote) - db.session.delete(article_vote) + # if the article status is available switch it into hidden.. + if article.status == 1: + article.status = 0 + db.session.add(article) + db.session.commit() + # if it's hidden switch it into available + elif article.status == 0: + article.status = 1 + db.session.add(article) db.session.commit() - return redirect('/admin') except: - return 'Error deleting article!.' + return 'Error hiding the article!' + -@app.route('/article_is_hidden/') -def article_is_hidden(id): - #select the article by its id number - article = Article.query.filter_by(id=id).first() - #if there is an article with the given id number... - if article: - try: - #if the article status is available switch it into hidden.. - if article.status == 1: - article.status = 0 - db.session.add(article) - db.session.commit() - #if it's hidden switch it into available - elif article.status == 0: - article.status = 1 - db.session.add(article) - db.session.commit() - return redirect('/admin') - except: - return 'Error hiding the article!' # =========================================================================== # search function # =========================================================================== @@ -673,18 +731,21 @@ def search(): content = request.args.get('content') - a = db.session.query(Article).filter(or_(Article.title.contains(content), Article.highlight.contains(content), Article.abstract.contains(content))).all() + a = db.session.query(Article).filter(or_(Article.title.contains(content), Article.highlight.contains(content), + Article.abstract.contains(content))).all() c = db.session.query(Comment).filter(Comment.body.contains(content)) articles = a comments = c - + return render_template('search.html', articles=articles, comments=comments, Tool=Tool, message=message) + @app.route('/error/') def error(message): return render_template('error.html', message=message) + @app.route('/author/') def author(author_id): author = Author.query.filter_by(id=author_id).first() @@ -692,12 +753,6 @@ def author(author_id): comments = Comment.query.order_by(Comment.time.desc()).filter_by(author_id=author_id).all() return render_template('author.html', articles=articles, comments=comments, Tool=Tool, author=author) + if __name__ == '__main__': app.run(debug=True) - - - - - - - diff --git a/templates/admin.html b/templates/admin.html index 585fca7..33a9604 100644 --- a/templates/admin.html +++ b/templates/admin.html @@ -44,6 +44,20 @@

comments

{% endfor %} + + +

Visitors

+ {% for visitor in visitors %} + + + + + {% endfor %} +
+ {{ visitor.ip }} + + +


diff --git a/templates/donation.html b/templates/donation.html index 494fe6a..9211426 100644 --- a/templates/donation.html +++ b/templates/donation.html @@ -1,14 +1,13 @@ {% extends "template.html" %} {% block content %} - body style="background-color:#dadada;"> -
-
-

In the development of the site, you can scan the QR code to support us.

- + +
+
+

In the development of the site, you can scan the QR code to support us.

+ +
-
-


diff --git a/templates/template.html b/templates/template.html index 662c63c..f7ec4f0 100644 --- a/templates/template.html +++ b/templates/template.html @@ -6,33 +6,18 @@ - - - - - - - - - - - - - - @@ -72,37 +57,53 @@ - -
+


-
-
-
-
-
-
Contact Us
-
-

Phone: 131-7551-6271

-

Email: i.leaderx@hotmail.com

-

Add: jinhua, zhejiang, 321000

-
-
-
-
About Us
-
-

Zhejiang Normal University

-

Mathematics and computer science college

-

The SPM Spring 2020 Team

- -
- -
-
-
© ZJNU.com
-
-
-
-
+
+
+
+
+
+
Contact Us
+
+

Phone: 131-7551-6271

+

Email: i.leaderx@hotmail.com

+

Add: jinhua, zhejiang, 321000

+
+
+
+
About Us
+
+

Zhejiang Normal University

+

Mathematics and computer science college

+

The SPM Spring 2020 Team

+ +
+ +
+
+
© ZJNU.com
+
+
+
+
+ + + + + + + + + + + + + + + {# #} + + From a747b4acac2e3f3398d09f197927c8fddb6668a5 Mon Sep 17 00:00:00 2001 From: 421281726 <421281726@qq.com> Date: Mon, 21 Dec 2020 21:08:33 +0800 Subject: [PATCH 2/2] FEAT: add requirements.txt --- requirements.txt | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 requirements.txt diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..6429bfa --- /dev/null +++ b/requirements.txt @@ -0,0 +1,8 @@ +click==7.1.2 +Flask==1.1.2 +Flask-SQLAlchemy==2.4.4 +itsdangerous==1.1.0 +Jinja2==2.11.2 +MarkupSafe==1.1.1 +SQLAlchemy==1.3.20 +Werkzeug==1.0.1