implement post and comment restrictions, changes to views
This commit is contained in:
parent
a88b12e844
commit
e7912ad88c
10 changed files with 53 additions and 17 deletions
|
|
@ -13,6 +13,7 @@
|
|||
+ Allowed operations: change display name, description, restriction status, and exile (guild-local ban) members
|
||||
+ Site administrators and guild owners can add moderators
|
||||
- Administrators can claim ownership of abandoned guilds
|
||||
- Guilds can have restricted posting/commenting now. Unmoderated guilds always have.
|
||||
- Implemented guild subscriptions (not as in $$$, yes as in the follow button)
|
||||
- Minimum karma requirement for creating a guild is now configurable via env variable `FREAK_CREATE_GUILD_THRESHOLD` (previously hardcoded at 15)
|
||||
- Users can now set their display name, biography and color theme in `/settings`
|
||||
|
|
|
|||
|
|
@ -33,9 +33,9 @@ def username_availability(username: str):
|
|||
'is_available': is_available
|
||||
}
|
||||
|
||||
@bp.route('/guild_name_availability/<username>')
|
||||
@bp.route('/guild_name_availability/<name>')
|
||||
def guild_name_availability(name: str):
|
||||
is_valid = re.fullmatch('[a-z0-9_-]+', name) is not None
|
||||
is_valid = username_is_legal(name)
|
||||
|
||||
if is_valid:
|
||||
gd = db.session.execute(select(Guild).where(Guild.name == name)).scalar()
|
||||
|
|
|
|||
|
|
@ -42,9 +42,10 @@ post_report_reasons = [
|
|||
ReportReason(180, 'impersonation', 'Impersonation'),
|
||||
ReportReason(141, 'doxing', 'Diffusion of PII (personally identifiable information)'),
|
||||
## less urgent
|
||||
ReportReason(140, 'bullying', 'Harassment, bullying, or suicide incitement'),
|
||||
ReportReason(112, 'lgbt_hate', 'Hate speech against LGBTQ+ or women'),
|
||||
ReportReason(140, 'bullying', 'Harassment, bullying, or suicide incitement'),
|
||||
ReportReason(150, 'security_exploit', 'Dangerous security exploit or violation'),
|
||||
ReportReason(160, 'spam', 'Unsolicited advertising'),
|
||||
ReportReason(190, 'false_information', 'False or deceiving information'),
|
||||
ReportReason(123, 'copyviol', 'This is my creation and someone else is using it without my permission/license'),
|
||||
## minor (unironically)
|
||||
|
|
@ -168,7 +169,7 @@ class User(Base):
|
|||
## XXX posts and comments relationships are temporarily disabled because they make
|
||||
## SQLAlchemy fail initialization of models — bricking the app.
|
||||
## Posts are queried manually anyway
|
||||
#posts = relationship("Post", back_populates='author', )
|
||||
#posts = relationship("Post", primaryjoin=lambda: #back_populates='author', pr)
|
||||
upvoted_posts = relationship("Post", secondary=PostUpvote, back_populates='upvoters')
|
||||
#comments = relationship("Comment", back_populates='author')
|
||||
|
||||
|
|
@ -364,8 +365,10 @@ class Guild(Base):
|
|||
mem: Member | None = db.session.execute(select(Member).where(Member.user_id == other.id, Member.guild_id == self.id)).scalar() if other else None
|
||||
if mem and mem.is_banned:
|
||||
return False
|
||||
if other.moderates(self):
|
||||
return True
|
||||
if self.is_restricted:
|
||||
return mem and mem.is_approved
|
||||
return (mem and mem.is_approved)
|
||||
return True
|
||||
|
||||
|
||||
|
|
@ -447,7 +450,7 @@ class Post(Base):
|
|||
title = Column(String(256), nullable=False)
|
||||
post_type = Column(SmallInteger, server_default=text('0'))
|
||||
author_id = Column(BigInteger, ForeignKey('freak_user.id', name='post_author_id'), nullable=True)
|
||||
topic_id = Column(BigInteger, ForeignKey('freak_topic.id', name='post_topic_id'), nullable=True)
|
||||
topic_id = Column('topic_id', BigInteger, ForeignKey('freak_topic.id', name='post_topic_id'), nullable=True)
|
||||
created_at = Column(DateTime, server_default=func.current_timestamp())
|
||||
created_ip = Column(String(64), default=get_remote_addr, nullable=False)
|
||||
updated_at = Column(DateTime, nullable=True)
|
||||
|
|
@ -465,7 +468,7 @@ class Post(Base):
|
|||
|
||||
# utilities
|
||||
author: Relationship[User] = relationship("User", lazy='selectin', foreign_keys=[author_id])#, back_populates="posts")
|
||||
guild = relationship("Guild", back_populates="posts", lazy='selectin')
|
||||
guild: Relationship[Guild] = relationship("Guild", back_populates="posts", lazy='selectin')
|
||||
comments = relationship("Comment", back_populates="parent_post")
|
||||
upvoters = relationship("User", secondary=PostUpvote, back_populates='upvoted_posts')
|
||||
|
||||
|
|
|
|||
|
|
@ -27,21 +27,30 @@
|
|||
usernameInputMessage.className = 'username-input-message error';
|
||||
return;
|
||||
}
|
||||
if (value.length >= 100) {
|
||||
usernameInputMessage.innerHTML = 'Your username must be shorter.';
|
||||
usernameInputMessage.className = 'username-input-message error';
|
||||
return;
|
||||
}
|
||||
if(/^[01]/.test(value)) {
|
||||
usernameInputMessage.innerHTML = 'Your username cannot start with 0 or 1.';
|
||||
usernameInputMessage.className = 'username-input-message error';
|
||||
return;
|
||||
}
|
||||
usernameInputMessage.innerHTML = 'Checking username...';
|
||||
usernameInputMessage.className = 'username-input-message checking';
|
||||
usernameInputMessage.className = 'username-input-message checking faint';
|
||||
requestUsernameAvailability(value, endpoint).then((resp) => {
|
||||
if (['ok', void 0].indexOf(resp.status) < 0){
|
||||
usernameInputMessage.innerHTML = 'Sorry, there was an unknown error.';
|
||||
usernameInputMessage.className = 'username-input-message error';
|
||||
return;
|
||||
}
|
||||
if (resp.is_available){
|
||||
usernameInputMessage.innerHTML = "The username @" + value + " is available!";
|
||||
if (!resp.is_legal) {
|
||||
usernameInputMessage.innerHTML = "You can't use this username.";
|
||||
usernameInputMessage.className = 'username-input-message error';
|
||||
return;
|
||||
} else if (resp.is_available){
|
||||
usernameInputMessage.innerHTML = `The username @${value} is available!`;
|
||||
usernameInputMessage.className = 'username-input-message success';
|
||||
return;
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@
|
|||
<!-- no user -->
|
||||
{% elif current_user.is_authenticated %}
|
||||
<li class="nomobile">
|
||||
<a class="round border-accent" href="/create" title="Create a post" aria-label="Create a post">
|
||||
<a class="round border-accent" href="{{ url_for('create.create', on=current_guild.name) if current_guild else '/create/' }}" title="Create a post" aria-label="Create a post">
|
||||
{{ icon('add') }}
|
||||
<span>New post</span>
|
||||
</a>
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
<form action="{{ url_for('create.createguild') }}" method="POST" enctype="multipart/form-data" class="boundaryless">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||
<div>
|
||||
<p>URL of the guild: <strong>+</strong><input type="text" class="username-input" name="name" required="true" data-endpoint="guild_name_availability/$1" /></p>
|
||||
<p>URL of the guild: <strong>+</strong><input type="text" class="username-input" name="name" required="true" data-endpoint="/guild_name_availability/$1" /></p>
|
||||
<p><small class="faint">Must be alphanumeric and unique. <strong>May not be changed later</strong>: choose wisely!</small></p>
|
||||
</div>
|
||||
<div>
|
||||
|
|
|
|||
|
|
@ -22,9 +22,16 @@ disabled=""
|
|||
</ul>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro comment_area(url) %}
|
||||
{% macro comment_area(p) %}
|
||||
{% if current_user.is_authenticated %}
|
||||
<form id="comment-area" class="boundaryless" action="{{ url }}" method="POST" enctype="multipart/form-data">
|
||||
{% if current_user.is_disabled %}
|
||||
<div class="centered">Your account is suspended</div>
|
||||
{% elif current_guild and not current_guild.allows_posting(current_user) %}
|
||||
<div class="centered">This community allows only its members to post and comment</div>
|
||||
{% elif p.is_locked %}
|
||||
<div class="centered">Comments are closed</div>
|
||||
{% else %}
|
||||
<form id="comment-area" class="boundaryless" action="{{ p.url() }}" method="POST" enctype="multipart/form-data">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
||||
<input type="hidden" name="reply_to" value="" />
|
||||
<div>
|
||||
|
|
@ -35,6 +42,7 @@ disabled=""
|
|||
<button type="submit" class="primary">Publish</button>
|
||||
</div>
|
||||
</form>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<div class="centered"><a href="/login">Log in</a> to leave a comment</div>
|
||||
{% endif %}
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@
|
|||
</ul>
|
||||
</div>
|
||||
|
||||
{{ comment_area(p.url()) }}
|
||||
{{ comment_area(p) }}
|
||||
<div class="comment-section">
|
||||
<ul>
|
||||
{% for comment in comments %}
|
||||
|
|
|
|||
|
|
@ -40,6 +40,20 @@ def user_profile_s(username):
|
|||
|
||||
|
||||
def single_post_post_hook(p: Post):
|
||||
if p.guild is not None:
|
||||
gu = p.guild
|
||||
if gu.has_exiled(current_user):
|
||||
flash(f'You have been banned from {gu.handle()}')
|
||||
return
|
||||
|
||||
if not gu.allows_posting(current_user):
|
||||
flash(f'You can\'t post in {gu.handle()}')
|
||||
return
|
||||
|
||||
if p.is_locked:
|
||||
flash(f'You can\'t comment on locked posts')
|
||||
return
|
||||
|
||||
if 'reply_to' in request.form:
|
||||
reply_to_id = request.form['reply_to']
|
||||
text = request.form['text']
|
||||
|
|
@ -100,7 +114,7 @@ def guild_post_detail(gname, id, slug=''):
|
|||
if request.method == 'POST':
|
||||
single_post_post_hook(post)
|
||||
|
||||
return render_template('singlepost.html', p=post, comments=comments_of(post))
|
||||
return render_template('singlepost.html', p=post, comments=comments_of(post), current_guild = post.guild)
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,8 @@ def guild_feed(name):
|
|||
posts = db.paginate(topic_timeline(name))
|
||||
|
||||
return render_template(
|
||||
'feed.html', feed_type='guild', feed_title=f'{guild.display_name} (+{guild.name})', l=posts, guild=guild)
|
||||
'feed.html', feed_type='guild', feed_title=f'{guild.display_name} (+{guild.name})', l=posts, guild=guild,
|
||||
current_guild=guild)
|
||||
|
||||
@bp.route('/r/<name>/')
|
||||
def guild_feed_r(name):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue