mirror of
https://codeberg.org/rimu/pyfedi
synced 2025-01-23 11:26:56 -08:00
sub-topics - admin area #44
This commit is contained in:
parent
b9a88a7fa6
commit
1f7f2967e7
6 changed files with 119 additions and 40 deletions
|
@ -95,7 +95,7 @@ class EditCommunityForm(FlaskForm):
|
|||
class EditTopicForm(FlaskForm):
|
||||
name = StringField(_l('Name'), validators=[DataRequired()])
|
||||
machine_name = StringField(_l('Url'), validators=[DataRequired()])
|
||||
add_community = SelectField(_l('Community to add'), coerce=int, validators=[Optional()])
|
||||
parent_id = SelectField(_l('Parent topic'), coerce=int, validators=[Optional()])
|
||||
submit = SubmitField(_l('Save'))
|
||||
|
||||
|
||||
|
|
|
@ -12,7 +12,8 @@ from app.activitypub.signature import post_request
|
|||
from app.activitypub.util import default_context
|
||||
from app.admin.forms import FederationForm, SiteMiscForm, SiteProfileForm, EditCommunityForm, EditUserForm, \
|
||||
EditTopicForm, SendNewsletterForm, AddUserForm
|
||||
from app.admin.util import unsubscribe_from_everything_then_delete, unsubscribe_from_community, send_newsletter
|
||||
from app.admin.util import unsubscribe_from_everything_then_delete, unsubscribe_from_community, send_newsletter, \
|
||||
topic_tree, topics_for_form
|
||||
from app.community.util import save_icon_file, save_banner_file
|
||||
from app.models import AllowedInstances, BannedInstances, ActivityPubLog, utcnow, Site, Community, CommunityMember, \
|
||||
User, Instance, File, Report, Topic, UserRegistration, Role, Post
|
||||
|
@ -212,29 +213,13 @@ def admin_communities():
|
|||
site=g.site)
|
||||
|
||||
|
||||
def topics_for_form():
|
||||
topics = Topic.query.order_by(Topic.name).all()
|
||||
result = [(0, _('None'))]
|
||||
for topic in topics:
|
||||
result.append((topic.id, topic.name))
|
||||
return result
|
||||
|
||||
|
||||
def communities_for_form():
|
||||
communities = Community.query.order_by(Community.title).all()
|
||||
result = [(0, _('None'))]
|
||||
for community in communities:
|
||||
result.append((community.id, community.title))
|
||||
return result
|
||||
|
||||
|
||||
@bp.route('/community/<int:community_id>/edit', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
@permission_required('administer all communities')
|
||||
def admin_community_edit(community_id):
|
||||
form = EditCommunityForm()
|
||||
community = Community.query.get_or_404(community_id)
|
||||
form.topic.choices = topics_for_form()
|
||||
form.topic.choices = topics_for_form(0)
|
||||
if form.validate_on_submit():
|
||||
community.name = form.url.data
|
||||
community.title = form.title.data
|
||||
|
@ -253,6 +238,7 @@ def admin_community_edit(community_id):
|
|||
community.content_retention = form.content_retention.data
|
||||
community.topic_id = form.topic.data if form.topic.data != 0 else None
|
||||
community.default_layout = form.default_layout.data
|
||||
|
||||
icon_file = request.files['icon_file']
|
||||
if icon_file and icon_file.filename != '':
|
||||
if community.icon_id:
|
||||
|
@ -268,6 +254,8 @@ def admin_community_edit(community_id):
|
|||
if file:
|
||||
community.image = file
|
||||
|
||||
db.session.commit()
|
||||
community.topic.num_communities = community.topic.communities.count()
|
||||
db.session.commit()
|
||||
flash(_('Saved'))
|
||||
return redirect(url_for('admin.admin_communities'))
|
||||
|
@ -341,7 +329,7 @@ def unsubscribe_everyone_then_delete_task(community_id):
|
|||
@login_required
|
||||
@permission_required('administer all communities')
|
||||
def admin_topics():
|
||||
topics = Topic.query.order_by(Topic.name).all()
|
||||
topics = topic_tree()
|
||||
return render_template('admin/topics.html', title=_('Topics'), topics=topics,
|
||||
moderating_communities=moderating_communities(current_user.get_id()),
|
||||
joined_communities=joined_communities(current_user.get_id()),
|
||||
|
@ -354,16 +342,16 @@ def admin_topics():
|
|||
@permission_required('administer all communities')
|
||||
def admin_topic_add():
|
||||
form = EditTopicForm()
|
||||
form.add_community.choices = communities_for_form()
|
||||
form.parent_id.choices = topics_for_form(0)
|
||||
if form.validate_on_submit():
|
||||
topic = Topic(name=form.name.data, machine_name=form.machine_name.data, num_communities=0)
|
||||
if form.parent_id.data:
|
||||
topic.parent_id = form.parent_id.data
|
||||
else:
|
||||
topic.parent_id = None
|
||||
db.session.add(topic)
|
||||
db.session.commit()
|
||||
if form.add_community.data:
|
||||
community = Community.query.get(form.add_community.data)
|
||||
community.topic_id = topic.id
|
||||
topic.num_communities += 1
|
||||
db.session.commit()
|
||||
|
||||
flash(_('Saved'))
|
||||
return redirect(url_for('admin.admin_topics'))
|
||||
|
||||
|
@ -379,20 +367,22 @@ def admin_topic_add():
|
|||
def admin_topic_edit(topic_id):
|
||||
form = EditTopicForm()
|
||||
topic = Topic.query.get_or_404(topic_id)
|
||||
form.add_community.choices = communities_for_form()
|
||||
form.parent_id.choices = topics_for_form(topic_id)
|
||||
if form.validate_on_submit():
|
||||
topic.name = form.name.data
|
||||
topic.num_communities = topic.communities.count() + 1
|
||||
topic.num_communities = topic.communities.count()
|
||||
topic.machine_name = form.machine_name.data
|
||||
if form.add_community.data:
|
||||
community = Community.query.get(form.add_community.data)
|
||||
community.topic_id = topic.id
|
||||
if form.parent_id.data:
|
||||
topic.parent_id = form.parent_id.data
|
||||
else:
|
||||
topic.parent_id = None
|
||||
db.session.commit()
|
||||
flash(_('Saved'))
|
||||
return redirect(url_for('admin.admin_topics'))
|
||||
else:
|
||||
form.name.data = topic.name
|
||||
form.machine_name.data = topic.machine_name
|
||||
form.parent_id.data = topic.parent_id
|
||||
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()),
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
from typing import List, Tuple
|
||||
|
||||
from flask import request, abort, g, current_app, json, flash, render_template
|
||||
from flask_login import current_user
|
||||
from sqlalchemy import text, desc
|
||||
from flask_babel import _
|
||||
|
||||
from app import db, cache, celery
|
||||
from app.activitypub.signature import post_request
|
||||
from app.activitypub.util import default_context
|
||||
from app.models import User, Community, Instance, Site, ActivityPubLog, CommunityMember
|
||||
from app.models import User, Community, Instance, Site, ActivityPubLog, CommunityMember, Topic
|
||||
from app.utils import gibberish
|
||||
|
||||
|
||||
|
@ -101,3 +104,39 @@ def send_newsletter(form):
|
|||
|
||||
if form.test.data:
|
||||
break
|
||||
|
||||
|
||||
# replies to a post, in a tree, sorted by a variety of methods
|
||||
def topic_tree() -> List:
|
||||
topics = Topic.query.order_by(Topic.name)
|
||||
|
||||
topics_dict = {topic.id: {'topic': topic, 'children': []} for topic in topics.all()}
|
||||
|
||||
for topic in topics:
|
||||
if topic.parent_id is not None:
|
||||
parent_comment = topics_dict.get(topic.parent_id)
|
||||
if parent_comment:
|
||||
parent_comment['children'].append(topics_dict[topic.id])
|
||||
|
||||
return [topic for topic in topics_dict.values() if topic['topic'].parent_id is None]
|
||||
|
||||
|
||||
def topics_for_form(current_topic: int) -> List[Tuple[int, str]]:
|
||||
result = [(0, _('None'))]
|
||||
topics = topic_tree()
|
||||
for topic in topics:
|
||||
if topic['topic'].id != current_topic:
|
||||
result.append((topic['topic'].id, topic['topic'].name))
|
||||
if topic['children']:
|
||||
result.extend(topics_for_form_children(topic['children'], current_topic, 1))
|
||||
return result
|
||||
|
||||
|
||||
def topics_for_form_children(topics, current_topic: int, depth: int) -> List[Tuple[int, str]]:
|
||||
result = []
|
||||
for topic in topics:
|
||||
if topic['topic'].id != current_topic:
|
||||
result.append((topic['topic'].id, '--' * depth + ' ' + topic['topic'].name))
|
||||
if topic['children']:
|
||||
result.extend(topics_for_form_children(topic['children'], current_topic, depth + 1))
|
||||
return result
|
||||
|
|
|
@ -172,7 +172,7 @@ class File(db.Model):
|
|||
file_name = db.Column(db.String(255))
|
||||
width = db.Column(db.Integer)
|
||||
height = db.Column(db.Integer)
|
||||
alt_text = db.Column(db.String(256))
|
||||
alt_text = db.Column(db.String(300))
|
||||
source_url = db.Column(db.String(1024))
|
||||
thumbnail_path = db.Column(db.String(255))
|
||||
thumbnail_width = db.Column(db.Integer)
|
||||
|
|
|
@ -11,6 +11,24 @@
|
|||
{% include 'admin/_nav.html' %}
|
||||
</div>
|
||||
</div>
|
||||
{% macro render_topic(topic, depth) %}
|
||||
<tr>
|
||||
<td nowrap="nowrap">{{ '--' * depth }} {{ topic['topic'].name }}</td>
|
||||
<td>{{ topic['topic'].num_communities }}</td>
|
||||
<td><a href="{{ url_for('admin.admin_topic_edit', topic_id=topic['topic'].id) }}">Edit</a> |
|
||||
{% if topic['topic'].num_communities == 0 %}
|
||||
<a href="{{ url_for('admin.admin_topic_delete', topic_id=topic['topic'].id) }}" class="confirm_first">Delete</a>
|
||||
{% else %}
|
||||
Delete
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% if topic['children'] %}
|
||||
{% for topic in topic['children'] %}
|
||||
{{ render_topic(topic, depth + 1)|safe }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
|
@ -22,13 +40,7 @@
|
|||
<th>Actions</th>
|
||||
</tr>
|
||||
{% for topic in topics %}
|
||||
<tr>
|
||||
<td>{{ topic.name }}</td>
|
||||
<td>{{ topic.num_communities }}</td>
|
||||
<td><a href="{{ url_for('admin.admin_topic_edit', topic_id=topic.id) }}">Edit</a> |
|
||||
<a href="{{ url_for('admin.admin_topic_delete', topic_id=topic.id) }}" class="confirm_first">Delete</a>
|
||||
</td>
|
||||
</tr>
|
||||
{{ render_topic(topic, 0)|safe }}
|
||||
{% endfor %}
|
||||
</table>
|
||||
</div>
|
||||
|
|
38
migrations/versions/e72aa356e4d0_increase_alt_text_length.py
Normal file
38
migrations/versions/e72aa356e4d0_increase_alt_text_length.py
Normal file
|
@ -0,0 +1,38 @@
|
|||
"""increase alt text length
|
||||
|
||||
Revision ID: e72aa356e4d0
|
||||
Revises: a88efa63415b
|
||||
Create Date: 2024-03-04 12:12:07.458127
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = 'e72aa356e4d0'
|
||||
down_revision = 'a88efa63415b'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
with op.batch_alter_table('file', schema=None) as batch_op:
|
||||
batch_op.alter_column('alt_text',
|
||||
existing_type=sa.VARCHAR(length=256),
|
||||
type_=sa.String(length=300),
|
||||
existing_nullable=True)
|
||||
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
with op.batch_alter_table('file', schema=None) as batch_op:
|
||||
batch_op.alter_column('alt_text',
|
||||
existing_type=sa.String(length=300),
|
||||
type_=sa.VARCHAR(length=256),
|
||||
existing_nullable=True)
|
||||
|
||||
# ### end Alembic commands ###
|
Loading…
Reference in a new issue