From f32b0f17a25c022eee3363251996b90a29eb09a6 Mon Sep 17 00:00:00 2001 From: Grey Li Date: Sun, 4 Aug 2024 22:12:58 +0800 Subject: [PATCH 1/9] Update theme name --- greybook/settings.py | 2 +- greybook/static/css/{perfect_blue.min.css => bluelog.min.css} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename greybook/static/css/{perfect_blue.min.css => bluelog.min.css} (100%) diff --git a/greybook/settings.py b/greybook/settings.py index f7d31c9..315542e 100644 --- a/greybook/settings.py +++ b/greybook/settings.py @@ -29,7 +29,7 @@ class BaseConfig: GREYBOOK_MANAGE_POST_PER_PAGE = 15 GREYBOOK_COMMENT_PER_PAGE = 15 # ('theme name', 'display name') - GREYBOOK_THEMES = {'default': 'Default', 'perfect_blue': 'Perfect Blue'} + GREYBOOK_THEMES = {'default': 'Default', 'bluelog': 'Bluelog'} GREYBOOK_SLOW_QUERY_THRESHOLD = 1 GREYBOOK_UPLOAD_PATH = os.getenv('GREYBOOK_UPLOAD_PATH', BASE_DIR / 'uploads') diff --git a/greybook/static/css/perfect_blue.min.css b/greybook/static/css/bluelog.min.css similarity index 100% rename from greybook/static/css/perfect_blue.min.css rename to greybook/static/css/bluelog.min.css From dbc278ddcece63d92ab88d2827db300cb2caf182 Mon Sep 17 00:00:00 2001 From: Grey Li Date: Sun, 4 Aug 2024 22:13:27 +0800 Subject: [PATCH 2/9] Update faker filename --- greybook/core/commands.py | 2 +- greybook/{fakes.py => lorem.py} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename greybook/{fakes.py => lorem.py} (100%) diff --git a/greybook/core/commands.py b/greybook/core/commands.py index ecb30ee..906ef5b 100644 --- a/greybook/core/commands.py +++ b/greybook/core/commands.py @@ -68,7 +68,7 @@ def init_blog_command(username, password): @click.option('--reply', default=50, help='Quantity of replies, default is 50.') def lorem_command(category, post, comment, reply): """Generate fake data.""" - from greybook.fakes import fake_admin, fake_categories, fake_comments, fake_links, fake_posts, fake_replies + from greybook.lorem import fake_admin, fake_categories, fake_comments, fake_links, fake_posts, fake_replies db.drop_all() db.create_all() diff --git a/greybook/fakes.py b/greybook/lorem.py similarity index 100% rename from greybook/fakes.py rename to greybook/lorem.py From 7049d6cb502e3637e3660f4511c610e1cf3c8374 Mon Sep 17 00:00:00 2001 From: Grey Li Date: Sun, 4 Aug 2024 22:13:42 +0800 Subject: [PATCH 3/9] Update copyright year --- greybook/templates/base.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/greybook/templates/base.html b/greybook/templates/base.html index 051cac8..3e59326 100644 --- a/greybook/templates/base.html +++ b/greybook/templates/base.html @@ -84,7 +84,7 @@ {% if admin.custom_footer %} {{ admin.custom_footer | safe }} {% else %} - © 2023 + © 2024 {{ admin.name }} ยท Powered by Greybook {% endif %} From 41f4a4c3914ba1c161c3d4651bc83a5437ad97d0 Mon Sep 17 00:00:00 2001 From: Grey Li Date: Sun, 4 Aug 2024 22:17:53 +0800 Subject: [PATCH 4/9] Fix typo in logging setup --- greybook/core/logging.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/greybook/core/logging.py b/greybook/core/logging.py index 67744b1..f5cf298 100644 --- a/greybook/core/logging.py +++ b/greybook/core/logging.py @@ -29,7 +29,7 @@ def format(self, record): mail_handler = SMTPHandler( mailhost=app.config['MAIL_SERVER'], fromaddr=app.config['MAIL_USERNAME'], - toaddrs=['ADMIN_EMAIL'], + toaddrs=['GREYBOOK_ADMIN_EMAIL'], subject=app.config['GREYBOOK_ERROR_EMAIL_SUBJECT'], credentials=(app.config['MAIL_USERNAME'], app.config['MAIL_PASSWORD']), ) From 98fb6be10948670f4a93d1940313a8990ca433fb Mon Sep 17 00:00:00 2001 From: Grey Li Date: Sun, 4 Aug 2024 22:18:08 +0800 Subject: [PATCH 5/9] Add pager macro --- greybook/templates/macros.html | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/greybook/templates/macros.html b/greybook/templates/macros.html index 5cc40a4..d3ca10c 100644 --- a/greybook/templates/macros.html +++ b/greybook/templates/macros.html @@ -7,3 +7,22 @@ {% endmacro %} + +{% macro pager(pagination, fragment='') %} + +{% endmacro %} From 3dc72eaa394e6e598822d362e05e1a9f9f3d2052 Mon Sep 17 00:00:00 2001 From: Grey Li Date: Sun, 4 Aug 2024 22:29:12 +0800 Subject: [PATCH 6/9] Rewrite the pagination query --- greybook/blueprints/admin.py | 12 ++++++++---- greybook/blueprints/blog.py | 21 +++++++-------------- 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/greybook/blueprints/admin.py b/greybook/blueprints/admin.py index 40ee7f6..ed3cdf3 100644 --- a/greybook/blueprints/admin.py +++ b/greybook/blueprints/admin.py @@ -43,10 +43,12 @@ def settings(): @login_required def manage_post(): page = request.args.get('page', 1, type=int) + per_page = current_app.config['GREYBOOK_MANAGE_POST_PER_PAGE'] + stmt = select(Post).order_by(Post.created_at.desc()) pagination = db.paginate( - select(Post).order_by(Post.created_at.desc()), + stmt, page=page, - per_page=current_app.config['GREYBOOK_MANAGE_POST_PER_PAGE'], + per_page=per_page, error_out=False, ) if page > pagination.pages: @@ -127,8 +129,9 @@ def manage_comment(): else: filtered_comments = select(Comment) + stmt = filtered_comments.order_by(Comment.created_at.desc()) pagination = db.paginate( - filtered_comments.order_by(Comment.created_at.desc()), + stmt, page=page, per_page=per_page, error_out=False, @@ -152,7 +155,8 @@ def approve_comment(comment_id): @admin_bp.route('/comments/approve', methods=['POST']) @login_required def approve_all_comment(): - comments = db.session.execute(select(Comment).filter_by(reviewed=False)).scalars().all() + stmt = select(Comment).filter_by(reviewed=False) + comments = db.session.scalars(stmt).all() for comment in comments: comment.reviewed = True db.session.commit() diff --git a/greybook/blueprints/blog.py b/greybook/blueprints/blog.py index c1c0cbc..7e0a34e 100644 --- a/greybook/blueprints/blog.py +++ b/greybook/blueprints/blog.py @@ -27,11 +27,8 @@ def index(): page = request.args.get('page', 1, type=int) per_page = current_app.config['GREYBOOK_POST_PER_PAGE'] - pagination = db.paginate( - select(Post).order_by(Post.created_at.desc()), - page=page, - per_page=per_page, - ) + stmt = select(Post).order_by(Post.created_at.desc()) + pagination = db.paginate(stmt, page=page, per_page=per_page) posts = pagination.items return render_template('blog/index.html', pagination=pagination, posts=posts) @@ -46,11 +43,8 @@ def show_category(category_id): category = db.get_or_404(Category, category_id) page = request.args.get('page', 1, type=int) per_page = current_app.config['GREYBOOK_POST_PER_PAGE'] - pagination = db.paginate( - select(Post).filter(with_parent(category, Category.posts)).order_by(Post.created_at.desc()), - page=page, - per_page=per_page, - ) + stmt = select(Post).filter(with_parent(category, Category.posts)).order_by(Post.created_at.desc()) + pagination = db.paginate(stmt, page=page, per_page=per_page) posts = pagination.items return render_template('blog/category.html', category=category, pagination=pagination, posts=posts) @@ -60,14 +54,13 @@ def show_post(post_id): post = db.get_or_404(Post, post_id) page = request.args.get('page', 1, type=int) per_page = current_app.config['GREYBOOK_COMMENT_PER_PAGE'] - pagination = db.paginate( + stmt = ( select(Comment) .filter(with_parent(post, Post.comments)) .filter_by(reviewed=True) - .order_by(Comment.created_at.asc()), - page=page, - per_page=per_page, + .order_by(Comment.created_at.asc()) ) + pagination = db.paginate(stmt, page=page, per_page=per_page) comments = pagination.items if current_user.is_authenticated: From bedcae57b1068c59cd6362ffa11b201b6c376c69 Mon Sep 17 00:00:00 2001 From: Grey Li Date: Mon, 5 Aug 2024 21:36:34 +0800 Subject: [PATCH 7/9] Remove get_or_404 usage --- greybook/blueprints/admin.py | 20 ++++++++++---------- greybook/blueprints/blog.py | 8 ++++---- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/greybook/blueprints/admin.py b/greybook/blueprints/admin.py index ed3cdf3..cce140f 100644 --- a/greybook/blueprints/admin.py +++ b/greybook/blueprints/admin.py @@ -1,6 +1,6 @@ import os -from flask import Blueprint, current_app, flash, redirect, render_template, request, url_for +from flask import Blueprint, abort, current_app, flash, redirect, render_template, request, url_for from flask_ckeditor import upload_fail, upload_success from flask_login import current_user, login_required from sqlalchemy import select @@ -77,7 +77,7 @@ def new_post(): @login_required def edit_post(post_id): form = PostForm() - post = db.get_or_404(Post, post_id) + post = db.session.get(Post, post_id) or abort(404) if form.validate_on_submit(): post.title = form.title.data post.body = form.body.data @@ -95,7 +95,7 @@ def edit_post(post_id): @admin_bp.route('/post//delete', methods=['POST']) @login_required def delete_post(post_id): - post = db.get_or_404(Post, post_id) + post = db.session.get(Post, post_id) or abort(404) post.delete() flash('Post deleted.', 'success') return redirect_back() @@ -104,7 +104,7 @@ def delete_post(post_id): @admin_bp.route('/post//set-comment', methods=['POST']) @login_required def set_comment(post_id): - post = db.get_or_404(Post, post_id) + post = db.session.get(Post, post_id) or abort(404) if post.can_comment: post.can_comment = False flash('Comment disabled.', 'success') @@ -145,7 +145,7 @@ def manage_comment(): @admin_bp.route('/comment//approve', methods=['POST']) @login_required def approve_comment(comment_id): - comment = db.get_or_404(Comment, comment_id) + comment = db.session.get(Comment, comment_id) or abort(404) comment.reviewed = True db.session.commit() flash('Comment published.', 'success') @@ -167,7 +167,7 @@ def approve_all_comment(): @admin_bp.route('/comment//delete', methods=['POST']) @login_required def delete_comment(comment_id): - comment = db.get_or_404(Comment, comment_id) + comment = db.session.get(Comment, comment_id) or abort(404) db.session.delete(comment) db.session.commit() flash('Comment deleted.', 'success') @@ -198,7 +198,7 @@ def new_category(): @login_required def edit_category(category_id): form = CategoryForm() - category = db.get_or_404(Category, category_id) + category = db.session.get(Category, category_id) or abort(404) if category.id == 1: flash('You can not edit the default category.', 'warning') return redirect(url_for('blog.index')) @@ -216,7 +216,7 @@ def edit_category(category_id): @admin_bp.route('/category//delete', methods=['POST']) @login_required def delete_category(category_id): - category = db.get_or_404(Category, category_id) + category = db.session.get(Category, category_id) or abort(404) if category.id == 1: flash('You can not delete the default category.', 'warning') return redirect(url_for('blog.index')) @@ -250,7 +250,7 @@ def new_link(): @login_required def edit_link(link_id): form = LinkForm() - link = db.get_or_404(Link, link_id) + link = db.session.get(Link, link_id) or abort(404) if form.validate_on_submit(): link.name = form.name.data link.url = form.url.data @@ -266,7 +266,7 @@ def edit_link(link_id): @admin_bp.route('/link//delete', methods=['POST']) @login_required def delete_link(link_id): - link = db.get_or_404(Link, link_id) + link = db.session.get(Link, link_id) or abort(404) db.session.delete(link) db.session.commit() flash('Link deleted.', 'success') diff --git a/greybook/blueprints/blog.py b/greybook/blueprints/blog.py index 7e0a34e..90a13b8 100644 --- a/greybook/blueprints/blog.py +++ b/greybook/blueprints/blog.py @@ -40,7 +40,7 @@ def about(): @blog_bp.route('/category/') def show_category(category_id): - category = db.get_or_404(Category, category_id) + category = db.session.get(Category, category_id) or abort(404) page = request.args.get('page', 1, type=int) per_page = current_app.config['GREYBOOK_POST_PER_PAGE'] stmt = select(Post).filter(with_parent(category, Category.posts)).order_by(Post.created_at.desc()) @@ -51,7 +51,7 @@ def show_category(category_id): @blog_bp.route('/post/', methods=['GET', 'POST']) def show_post(post_id): - post = db.get_or_404(Post, post_id) + post = db.session.get(Post, post_id) or abort(404) page = request.args.get('page', 1, type=int) per_page = current_app.config['GREYBOOK_COMMENT_PER_PAGE'] stmt = ( @@ -85,7 +85,7 @@ def show_post(post_id): ) replied_id = request.args.get('reply') if replied_id: - replied_comment = db.get_or_404(Comment, replied_id) + replied_comment = comment = db.session.get(Comment, replied_id) or abort(404) comment.replied = replied_comment send_new_reply_email(replied_comment) db.session.add(comment) @@ -101,7 +101,7 @@ def show_post(post_id): @blog_bp.route('/reply/comment/') def reply_comment(comment_id): - comment = db.get_or_404(Comment, comment_id) + comment = db.session.get(Comment, comment_id) or abort(404) if not comment.post.can_comment: flash('Comment is disabled.', 'warning') return redirect(url_for('.show_post', post_id=comment.post.id)) From 1159c649add4c95b40674f5073a28771c72032f4 Mon Sep 17 00:00:00 2001 From: Grey Li Date: Tue, 6 Aug 2024 21:21:57 +0800 Subject: [PATCH 8/9] Simplify query statements --- greybook/blueprints/auth.py | 2 +- greybook/blueprints/blog.py | 2 +- greybook/core/commands.py | 4 ++-- greybook/core/templating.py | 11 +++++------ greybook/forms.py | 4 ++-- 5 files changed, 11 insertions(+), 12 deletions(-) diff --git a/greybook/blueprints/auth.py b/greybook/blueprints/auth.py index 9600f1a..361fd9a 100644 --- a/greybook/blueprints/auth.py +++ b/greybook/blueprints/auth.py @@ -20,7 +20,7 @@ def login(): username = form.username.data password = form.password.data remember = form.remember.data - admin = db.session.execute(select(Admin)).scalar() + admin = db.session.scalar(select(Admin)) if admin: if username == admin.username and admin.validate_password(password): login_user(admin, remember) diff --git a/greybook/blueprints/blog.py b/greybook/blueprints/blog.py index 90a13b8..c1ab504 100644 --- a/greybook/blueprints/blog.py +++ b/greybook/blueprints/blog.py @@ -85,7 +85,7 @@ def show_post(post_id): ) replied_id = request.args.get('reply') if replied_id: - replied_comment = comment = db.session.get(Comment, replied_id) or abort(404) + replied_comment = db.session.get(Comment, replied_id) or abort(404) comment.replied = replied_comment send_new_reply_email(replied_comment) db.session.add(comment) diff --git a/greybook/core/commands.py b/greybook/core/commands.py index 906ef5b..eb729d9 100644 --- a/greybook/core/commands.py +++ b/greybook/core/commands.py @@ -31,7 +31,7 @@ def init_blog_command(username, password): db.create_all() click.echo('Initialized the database.') - admin = db.session.execute(select(Admin)).scalar() + admin = db.session.scalar(select(Admin)) if admin is not None: admin.username = username admin.password = password @@ -48,7 +48,7 @@ def init_blog_command(username, password): db.session.add(admin) click.echo('Created the administrator account.') - category = db.session.execute(select(Category)).scalar() + category = db.session.scalar(select(Category)) if category is None: category = Category(name='Default') db.session.add(category) diff --git a/greybook/core/templating.py b/greybook/core/templating.py index 6fccefa..4885b7e 100644 --- a/greybook/core/templating.py +++ b/greybook/core/templating.py @@ -8,14 +8,13 @@ def register_template_handlers(app): @app.context_processor def make_template_context(): - admin = db.session.execute(select(Admin)).scalar() - categories = db.session.execute(select(Category).order_by(Category.name)).scalars().all() - links = db.session.execute(select(Link).order_by(Link.name)).scalars().all() + admin = db.session.scalar(select(Admin)) + categories = db.session.scalars(select(Category).order_by(Category.name)).all() + links = db.session.scalars(select(Link).order_by(Link.name)).all() if current_user.is_authenticated: - unread_comments = ( - db.session.execute(select(func.count(Comment.id)).filter_by(reviewed=False)).scalars().one() - ) + stmt = select(func.count(Comment.id)).filter_by(reviewed=False) + unread_comments = db.session.scalars(stmt).one() else: unread_comments = None return dict(admin=admin, categories=categories, links=links, unread_comments=unread_comments) diff --git a/greybook/forms.py b/greybook/forms.py index 2e9bf6f..0493950 100644 --- a/greybook/forms.py +++ b/greybook/forms.py @@ -43,7 +43,7 @@ class PostForm(FlaskForm): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - categories = db.session.execute(select(Category).order_by(Category.name)).scalars() + categories = db.session.scalars(select(Category).order_by(Category.name)) self.category.choices = [(category.id, category.name) for category in categories] @@ -52,7 +52,7 @@ class CategoryForm(FlaskForm): submit = SubmitField() def validate_name(self, field): - if db.session.execute(select(Category).filter_by(name=field.data)).scalar(): + if db.session.scalar(select(Category).filter_by(name=field.data)): raise ValidationError('Name already in use.') From 3c0282c51a8552d2104eedaa7cd3d4259328fd33 Mon Sep 17 00:00:00 2001 From: Grey Li Date: Tue, 6 Aug 2024 21:22:35 +0800 Subject: [PATCH 9/9] Update template string quotes --- greybook/templates/blog/about.html | 2 +- greybook/templates/blog/category.html | 2 +- greybook/templates/blog/post.html | 2 +- tests/test_blog.py | 6 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/greybook/templates/blog/about.html b/greybook/templates/blog/about.html index c26ac12..fcfe6e3 100644 --- a/greybook/templates/blog/about.html +++ b/greybook/templates/blog/about.html @@ -11,7 +11,7 @@

About

{{ admin.about|safe }} {% endblock %} diff --git a/greybook/templates/blog/category.html b/greybook/templates/blog/category.html index 02571fa..4b88d44 100644 --- a/greybook/templates/blog/category.html +++ b/greybook/templates/blog/category.html @@ -18,7 +18,7 @@

Category: {{ category.name }}

{% endblock %} diff --git a/greybook/templates/blog/post.html b/greybook/templates/blog/post.html index a278729..933b81f 100644 --- a/greybook/templates/blog/post.html +++ b/greybook/templates/blog/post.html @@ -140,7 +140,7 @@
Comment disabled.
{% endif %} {% endblock %} diff --git a/tests/test_blog.py b/tests/test_blog.py index b4b0f93..1907f08 100644 --- a/tests/test_blog.py +++ b/tests/test_blog.py @@ -27,11 +27,11 @@ def test_change_theme(self): response = self.client.get('/change-theme/default', follow_redirects=True) data = response.get_data(as_text=True) self.assertIn('css/default.min.css', data) - self.assertNotIn('css/perfect_blue.min.css', data) + self.assertNotIn('css/bluelog.min.css', data) - response = self.client.get('/change-theme/perfect_blue', follow_redirects=True) + response = self.client.get('/change-theme/bluelog', follow_redirects=True) data = response.get_data(as_text=True) - self.assertIn('css/perfect_blue.min.css', data) + self.assertIn('css/bluelog.min.css', data) self.assertNotIn('css/default.min.css', data) def test_about_page(self):