From 0b5f515de6cf66a6548dadd482708529478d32b2 Mon Sep 17 00:00:00 2001 From: rimu <3310831+rimu@users.noreply.github.com> Date: Fri, 8 Nov 2024 15:09:24 +1300 Subject: [PATCH] show posts from child topics --- app/admin/forms.py | 1 + app/admin/routes.py | 5 ++- app/models.py | 1 + app/topic/routes.py | 15 ++++++++- ...debcf5ac6f_topic_show_posts_in_children.py | 32 +++++++++++++++++++ 5 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 migrations/versions/a4debcf5ac6f_topic_show_posts_in_children.py diff --git a/app/admin/forms.py b/app/admin/forms.py index ef3ec3e2..34ca898c 100644 --- a/app/admin/forms.py +++ b/app/admin/forms.py @@ -119,6 +119,7 @@ class EditTopicForm(FlaskForm): name = StringField(_l('Name'), validators=[DataRequired()], render_kw={'title': _l('Human readable name for the topic.')}) machine_name = StringField(_l('Slug'), validators=[DataRequired()], render_kw={'title': _l('A short and unique identifier that becomes part of the URL.')}) parent_id = SelectField(_l('Parent topic'), coerce=int, validators=[Optional()], render_kw={'class': 'form-select'}) + show_posts_in_children = BooleanField(_l('Show posts from child topics'), validators=[Optional()]) submit = SubmitField(_l('Save')) diff --git a/app/admin/routes.py b/app/admin/routes.py index 7d3c0aca..36adb346 100644 --- a/app/admin/routes.py +++ b/app/admin/routes.py @@ -825,7 +825,8 @@ def admin_topic_add(): form = EditTopicForm() form.parent_id.choices = topics_for_form(0) if form.validate_on_submit(): - topic = Topic(name=form.name.data, machine_name=slugify(form.machine_name.data.strip()), num_communities=0) + topic = Topic(name=form.name.data, machine_name=slugify(form.machine_name.data.strip()), num_communities=0, + show_posts_in_children=form.show_posts_in_children.data) if form.parent_id.data: topic.parent_id = form.parent_id.data else: @@ -855,6 +856,7 @@ def admin_topic_edit(topic_id): topic.name = form.name.data topic.num_communities = topic.communities.count() topic.machine_name = form.machine_name.data + topic.show_posts_in_children = form.show_posts_in_children.data if form.parent_id.data: topic.parent_id = form.parent_id.data else: @@ -867,6 +869,7 @@ def admin_topic_edit(topic_id): form.name.data = topic.name form.machine_name.data = topic.machine_name form.parent_id.data = topic.parent_id + form.show_posts_in_children.data = topic.show_posts_in_children return render_template('admin/edit_topic.html', title=_('Edit topic'), form=form, topic=topic, moderating_communities=moderating_communities(current_user.get_id()), joined_communities=joined_communities(current_user.get_id()), diff --git a/app/models.py b/app/models.py index be647c3b..c9293bd7 100644 --- a/app/models.py +++ b/app/models.py @@ -371,6 +371,7 @@ class Topic(db.Model): name = db.Column(db.String(50)) num_communities = db.Column(db.Integer, default=0) parent_id = db.Column(db.Integer) + show_posts_in_children = db.Column(db.Boolean, default=False) communities = db.relationship('Community', lazy='dynamic', backref='topic', cascade="all, delete-orphan") def path(self): diff --git a/app/topic/routes.py b/app/topic/routes.py index d624e310..6ac24bf9 100644 --- a/app/topic/routes.py +++ b/app/topic/routes.py @@ -1,6 +1,7 @@ from collections import namedtuple from datetime import timedelta, timezone from random import randint +from typing import List from feedgen.feed import FeedGenerator from flask import request, flash, json, url_for, current_app, redirect, abort, make_response, g @@ -52,7 +53,12 @@ def show_topic(topic_path): if current_topic: # get posts from communities in that topic - posts = Post.query.join(Community, Post.community_id == Community.id).filter(Community.topic_id == current_topic.id, Community.banned == False) + if current_topic.show_posts_in_children: # include posts from child topics + topic_ids = get_all_child_topic_ids(current_topic) + else: + topic_ids = [current_topic.id] + posts = Post.query.join(Community, Post.community_id == Community.id).filter(Community.topic_id.in_(topic_ids), + Community.banned == False) # filter out nsfw and nsfl if desired if current_user.is_anonymous: @@ -273,6 +279,13 @@ def suggestion_denied(): return render_template('topic/suggestion_denied.html') +def get_all_child_topic_ids(topic: Topic) -> List[int]: + # recurse down the topic tree, gathering all the topic IDs found + topic_ids = [topic.id] + for child_topic in Topic.query.filter(Topic.parent_id == topic.id): + topic_ids.extend(get_all_child_topic_ids(child_topic)) + return topic_ids + def topics_for_form(): topics = Topic.query.filter_by(parent_id=None).order_by(Topic.name).all() result = [] diff --git a/migrations/versions/a4debcf5ac6f_topic_show_posts_in_children.py b/migrations/versions/a4debcf5ac6f_topic_show_posts_in_children.py new file mode 100644 index 00000000..2de1813a --- /dev/null +++ b/migrations/versions/a4debcf5ac6f_topic_show_posts_in_children.py @@ -0,0 +1,32 @@ +"""topic: show_posts_in_children + +Revision ID: a4debcf5ac6f +Revises: e23ce3d53def +Create Date: 2024-11-08 14:46:56.009352 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = 'a4debcf5ac6f' +down_revision = 'e23ce3d53def' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table('topic', schema=None) as batch_op: + batch_op.add_column(sa.Column('show_posts_in_children', sa.Boolean(), nullable=True)) + + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table('topic', schema=None) as batch_op: + batch_op.drop_column('show_posts_in_children') + + # ### end Alembic commands ###