news: add summary and thumbnails to topics
Provides data for homepage, as well as others topics
This commit is contained in:
parent
c68b9b2048
commit
af61b21fc8
|
@ -1,6 +1,6 @@
|
|||
from flask_wtf import FlaskForm
|
||||
from wtforms import StringField, SubmitField, TextAreaField, MultipleFileField, SelectField
|
||||
from wtforms.validators import InputRequired, Length
|
||||
from wtforms import StringField, SubmitField, TextAreaField, MultipleFileField, SelectField, DecimalField
|
||||
from wtforms.validators import InputRequired, Length, Optional
|
||||
import app.utils.validators as vd
|
||||
from app.utils.antibot_field import AntibotField
|
||||
|
||||
|
@ -54,6 +54,14 @@ class TopicCreationForm(CommentForm):
|
|||
'Nom du sujet',
|
||||
validators=[InputRequired(), Length(min=3, max=128)])
|
||||
|
||||
summary = TextAreaField(
|
||||
'Résumé',
|
||||
validators=[Optional(), Length(min=3, max=128)])
|
||||
|
||||
thumbnail = DecimalField(
|
||||
'N° de l’illustration',
|
||||
validators=[Optional(), vd.attachment_exists])
|
||||
|
||||
submit = SubmitField('Créer le sujet')
|
||||
|
||||
|
||||
|
@ -61,11 +69,7 @@ class AnonymousTopicCreationForm(TopicCreationForm, AnonymousCommentForm):
|
|||
ab = AntibotField()
|
||||
|
||||
|
||||
class TopicEditForm(CommentEditForm):
|
||||
title = StringField(
|
||||
'Nom du sujet',
|
||||
validators=[InputRequired(), Length(min=3, max=128)])
|
||||
|
||||
class TopicEditForm(TopicCreationForm):
|
||||
# List of forums is generated at runtime
|
||||
forum = SelectField(
|
||||
'Forum',
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
from app import db
|
||||
from app.models.post import Post
|
||||
from sqlalchemy.orm import backref
|
||||
from sqlalchemy.dialects.postgresql import UUID
|
||||
|
||||
class Topic(Post):
|
||||
__tablename__ = 'topic'
|
||||
|
@ -29,10 +30,17 @@ class Topic(Post):
|
|||
backref=backref('topics', lazy='dynamic'), foreign_keys=forum_id)
|
||||
|
||||
# Associated thread
|
||||
thread_id = db.Column(db.Integer,db.ForeignKey('thread.id'),nullable=False)
|
||||
thread_id = db.Column(db.Integer, db.ForeignKey('thread.id'), nullable=False)
|
||||
thread = db.relationship('Thread', foreign_keys=thread_id,
|
||||
back_populates='owner_topic')
|
||||
|
||||
# Summary
|
||||
summary = db.Column(db.UnicodeText)
|
||||
|
||||
# ID of thumbnail
|
||||
thumbnail_id = db.Column(UUID(as_uuid=True), db.ForeignKey('attachment.id'), nullable=True)
|
||||
thumbnail = db.relationship('Attachment', foreign_keys=thumbnail_id, lazy='joined')
|
||||
|
||||
# Number of views in the forum
|
||||
views = db.Column(db.Integer)
|
||||
|
||||
|
|
|
@ -54,6 +54,7 @@ def forum_page(f, page=1):
|
|||
db.session.merge(th)
|
||||
|
||||
t = Topic(f, author, form.title.data, th)
|
||||
t.summary = form.summary.data
|
||||
db.session.add(t)
|
||||
db.session.commit()
|
||||
|
||||
|
@ -68,6 +69,10 @@ def forum_page(f, page=1):
|
|||
for a, file in attachments:
|
||||
a.set_file(file)
|
||||
|
||||
# If there's a thumbnail, set it
|
||||
if form.thumbnail.data:
|
||||
t.thumbnail = c.attachments[int(form.thumbnail.data)-1]
|
||||
|
||||
# Update member's xp and trophies
|
||||
if current_user.is_authenticated:
|
||||
current_user.add_xp(2) # 2 points for a topic
|
||||
|
|
|
@ -74,6 +74,12 @@ def edit_post(postid):
|
|||
|
||||
if isinstance(p, Topic):
|
||||
p.title = form.title.data
|
||||
p.summary = form.summary.data
|
||||
# If there's a thumbnail, set it
|
||||
if form.thumbnail.data:
|
||||
p.thumbnail = comment.attachments[int(form.thumbnail.data)-1]
|
||||
else:
|
||||
p.thumbnail = None
|
||||
f = Forum.query.filter_by(url=form.forum.data).first_or_404()
|
||||
if current_user.can_post_in_forum(f):
|
||||
p.forum = f
|
||||
|
@ -102,6 +108,7 @@ def edit_post(postid):
|
|||
form.message.data = p.thread.top_comment.text
|
||||
form.title.data = p.title
|
||||
form.forum.data = p.forum.url
|
||||
form.summary.data = p.summary
|
||||
return render('forum/edit_topic.html', t=p, form=form)
|
||||
|
||||
@app.route('/post/supprimer/<int:postid>', methods=['GET','POST'])
|
||||
|
|
|
@ -48,6 +48,22 @@
|
|||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
{{ form.summary.label }}
|
||||
{{ form.summary }}
|
||||
{% for error in form.summary.errors %}
|
||||
<span class="msgerror">{{ error }}</span>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
{{ form.thumbnail.label }}
|
||||
{{ form.thumbnail }}
|
||||
{% for error in form.thumbnail.errors %}
|
||||
<span class="msgerror">{{ error }}</span>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
{% if form.pseudo %}
|
||||
<div>
|
||||
{{ form.pseudo.label }}
|
||||
|
|
|
@ -75,6 +75,22 @@
|
|||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
{{ form.summary.label }}
|
||||
{{ form.summary }}
|
||||
{% for error in form.summary.errors %}
|
||||
<span class="msgerror">{{ error }}</span>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
{{ form.thumbnail.label }}
|
||||
{{ form.thumbnail }}
|
||||
{% for error in form.thumbnail.errors %}
|
||||
<span class="msgerror">{{ error }}</span>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
{{ widget_editor.text_editor(form.message) }}
|
||||
|
||||
<div>
|
||||
|
|
|
@ -15,6 +15,10 @@
|
|||
<section>
|
||||
<h1>{{ t.title }}</h1>
|
||||
|
||||
{% if t.summary %}
|
||||
<div>{{ t.summary | md }}</div>
|
||||
{% endif %}
|
||||
|
||||
{% if t.thread.top_comment %}
|
||||
{% call widget_thread.thread_leader(t.thread.top_comment) %}
|
||||
<div class="info">
|
||||
|
|
|
@ -46,63 +46,18 @@
|
|||
<div class="home-news">
|
||||
<h1>Actualitées</h1>
|
||||
<ul>
|
||||
{% for n in last_news %}
|
||||
<li>
|
||||
<a href="#"><img src="https://www.planet-casio.com/images/staff/tdm9_collision2.jpg"/></a>
|
||||
<a href="{{ url_for('forum_topic', f=n.forum, page=(n,'fin'))}}"><img src="{{ n.thumbnail.url }}"/></a>
|
||||
<div>
|
||||
<h3><a href="#">Les collisions — partie 2</a></h3>
|
||||
<p class="date"><i>Publié par <a href="#">Shadow15510</a> le <time>09/06/2023 09:10</time></i></p>
|
||||
La deuxième partie du tutoriel du mercredi sur les collisions est maintenant disponible en vidéo.
|
||||
<h3><a href="{{ url_for('forum_topic', f=n.forum, page=(n,'fin'))}}">{{ n.title }}</a></h3>
|
||||
<p class="date"><i>Publié par <a href="{{ url_for('user_by_id', user_id=n.author.id) }}">{{ n.author.name }}</a>
|
||||
le <time>{{ n.date_created | dyndate }}</time></i></p>
|
||||
{{ (n.summary or "") | md }}
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#"><img src="https://www.planet-casio.com/images/staff/CPC30-image-thumb-results.png"/></a>
|
||||
<div>
|
||||
<h3><a href="#">Résultats du CPC #30 — Les profondeurs !</a>
|
||||
</h3>
|
||||
<p class="date"><i>Publié par <a href="#">Lephenixnoir</a> le <time>08/06/2023 22:10</time></i></p>
|
||||
Les programmes sont profonds et avec un peu de chance les tests aussi ! </div>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#"><img src="https://www.planet-casio.com/images/staff/tituya-thumb.png"/></a>
|
||||
<div>
|
||||
<h3><a href="#">Un second renardministrateur !</a>
|
||||
</h3>
|
||||
<p class="date"><i>Publié par <a href="#">Lephenixnoir</a> le <time>07/06/2023 22:55</time></i></p>
|
||||
Vive la renardocratie ! </div>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#"><img src="https://www.planet-casio.com/images/staff/massy2.jpg"/></a>
|
||||
<div>
|
||||
<h3><a href="#">Visite chez Casio France à Massy, musée inclus</a>
|
||||
</h3>
|
||||
<p class="date"><i>Publié par <a href="#">Critor</a> le <time>05/06/2023 11:51</time></i></p>
|
||||
Compte-rendu de notre visite au sein même des locaux de Casio France à Massy en mai 2023, passage par leur musée privé inclus. </div>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#"><img src="https://www.planet-casio.com/images/staff/CPC30-image-title.jpg"/></a>
|
||||
<div>
|
||||
<h3><a href="#">Le CPC#30 - Les Profondeurs ... C'est désormais terminé ... Bravo à tous les participants.</a>
|
||||
</h3>
|
||||
<p class="date"><i>Publié par <a href="#">Slyvtt</a> le <time>03/06/2023 21:36</time></i></p>
|
||||
Aujourd'hui sonne la fin du CPC#30 avec à la clef 6 participations pour vous donner du fun. Graphs Monochromes et Couleurs sont à la fête avec des programmes en Basic et des Addins. </div>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#"><img src="https://www.planet-casio.com/images/staff/tdm9_miniature.jpg"/></a>
|
||||
<div>
|
||||
<h3><a href="#">Les Tutos du Mercredi débarquent sur Youtube !</a>
|
||||
</h3>
|
||||
<p class="date"><i>Publié par <a href="#">Shadow15510</a> le <time>29/05/2023 14:15</time></i></p>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#"><img src="https://www.planet-casio.com/images/staff/CPC30-image-thumb.jpg"/></a>
|
||||
<div>
|
||||
<h3><a href="#">Le CPC #30 - Les profondeurs !</a>
|
||||
</h3>
|
||||
<p class="date"><i>Publié par <a href="#">Lephenixnoir</a> le <time>27/05/2023 18:00</time></i></p>
|
||||
Le concours CPC revient en force et c'est le moment de se plonger (métaphoriquement <i>et</i> littéralement !) dans le game design fin et la programmation sportive. Une semaine pour les programmer tous, et dans les profondeurs les li— oups ! </div>
|
||||
</li>
|
||||
<li><p><i><a href="https://www.planet-casio.com/Fr/forums/partie6-.html">Voir toutes les news</a></i></p></li>
|
||||
{% endfor %}
|
||||
<li><p><i><a href="/forum/actus/">Voir toutes les news</a></i></p></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="home-shoutbox" style="border: 1px solid #737373; padding: 20px">
|
||||
|
|
|
@ -56,3 +56,13 @@ def own_title(form, title):
|
|||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def attachment_exists(form, number):
|
||||
try:
|
||||
n = int(number.data)
|
||||
if n <= 0 or n > len(form.attachments.data):
|
||||
raise Exception()
|
||||
except Exception as e:
|
||||
raise ValidationError('L’illustration doit être le numéro d’une pièce-jointe')
|
||||
|
||||
return True
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
"""Topics: add summary and thumbnail
|
||||
|
||||
Revision ID: a8f539a93bd5
|
||||
Revises: 5ffc4e562ed8
|
||||
Create Date: 2023-07-25 21:44:55.782425
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy.dialects import postgresql
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = 'a8f539a93bd5'
|
||||
down_revision = '5ffc4e562ed8'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
with op.batch_alter_table('topic', schema=None) as batch_op:
|
||||
batch_op.add_column(sa.Column('summary', sa.UnicodeText(), nullable=True))
|
||||
batch_op.add_column(sa.Column('thumbnail_id', postgresql.UUID(as_uuid=True), nullable=True))
|
||||
batch_op.create_foreign_key(None, 'attachment', ['thumbnail_id'], ['id'])
|
||||
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
with op.batch_alter_table('topic', schema=None) as batch_op:
|
||||
batch_op.drop_constraint(None, type_='foreignkey')
|
||||
batch_op.drop_column('thumbnail_id')
|
||||
batch_op.drop_column('summary')
|
||||
|
||||
# ### end Alembic commands ###
|
Loading…
Reference in New Issue