Browse Source

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
pull/52/head
Darks 1 year ago
parent
commit
e6c1545031
Signed by: Darks GPG Key ID: F61F10FA138E797C
  1. 10
      app/forms/forum.py
  2. 13
      app/models/users.py
  3. 2
      app/processors/utilities.py
  4. 24
      app/routes/forum/topic.py
  5. 2
      app/static/css/global.css
  6. 9
      app/static/css/table.css
  7. 18
      app/templates/forum/topic.html
  8. 5
      config.py
  9. 4
      local_config.py.default
  10. 42
      migrations/versions/d1b465f88d3b_modification_du_guest.py

10
app/forms/forum.py

@ -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])

13
app/models/users.py

@ -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):

2
app/processors/utilities.py

@ -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,
)

24
app/routes/forum/topic.py

@ -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

2
app/static/css/global.css

@ -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 */

9
app/static/css/table.css

@ -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;
}

18
app/templates/forum/topic.html

@ -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 %}

5
config.py

@ -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

4
local_config.py.default

@ -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

42
migrations/versions/d1b465f88d3b_modification_du_guest.py

@ -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 ###
Loading…
Cancel
Save