feature: ajout du post en tant qu'invité

- Pour les commentaires seulement
- Ajout d'une option pour désactiver (antispam)
- Penser à faire les ACL rapidement…
- Un poil de CSS pour l'intégration du bouzin
This commit is contained in:
Darks 2020-07-17 23:49:04 +02:00
parent b2ea2ce6ad
commit e6c1545031
Signed by: Darks
GPG Key ID: F61F10FA138E797C
10 changed files with 113 additions and 16 deletions

View File

@ -1,6 +1,7 @@
from flask_wtf import FlaskForm
from wtforms import StringField, FormField, SubmitField, TextAreaField
from wtforms.validators import DataRequired, Length
import app.utils.validators as vd
class TopicCreationForm(FlaskForm):
title = StringField('Nom du sujet',
@ -8,6 +9,15 @@ class TopicCreationForm(FlaskForm):
message = TextAreaField('Message principal', validators=[DataRequired()])
submit = SubmitField('Créer le sujet')
class AnonymousTopicCreationForm(TopicCreationForm):
pseudo = StringField('Pseudo',
validators=[DataRequired(), vd.name_valid, vd.name_available])
class CommentForm(FlaskForm):
message = TextAreaField('Commentaire', validators=[DataRequired()])
submit = SubmitField('Commenter')
class AnonymousCommentForm(CommentForm):
pseudo = StringField('Pseudo',
validators=[DataRequired(), vd.name_valid, vd.name_available])

View File

@ -51,14 +51,15 @@ class Guest(User):
# ID of the [User] entry
id = db.Column(db.Integer, db.ForeignKey('user.id'), primary_key=True)
# Reusable username, can be the name of a member (will be distinguished at
# rendering time)
username = db.Column(db.Unicode(64), index=True)
# IP address, 47 characters is the max for an IPv6 address
ip = db.Column(db.String(47))
# Reusable username, cannot be chosen as the name of a member
# but will be distinguished at rendering time if a member take it later
name = db.Column(db.Unicode(64))
def __init__(self, name):
self.name = name
def __repr__(self):
return f'<Guest: {self.username} ({self.ip})>'
return f'<Guest: {self.username}>'
class Member(User):

View File

@ -1,5 +1,6 @@
from app import app
from flask import url_for
from config import V5Config
@app.context_processor
def utilities_processor():
@ -8,4 +9,5 @@ def utilities_processor():
len=len,
# enumerate=enumerate,
_url_for = lambda route, args, **other: url_for(route, **args, **other),
V5Config = V5Config,
)

View File

@ -4,11 +4,12 @@ from flask import request, redirect, url_for, flash, abort
from app import app, db
from config import V5Config
from app.utils.render import render
from app.forms.forum import CommentForm
from app.forms.forum import CommentForm, AnonymousCommentForm
from app.models.forum import Forum
from app.models.topic import Topic
from app.models.thread import Thread
from app.models.comment import Comment
from app.models.users import Guest
@app.route('/forum/<forum:f>/<topicpage:page>', methods=['GET', 'POST'])
@ -19,16 +20,27 @@ def forum_topic(f, page):
if f != t.forum:
abort(404)
form = CommentForm()
if current_user.is_authenticated:
form = CommentForm()
else:
form = AnonymousCommentForm()
if form.validate_on_submit():
c = Comment(current_user, form.message.data, t.thread)
if form.validate_on_submit() and \
(V5Config.ENABLE_GUEST_POST or current_user.is_authenticated):
if current_user.is_authenticated:
author = current_user
else:
author = Guest(form.pseudo.data)
db.session.add(author)
c = Comment(author, form.message.data, t.thread)
db.session.add(c)
db.session.commit()
# Update member's xp and trophies
current_user.add_xp(V5Config.XP_POINTS['comment'])
current_user.update_trophies('new-post')
if current_user.is_authenticated:
current_user.add_xp(V5Config.XP_POINTS['comment'])
current_user.update_trophies('new-post')
flash('Message envoyé', 'ok')
# Redirect to empty the form

View File

@ -17,7 +17,7 @@
body {
margin: 0;
background: var(--background); color: var(--text);
font-family: Twemoji, 'DejaVu Sans', sans-serif;
font-family: 'DejaVu Sans', sans-serif;
}
/* General */

View File

@ -71,6 +71,15 @@ table.thread {
table.thread td.member {
width: 20%;
}
table.thread td.guest {
width: 20%; padding-top: 12px;
text-align: center;
}
table.thread td.guest em {
display: block;
font-weight: bold; font-style: normal;
margin-bottom: 8px;
}
table.thread td {
vertical-align: top;
}

View File

@ -21,7 +21,11 @@
{% for c in comments.items %}
<tr id="{{ c.id }}">
{% if c != t.thread.top_comment %}
<td class="member">{{ widget_member.profile(c.author ) }}</td>
{% if c.author.type == "member" %}
<td class="member">{{ widget_member.profile(c.author ) }}</td>
{% else %}
<td class="guest"><em>Invité</em>{{ c.author.name }}</td>
{% endif %}
<td>
<div>{% if c.date_created != c.date_modified %}
Posté le {{ c.date_created|date }} (Modifié le {{ c.date_modified|date }})
@ -44,15 +48,25 @@
{{ widget_pagination.paginate(comments, 'forum_topic', t, {'f': t.forum}) }}
{% if current_user.is_authenticated or V5Config.ENABLE_GUEST_POST %}
<div class=form>
<h3>Commenter le sujet</h3>
<form action="" method="post" enctype="multipart/form-data">
<form action="" method="post" enctype="multipart/form-data">
{{ form.hidden_tag() }}
{% if form.pseudo %}
{{ form.pseudo.label }}
{{ form.pseudo }}
{% for error in form.pseudo.errors %}
<span class="msgerror">{{ error }}</span>
{% endfor %}
{% endif %}
{{ widget_editor.text_editor(form.message, label=False) }}
<div>{{ form.submit(class_='bg-ok') }}</div>
</form>
{% endif %}
</div>
</section>
{% endblock %}

View File

@ -18,6 +18,7 @@ class Config(object):
class DefaultConfig(object):
"""Every value here can be overrided in the local_config.py class"""
# Length allocated to privilege names (slugs)
PRIVS_MAXLEN = 64
# Forbidden user names
@ -54,7 +55,9 @@ class DefaultConfig(object):
SECRET_KEY = "a-random-secret-key"
# Avatars folder
AVATARS_FOLDER = '/avatar/folder/'
# Enable guest post
ENABLE_GUEST_POST = True
class V5Config(LocalConfig, DefaultConfig):
# Args put here cannot be overidden with local_config
# Values put here cannot be overidden with local_config
pass

View File

@ -1,3 +1,6 @@
# This is a sample file
# You can override every value available in the class DefaultConfig
class LocalConfig(object):
DB_NAME = "pcv5"
USE_LDAP = True
@ -5,3 +8,4 @@ class LocalConfig(object):
LDAP_ORGANIZATION = "o=planet-casio"
SECRET_KEY = "a-random-secret-key" # CHANGE THIS VALUE *NOW*
AVATARS_FOLDER = '/home/pc/data/avatars/'
ENABLE_GUEST_POST = True

View File

@ -0,0 +1,42 @@
"""Modification du Guest
Revision ID: d1b465f88d3b
Revises: c40b1f0ed821
Create Date: 2020-07-17 22:56:36.260431
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = 'd1b465f88d3b'
down_revision = 'c40b1f0ed821'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('guest', sa.Column('name', sa.Unicode(length=64), nullable=True))
op.drop_index('ix_guest_username', table_name='guest')
op.drop_column('guest', 'ip')
op.drop_column('guest', 'username')
op.alter_column('member', 'avatar_id',
existing_type=sa.INTEGER(),
nullable=True,
existing_server_default=sa.text('0'))
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.alter_column('member', 'avatar_id',
existing_type=sa.INTEGER(),
nullable=False,
existing_server_default=sa.text('0'))
op.add_column('guest', sa.Column('username', sa.VARCHAR(length=64), autoincrement=False, nullable=True))
op.add_column('guest', sa.Column('ip', sa.VARCHAR(length=47), autoincrement=False, nullable=True))
op.create_index('ix_guest_username', 'guest', ['username'], unique=False)
op.drop_column('guest', 'name')
# ### end Alembic commands ###