community wiki #127

This commit is contained in:
rimu 2024-07-17 22:11:31 +08:00
parent 55e4289a6e
commit 2c3f1763b3
10 changed files with 448 additions and 13 deletions

View file

@ -63,6 +63,19 @@ class EditCommunityForm(FlaskForm):
submit = SubmitField(_l('Save'))
class EditCommunityWikiPageForm(FlaskForm):
title = StringField(_l('Title'), validators=[DataRequired()])
slug = StringField(_l('Slug'), validators=[DataRequired()])
body = TextAreaField(_l('Body'), render_kw={'rows': '10'})
edit_options = [(0, _l('Mods and admins')),
(1, _l('Trusted accounts')),
(2, _l('Community members')),
(3, _l('Any account'))
]
who_can_edit = SelectField(_l('Who can edit'), coerce=int, choices=edit_options, validators=[Optional()], render_kw={'class': 'form-select'})
submit = SubmitField(_l('Save'))
class AddModeratorForm(FlaskForm):
user_name = StringField(_l('User name'), validators=[DataRequired()])
submit = SubmitField(_l('Find'))

View file

@ -15,7 +15,8 @@ from app.chat.util import send_message
from app.community.forms import SearchRemoteCommunity, CreateDiscussionForm, CreateImageForm, CreateLinkForm, \
ReportCommunityForm, \
DeleteCommunityForm, AddCommunityForm, EditCommunityForm, AddModeratorForm, BanUserCommunityForm, \
EscalateReportForm, ResolveReportForm, CreateVideoForm, CreatePollForm, RetrieveRemotePost
EscalateReportForm, ResolveReportForm, CreateVideoForm, CreatePollForm, RetrieveRemotePost, \
EditCommunityWikiPageForm
from app.community.util import search_for_community, actor_to_community, \
save_post, save_icon_file, save_banner_file, send_to_remote_instance, \
delete_post_from_community, delete_post_reply_from_community, community_in_list, find_local_users
@ -25,7 +26,8 @@ from app.constants import SUBSCRIPTION_MEMBER, SUBSCRIPTION_OWNER, POST_TYPE_LIN
from app.inoculation import inoculation
from app.models import User, Community, CommunityMember, CommunityJoinRequest, CommunityBan, Post, \
File, PostVote, utcnow, Report, Notification, InstanceBlock, ActivityPubLog, Topic, Conversation, PostReply, \
NotificationSubscription, UserFollower, Instance, Language, Poll, PollChoice, ModLog
NotificationSubscription, UserFollower, Instance, Language, Poll, PollChoice, ModLog, CommunityWikiPage, \
CommunityWikiPageRevision
from app.community import bp
from app.user.utils import search_for_user
from app.utils import get_setting, render_template, allowlist_html, markdown_to_html, validation_required, \
@ -1326,6 +1328,184 @@ def community_moderate_subscribers(actor):
abort(404)
@bp.route('/<actor>/moderate/wiki', methods=['GET'])
@login_required
def community_wiki_list(actor):
community = actor_to_community(actor)
if community is not None:
if community.is_moderator() or current_user.is_admin():
low_bandwidth = request.cookies.get('low_bandwidth', '0') == '1'
pages = CommunityWikiPage.query.filter(CommunityWikiPage.community_id == community.id).order_by(CommunityWikiPage.title).all()
return render_template('community/community_wiki_list.html', title=_('Community Wiki'), community=community,
pages=pages, low_bandwidth=low_bandwidth, current='wiki',
moderating_communities=moderating_communities(current_user.get_id()),
joined_communities=joined_communities(current_user.get_id()),
menu_topics=menu_topics(), site=g.site,
inoculation=inoculation[randint(0, len(inoculation) - 1)] if g.site.show_inoculation_block else None
)
else:
abort(401)
else:
abort(404)
@bp.route('/<actor>/moderate/wiki/add', methods=['GET', 'POST'])
@login_required
def community_wiki_add(actor):
community = actor_to_community(actor)
if community is not None:
if community.is_moderator() or current_user.is_admin():
low_bandwidth = request.cookies.get('low_bandwidth', '0') == '1'
form = EditCommunityWikiPageForm()
if form.validate_on_submit():
new_page = CommunityWikiPage(community_id=community.id, slug=form.slug.data, title=form.title.data,
body=form.body.data, who_can_edit=form.who_can_edit.data)
new_page.body_html = markdown_to_html(new_page.body)
db.session.add(new_page)
db.session.commit()
initial_revision = CommunityWikiPageRevision(wiki_page_id=new_page.id, user_id=current_user.id,
community_id=community.id, title=form.title.data,
body=form.body.data, body_html=new_page.body_html)
db.session.add(initial_revision)
db.session.commit()
flash(_('Saved'))
return redirect(url_for('community.community_wiki_list', actor=community.link()))
return render_template('community/community_wiki_edit.html', title=_('Add wiki page'), community=community,
form=form, low_bandwidth=low_bandwidth, current='wiki',
moderating_communities=moderating_communities(current_user.get_id()),
joined_communities=joined_communities(current_user.get_id()),
menu_topics=menu_topics(), site=g.site,
inoculation=inoculation[randint(0, len(inoculation) - 1)] if g.site.show_inoculation_block else None
)
else:
abort(401)
else:
abort(404)
@bp.route('/<actor>/wiki/<slug>', methods=['GET', 'POST'])
def community_wiki_view(actor, slug):
community = actor_to_community(actor)
if community is not None:
page: CommunityWikiPage = CommunityWikiPage.query.filter_by(slug=slug, community_id=community.id).first()
if page is None:
abort(404)
else:
# Breadcrumbs
breadcrumbs = []
breadcrumb = namedtuple("Breadcrumb", ['text', 'url'])
breadcrumb.text = _('Home')
breadcrumb.url = '/'
breadcrumbs.append(breadcrumb)
if community.topic_id:
topics = []
previous_topic = Topic.query.get(community.topic_id)
topics.append(previous_topic)
while previous_topic.parent_id:
topic = Topic.query.get(previous_topic.parent_id)
topics.append(topic)
previous_topic = topic
topics = list(reversed(topics))
breadcrumb = namedtuple("Breadcrumb", ['text', 'url'])
breadcrumb.text = _('Topics')
breadcrumb.url = '/topics'
breadcrumbs.append(breadcrumb)
existing_url = '/topic'
for topic in topics:
breadcrumb = namedtuple("Breadcrumb", ['text', 'url'])
breadcrumb.text = topic.name
breadcrumb.url = f"{existing_url}/{topic.machine_name}"
breadcrumbs.append(breadcrumb)
existing_url = breadcrumb.url
else:
breadcrumb = namedtuple("Breadcrumb", ['text', 'url'])
breadcrumb.text = _('Communities')
breadcrumb.url = '/communities'
breadcrumbs.append(breadcrumb)
return render_template('community/community_wiki_page_view.html', title=page.title, page=page,
community=community, breadcrumbs=breadcrumbs, is_moderator=community.is_moderator(),
is_owner=community.is_owner(),
moderating_communities=moderating_communities(current_user.get_id()),
joined_communities=joined_communities(current_user.get_id()),
menu_topics=menu_topics(), site=g.site,
inoculation=inoculation[
randint(0, len(inoculation) - 1)] if g.site.show_inoculation_block else None
)
@bp.route('/<actor>/moderate/wiki/<int:page_id>/edit', methods=['GET', 'POST'])
@login_required
def community_wiki_edit(actor, page_id):
community = actor_to_community(actor)
if community is not None:
page: CommunityWikiPage = CommunityWikiPage.query.get_or_404(page_id)
if page.can_edit(current_user, community):
low_bandwidth = request.cookies.get('low_bandwidth', '0') == '1'
form = EditCommunityWikiPageForm()
if form.validate_on_submit():
page.title = form.title.data
page.slug = form.slug.data
page.body = form.body.data
page.body_html = markdown_to_html(page.body)
page.who_can_edit = form.who_can_edit.data
page.edited_at = utcnow()
new_revision = CommunityWikiPageRevision(wiki_page_id=page.id, user_id=current_user.id,
community_id=community.id, title=form.title.data,
body=form.body.data, body_html=page.body_html)
db.session.add(new_revision)
db.session.commit()
flash(_('Saved'))
if request.args.get('return') == 'list':
return redirect(url_for('community.community_wiki_list', actor=community.link()))
elif request.args.get('return') == 'page':
return redirect(url_for('community.community_wiki_view', actor=community.link(), slug=page.slug))
else:
form.title.data = page.title
form.slug.data = page.slug
form.body.data = page.body
form.who_can_edit.data = page.who_can_edit
return render_template('community/community_wiki_edit.html', title=_('Edit wiki page'), community=community,
form=form, low_bandwidth=low_bandwidth,
moderating_communities=moderating_communities(current_user.get_id()),
joined_communities=joined_communities(current_user.get_id()),
menu_topics=menu_topics(), site=g.site,
inoculation=inoculation[randint(0, len(inoculation) - 1)] if g.site.show_inoculation_block else None
)
else:
abort(401)
else:
abort(404)
@bp.route('/<actor>/moderate/wiki/<int:page_id>/delete', methods=['GET'])
@login_required
def community_wiki_delete(actor, page_id):
community = actor_to_community(actor)
if community is not None:
page: CommunityWikiPage = CommunityWikiPage.query.get_or_404(page_id)
if page.can_edit(current_user, community):
db.session.delete(page)
db.session.commit()
flash(_('Page deleted'))
return redirect(url_for('community.community_wiki_list', actor=community.link()))
else:
abort(404)
@bp.route('/<actor>/moderate/modlog', methods=['GET'])
@login_required
def community_modlog(actor):

View file

@ -406,6 +406,7 @@ class Community(db.Model):
posts = db.relationship('Post', lazy='dynamic', cascade="all, delete-orphan")
replies = db.relationship('PostReply', lazy='dynamic', cascade="all, delete-orphan")
wiki_pages = db.relationship('CommunityWikiPage', lazy='dynamic', backref='community', cascade="all, delete-orphan")
icon = db.relationship('File', foreign_keys=[icon_id], single_parent=True, backref='community', cascade="all, delete-orphan")
image = db.relationship('File', foreign_keys=[image_id], single_parent=True, cascade="all, delete-orphan")
languages = db.relationship('Language', lazy='dynamic', secondary=community_language, backref=db.backref('communities', lazy='dynamic'))
@ -476,15 +477,25 @@ class Community(db.Model):
))
).filter(CommunityMember.is_banned == False).all()
def is_member(self, user):
if user is None:
return CommunityMember.query.filter(CommunityMember.user_id == current_user.get_id(),
CommunityMember.community_id == self.id,
CommunityMember.is_banned == False).all()
else:
return CommunityMember.query.filter(CommunityMember.user_id == user.id,
CommunityMember.community_id == self.id,
CommunityMember.is_banned == False).all()
def is_moderator(self, user=None):
if user is None:
return any(moderator.user_id == current_user.id for moderator in self.moderators())
return any(moderator.user_id == current_user.get_id() for moderator in self.moderators())
else:
return any(moderator.user_id == user.id for moderator in self.moderators())
def is_owner(self, user=None):
if user is None:
return any(moderator.user_id == current_user.id and moderator.is_owner for moderator in self.moderators())
return any(moderator.user_id == current_user.get_id() and moderator.is_owner for moderator in self.moderators())
else:
return any(moderator.user_id == user.id and moderator.is_owner for moderator in self.moderators())
@ -1246,6 +1257,46 @@ class CommunityMember(db.Model):
created_at = db.Column(db.DateTime, default=utcnow)
class CommunityWikiPage(db.Model):
id = db.Column(db.Integer, primary_key=True)
community_id = db.Column(db.Integer, db.ForeignKey('community.id'), index=True)
slug = db.Column(db.String(100), index=True)
title = db.Column(db.String(255))
body = db.Column(db.Text)
body_html = db.Column(db.Text)
created_at = db.Column(db.DateTime, default=utcnow)
edited_at = db.Column(db.DateTime, default=utcnow)
who_can_edit = db.Column(db.Integer, default=0) # 0 = mods & admins, 1 = trusted, 2 = community members, 3 = anyone
revisions = db.relationship('CommunityWikiPageRevision', backref=db.backref('page'), cascade='all,delete',
lazy='dynamic')
def can_edit(self, user: User, community: Community):
if user.is_anonymous:
return False
if self.who_can_edit == 0:
if user.is_admin() or user.is_staff() or community.is_moderator(user):
return True
elif self.who_can_edit == 1:
if user.is_admin() or user.is_staff() or community.is_moderator(user) or user.trustworthy():
return True
elif self.who_can_edit == 2:
if user.is_admin() or user.is_staff() or community.is_moderator(user) or user.trustworthy() or community.is_member(user):
return True
elif self.who_can_edit == 3:
return True
return False
class CommunityWikiPageRevision(db.Model):
id = db.Column(db.Integer, primary_key=True)
wiki_page_id = db.Column(db.Integer, db.ForeignKey('community_wiki_page.id'), index=True)
community_id = db.Column(db.Integer, db.ForeignKey('community.id'), index=True)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
title = db.Column(db.String(255))
body = db.Column(db.Text)
body_html = db.Column(db.Text)
edited_at = db.Column(db.DateTime, default=utcnow)
class UserFollower(db.Model):
local_user_id = db.Column(db.Integer, db.ForeignKey('user.id'), primary_key=True)
remote_user_id = db.Column(db.Integer, db.ForeignKey('user.id'), primary_key=True)

View file

@ -55,7 +55,7 @@ def show_post(post_id: int):
flash(_('%(name)s has indicated they made a mistake in this post.', name=post.author.user_name), 'warning')
mods = community_moderators(community.id)
is_moderator = current_user.is_authenticated and any(mod.user_id == current_user.id for mod in mods)
is_moderator = community.is_moderator()
if community.private_mods:
mod_list = []
@ -310,21 +310,19 @@ def show_post(post_id: int):
if post.type == POST_TYPE_LINK and body_has_no_archive_link(post.body_html) and url_needs_archive(post.url):
archive_link = generate_archive_link(post.url)
response = render_template('post/post.html', title=post.title, post=post, is_moderator=is_moderator, community=post.community,
response = render_template('post/post.html', title=post.title, post=post, is_moderator=is_moderator, is_owner=community.is_owner(),
community=post.community,
breadcrumbs=breadcrumbs, related_communities=related_communities, mods=mod_list,
poll_form=poll_form, poll_results=poll_results, poll_data=poll_data, poll_choices=poll_choices, poll_total_votes=poll_total_votes,
canonical=post.ap_id, form=form, replies=replies, THREAD_CUTOFF_DEPTH=constants.THREAD_CUTOFF_DEPTH,
description=description, og_image=og_image, POST_TYPE_IMAGE=constants.POST_TYPE_IMAGE,
POST_TYPE_LINK=constants.POST_TYPE_LINK, POST_TYPE_ARTICLE=constants.POST_TYPE_ARTICLE,
POST_TYPE_VIDEO=constants.POST_TYPE_VIDEO, POST_TYPE_POLL=constants.POST_TYPE_POLL,
description=description, og_image=og_image,
autoplay=request.args.get('autoplay', False), archive_link=archive_link,
noindex=not post.author.indexable, preconnect=post.url if post.url else None,
recently_upvoted=recently_upvoted, recently_downvoted=recently_downvoted,
recently_upvoted_replies=recently_upvoted_replies, recently_downvoted_replies=recently_downvoted_replies,
reply_collapse_threshold=reply_collapse_threshold,
etag=f"{post.id}{sort}_{hash(post.last_active)}", markdown_editor=current_user.is_authenticated and current_user.markdown_editor,
low_bandwidth=request.cookies.get('low_bandwidth', '0') == '1', SUBSCRIPTION_MEMBER=SUBSCRIPTION_MEMBER,
SUBSCRIPTION_OWNER=SUBSCRIPTION_OWNER, SUBSCRIPTION_MODERATOR=SUBSCRIPTION_MODERATOR,
low_bandwidth=request.cookies.get('low_bandwidth', '0') == '1',
moderating_communities=moderating_communities(current_user.get_id()),
joined_communities=joined_communities(current_user.get_id()),
menu_topics=menu_topics(), site=g.site,

View file

@ -13,6 +13,9 @@
<a href="{{ url_for('community.community_moderate_subscribers', actor=community.link()) }}" class="btn {{ 'btn-primary' if current == 'subscribers' else 'btn-outline-secondary' }}" rel="nofollow noindex">
{{ _('Subscribers') }}
</a>
<a href="{{ url_for('community.community_wiki_list', actor=community.link()) }}" class="btn {{ 'btn-primary' if current == 'wiki' else 'btn-outline-secondary' }}" rel="nofollow noindex">
{{ _('Wiki') }}
</a>
<a href="/community/{{ community.link() }}/moderate/appeals" class="btn {{ 'btn-primary' if current == 'appeals' else 'btn-outline-secondary' }} disabled" rel="nofollow noindex" >
{{ _('Appeals') }}
</a>

View file

@ -0,0 +1,18 @@
{% if theme() and file_exists('app/templates/themes/' + theme() + '/base.html') %}
{% extends 'themes/' + theme() + '/base.html' %}
{% else %}
{% extends "base.html" %}
{% endif %} %}
{% from 'bootstrap/form.html' import render_form, render_field %}
{% block app_content %}
<div class="row">
<div class="col-12 col-md-8 position-relative main_pane">
{% block title %}<h1>{{ title }}</h1>{% endblock %}
{{ render_form(form) }}
</div>
{% include "_side_pane.html" %}
</div>
{% endblock %}

View file

@ -0,0 +1,67 @@
{% if theme() and file_exists('app/templates/themes/' + theme() + '/base.html') %}
{% extends 'themes/' + theme() + '/base.html' %}
{% else %}
{% extends "base.html" %}
{% endif %} %}
{% from 'bootstrap/form.html' import render_field %}
{% block app_content %}
<div class="row">
<div class="col-12 col-md-8 position-relative main_pane">
<nav aria-label="breadcrumb" id="breadcrumb_nav" title="Navigation">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="/">{{ _('Home') }}</a></li>
<li class="breadcrumb-item"><a href="{{ url_for('activitypub.community_profile', actor=community.ap_id if community.ap_id is not none else community.name) }}">{{ (community.title + '@' + community.ap_domain)|shorten }}</a></li>
<li class="breadcrumb-item"><a href="{{ url_for('community.community_edit', community_id=community.id) }}">{{ _('Settings') }}</a></li>
<li class="breadcrumb-item active">{{ _('Wiki') }}</li>
</ol>
</nav>
{% include "community/_community_moderation_nav.html" %}
<div class="row">
<div class="col-12 col-md-10">
<h1 class="mt-2">{{ _('Wiki pages for %(community)s', community=community.display_name()) }}</h1>
</div>
<div class="col-12 text-right">
<a class="btn btn-primary" href="{{ url_for('community.community_wiki_add', actor=community.link()) }}">{{ _('Add wiki page') }}</a>
</div>
</div>
{% if pages -%}
<table class="table table-responsive">
<thead>
<tr>
<th>{{ _('Name') }}</th>
<th>{{ _('Url') }}</th>
<th> </th>
</tr>
</thead>
<tbody>
{% for page in pages %}
<tr>
<td>{{ page.title }}</td>
<td><a href="{{ url_for('community.community_wiki_view', actor=community.link(), slug=page.slug) }}">{{ page.slug }}</a></td>
<td class="text-right">{% if page.can_edit(current_user, community) %}
<div class="dropdown">
<button class="btn btn-primary btn-sm dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
Actions
</button>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="{{ url_for('community.community_wiki_view', actor=community.link(), slug=page.slug) }}">{{ _('View') }}</a></li>
<li><a class="dropdown-item"
href="{{ url_for('community.community_wiki_edit', actor=community.link(), page_id=page.id, return='list') }}">
{{ _('Edit') }}</a></li>
<li><a class="confirm_first dropdown-item"
href="{{ url_for('community.community_wiki_delete', actor=community.link(), page_id=page.id) }}">
{{ _('Delete') }}</a></li>
</ul>
</div>
{% endif %}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else -%}
<p>{{ _('There are no wiki pages in this community.') }}</p>
{% endif -%}
</div>
</div>
{% endblock %}

View file

@ -0,0 +1,33 @@
{% if theme() and file_exists('app/templates/themes/' + theme() + '/base.html') -%}
{% extends 'themes/' + theme() + '/base.html' -%}
{% else -%}
{% extends "base.html" -%}
{% endif -%} -%}
{% from 'bootstrap/form.html' import render_form -%}
{% block app_content -%}
<div class="row">
<div class="col-12 col-md-8 position-relative main_pane">
<div class="row position-relative">
<div class="col post_col post_type_normal">
<nav aria-label="breadcrumb" id="breadcrumb_nav" title="Navigation">
<ol class="breadcrumb">
{% for breadcrumb in breadcrumbs -%}
<li class="breadcrumb-item">{% if breadcrumb.url -%}<a href="{{ breadcrumb.url }}">{% endif -%}{{ breadcrumb.text }}{% if breadcrumb.url -%}</a>{% endif -%}</li>
{% endfor -%}
<li class="breadcrumb-item"><a href="/c/{{ page.community.link() }}">{{ page.community.title }}@{{ page.community.ap_domain }}</a></li>
<li class="breadcrumb-item active">{{ page.title|shorten(15) }}</li>
</ol>
</nav>
<h1 class="mt-2 post_title">{{ page.title }}</h1>
{{ page.body_html | safe }}
{% if page.can_edit(current_user, community) -%}
<p><a class="btn btn-primary" href="{{ url_for('community.community_wiki_edit', actor=community.link(), page_id=page.id, return='page') }}">{{ _('Edit') }}</a></p>
{% endif %}
</div>
</div>
</div>
{% include "_side_pane.html" %}
</div>
{% endblock -%}

View file

@ -0,0 +1,71 @@
"""wikis
Revision ID: b97584a7a10b
Revises: ea5a07acf23c
Create Date: 2024-07-17 20:54:20.626562
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = 'b97584a7a10b'
down_revision = 'ea5a07acf23c'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('community_wiki_page',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('community_id', sa.Integer(), nullable=True),
sa.Column('slug', sa.String(length=100), nullable=True),
sa.Column('title', sa.String(length=255), nullable=True),
sa.Column('body', sa.Text(), nullable=True),
sa.Column('body_html', sa.Text(), nullable=True),
sa.Column('created_at', sa.DateTime(), nullable=True),
sa.Column('edited_at', sa.DateTime(), nullable=True),
sa.Column('who_can_edit', sa.Integer(), nullable=True),
sa.ForeignKeyConstraint(['community_id'], ['community.id'], ),
sa.PrimaryKeyConstraint('id')
)
with op.batch_alter_table('community_wiki_page', schema=None) as batch_op:
batch_op.create_index(batch_op.f('ix_community_wiki_page_community_id'), ['community_id'], unique=False)
batch_op.create_index(batch_op.f('ix_community_wiki_page_slug'), ['slug'], unique=False)
op.create_table('community_wiki_page_revision',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('wiki_page_id', sa.Integer(), nullable=True),
sa.Column('community_id', sa.Integer(), nullable=True),
sa.Column('user_id', sa.Integer(), nullable=True),
sa.Column('title', sa.String(length=255), nullable=True),
sa.Column('body', sa.Text(), nullable=True),
sa.Column('body_html', sa.Text(), nullable=True),
sa.Column('edited_at', sa.DateTime(), nullable=True),
sa.ForeignKeyConstraint(['community_id'], ['community.id'], ),
sa.ForeignKeyConstraint(['user_id'], ['user.id'], ),
sa.ForeignKeyConstraint(['wiki_page_id'], ['community_wiki_page.id'], ),
sa.PrimaryKeyConstraint('id')
)
with op.batch_alter_table('community_wiki_page_revision', schema=None) as batch_op:
batch_op.create_index(batch_op.f('ix_community_wiki_page_revision_community_id'), ['community_id'], unique=False)
batch_op.create_index(batch_op.f('ix_community_wiki_page_revision_wiki_page_id'), ['wiki_page_id'], unique=False)
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('community_wiki_page_revision', schema=None) as batch_op:
batch_op.drop_index(batch_op.f('ix_community_wiki_page_revision_wiki_page_id'))
batch_op.drop_index(batch_op.f('ix_community_wiki_page_revision_community_id'))
op.drop_table('community_wiki_page_revision')
with op.batch_alter_table('community_wiki_page', schema=None) as batch_op:
batch_op.drop_index(batch_op.f('ix_community_wiki_page_slug'))
batch_op.drop_index(batch_op.f('ix_community_wiki_page_community_id'))
op.drop_table('community_wiki_page')
# ### end Alembic commands ###

View file

@ -9,7 +9,7 @@ from app import create_app, db, cli
import os, click
from flask import session, g, json, request, current_app
from app.constants import POST_TYPE_LINK, POST_TYPE_IMAGE, POST_TYPE_ARTICLE, POST_TYPE_VIDEO, POST_TYPE_POLL, \
SUBSCRIPTION_MODERATOR
SUBSCRIPTION_MODERATOR, SUBSCRIPTION_MEMBER, SUBSCRIPTION_OWNER, SUBSCRIPTION_PENDING
from app.models import Site
from app.utils import getmtime, gibberish, shorten_string, shorten_url, digits, user_access, community_membership, \
can_create_post, can_upvote, can_downvote, shorten_number, ap_datetime, current_theme, community_link_to_href, \
@ -26,7 +26,8 @@ def app_context_processor():
return dict(getmtime=getmtime, instance_domain=current_app.config['SERVER_NAME'],
POST_TYPE_LINK=POST_TYPE_LINK, POST_TYPE_IMAGE=POST_TYPE_IMAGE,
POST_TYPE_ARTICLE=POST_TYPE_ARTICLE, POST_TYPE_VIDEO=POST_TYPE_VIDEO, POST_TYPE_POLL=POST_TYPE_POLL,
SUBSCRIPTION_MODERATOR=SUBSCRIPTION_MODERATOR)
SUBSCRIPTION_MODERATOR=SUBSCRIPTION_MODERATOR, SUBSCRIPTION_MEMBER=SUBSCRIPTION_MEMBER,
SUBSCRIPTION_OWNER=SUBSCRIPTION_OWNER, SUBSCRIPTION_PENDING=SUBSCRIPTION_PENDING)
@app.shell_context_processor