1
1
Fork 0

Comments - rendering

Fixed Flask-Admin bp collisions
dev
Jan Kužílek 5 years ago
parent 8255913c58
commit 70dba62cae

@ -6,8 +6,8 @@ from flask_migrate import Migrate
from flask_login import LoginManager from flask_login import LoginManager
from flask_assets import Environment as AssetsEnvironment, Bundle as AssetsBundle from flask_assets import Environment as AssetsEnvironment, Bundle as AssetsBundle
# from flask_admin import Admin from flask_admin import Admin
# from flask_admin.contrib.sqla import ModelView from flask_admin.contrib.sqla import ModelView
db = SQLAlchemy() db = SQLAlchemy()
migrate = Migrate() migrate = Migrate()
@ -15,7 +15,7 @@ login = LoginManager()
assets = AssetsEnvironment() assets = AssetsEnvironment()
# THIS FUCKER DARES TO MESS WITH MY BLUEPRINTS (that blueprint collision shitxception) # THIS FUCKER DARES TO MESS WITH MY BLUEPRINTS (that blueprint collision shitxception)
# admin = Admin() admin = Admin()
def create_app(): def create_app():
@ -27,7 +27,7 @@ def create_app():
MAX_CONTENT_LENGTH=10*1024*1024, MAX_CONTENT_LENGTH=10*1024*1024,
POST_LIST_THUMB_HEIGHT=200, POST_LIST_THUMB_HEIGHT=200,
POST_UPLOADS=os.path.join(app.instance_path, 'post'), POST_UPLOADS=os.path.join(app.instance_path, 'post'),
INSTANCE_NAME='YADC', INSTANCE_NAME='YaDc',
POSTS_PER_PAGE=4, POSTS_PER_PAGE=4,
SQLALCHEMY_ECHO=True, SQLALCHEMY_ECHO=True,
@ -45,11 +45,11 @@ def create_app():
from yadc import models from yadc import models
# admin.init_app(app) admin.init_app(app)
# admin.add_view(ModelView(models.User, db.session)) admin.add_view(ModelView(models.User, db.session, endpoint='admin_user'))
# admin.add_view(ModelView(models.Post, db.session)) admin.add_view(ModelView(models.Post, db.session, endpoint='admin_post'))
# admin.add_view(ModelView(models.Tag, db.session)) admin.add_view(ModelView(models.Tag, db.session, endpoint='admin_tag'))
# admin.add_view(ModelView(models.Comment, db.session)) admin.add_view(ModelView(models.Comment, db.session, endpoint='admin_comment'))
from yadc.bp import main, post, auth from yadc.bp import main, post, auth
app.register_blueprint(main.bp) app.register_blueprint(main.bp)

@ -1,16 +1,8 @@
import io
import os import os
from flask import (Blueprint, abort, current_app, flash, redirect, from flask import (Blueprint, abort, current_app, flash, redirect,
render_template, request, send_from_directory, url_for) render_template, request, send_from_directory, url_for)
from flask_login import current_user, login_required
from PIL import Image
from sqlalchemy import func
from sqlalchemy.orm import aliased
from yadc import db
from yadc.forms import UploadPostForm
from yadc.models import FILETYPE, RATING, Post, Tag
bp = Blueprint('main', __name__) bp = Blueprint('main', __name__)

@ -9,8 +9,8 @@ from sqlalchemy import func
from sqlalchemy.orm import aliased from sqlalchemy.orm import aliased
from yadc import db from yadc import db
from yadc.forms import UploadPostForm from yadc.forms import UploadForm, CommentForm
from yadc.models import FILETYPE, RATING, Post, Tag from yadc.models import FILETYPE, RATING, Post, Tag, Comment
from yadc.utils import query_replace from yadc.utils import query_replace
bp = Blueprint('post', __name__) bp = Blueprint('post', __name__)
@ -77,12 +77,15 @@ def post_show(id):
tag.count = count tag.count = count
tag.endpoint = query_replace({'tags': tag.content.replace(' ','_')}, url_for('.posts')) tag.endpoint = query_replace({'tags': tag.content.replace(' ','_')}, url_for('.posts'))
return render_template('post.html', post=post, tags=post.tags) form = CommentForm()
form.post_id.data = post.id
return render_template('post.html', post=post, tags=post.tags, comments=post.comments, comment_form=form)
@bp.route('/upload', methods=['GET', 'POST']) @bp.route('/upload', methods=['GET', 'POST'])
@login_required @login_required
def post_upload(): def upload():
form = UploadPostForm(request.form) form = UploadForm(request.form)
if request.method == 'POST' and form.validate(): if request.method == 'POST' and form.validate():
file = request.files.get(form.post_img.name) file = request.files.get(form.post_img.name)
file.data = io.BytesIO(file.read()) file.data = io.BytesIO(file.read())
@ -112,6 +115,22 @@ def post_upload():
flash('Successfully submitted {}'.format(str(post))) flash('Successfully submitted {}'.format(str(post)))
return redirect(url_for('.post_upload')) return redirect(url_for('.upload'))
return render_template('upload.html', form=form) return render_template('upload.html', form=form)
@bp.route('comment', methods=['POST'])
@login_required
def comment():
form = CommentForm(request.form)
if request.method == 'POST' and form.validate():
comment = Comment(content=form.content.data, post_id=form.post_id.data, user=current_user)
db.session.add(comment)
db.session.commit()
flash('Successfully submitted {}'.format(str(comment)))
return redirect(url_for('.post_show', id=form.post_id.data))
return redirect(url_for('.posts'))

@ -1,5 +1,5 @@
from wtforms import Form from wtforms import Form
from wtforms import StringField, PasswordField, BooleanField, SubmitField, FileField, MultipleFileField, ValidationError, RadioField from wtforms import StringField, PasswordField, BooleanField, SubmitField, FileField, MultipleFileField, ValidationError, RadioField, TextAreaField, HiddenField
from wtforms.validators import DataRequired, InputRequired, Email, EqualTo, AnyOf from wtforms.validators import DataRequired, InputRequired, Email, EqualTo, AnyOf
from werkzeug.utils import cached_property from werkzeug.utils import cached_property
@ -61,7 +61,7 @@ def validate_file(form, field):
if not file or file.filename == '': if not file or file.filename == '':
raise ValidationError('Please select a file') raise ValidationError('Please select a file')
class UploadPostForm(CSRFForm): class UploadForm(CSRFForm):
post_img = FileField('Image', validators=[validate_file], render_kw={'required':''}) post_img = FileField('Image', validators=[validate_file], render_kw={'required':''})
sauce = StringField('Sauce', validators=[DataRequired()]) sauce = StringField('Sauce', validators=[DataRequired()])
tags = StringField('Tags') tags = StringField('Tags')
@ -80,5 +80,7 @@ class UploadPostForm(CSRFForm):
if client_mimetype not in ['image/png','image/jpeg']: if client_mimetype not in ['image/png','image/jpeg']:
raise ValidationError('Please select an image file of PNG or JPEG format') raise ValidationError('Please select an image file of PNG or JPEG format')
class CommentForm(CSRFForm):
# class CommentForm(CSRFForm): post_id = HiddenField(validators=[DataRequired()])
content = TextAreaField('Comment', validators=[DataRequired()])
submit = SubmitField('Send')

@ -44,6 +44,10 @@ class TAG_CATEGORY(enum.Enum):
character = 4 character = 4
copyright = 5 copyright = 5
# class COMMENT_STATUS(enum.Enum):
# visible = 0
# deleted = 2
class TimestampMixin(object): class TimestampMixin(object):
created = db.Column(UtcDateTime, nullable=False, default=utcnow()) created = db.Column(UtcDateTime, nullable=False, default=utcnow())
updated = db.Column(UtcDateTime, nullable=False, onupdate=utcnow(), default=utcnow()) updated = db.Column(UtcDateTime, nullable=False, onupdate=utcnow(), default=utcnow())
@ -78,7 +82,8 @@ class User(UserMixin, TimestampMixin, db.Model):
@property @property
def is_moderator(self): def is_moderator(self):
return self.op_level in [OP_LEVEL.moderator, OP_LEVEL.admin] # return self.op_level in [OP_LEVEL.moderator, OP_LEVEL.admin]
return self.op_level.value >= OP_LEVEL.moderator.value
@property @property
def is_admin(self): def is_admin(self):
@ -192,7 +197,11 @@ class Tag(TimestampMixin, db.Model):
class Comment(TimestampMixin, db.Model): class Comment(TimestampMixin, db.Model):
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)
content = db.Column(db.String(512)) content = db.Column(db.String(512), nullable=False)
# status = db.Column(db.Enum(COMMENT_STATUS), default=COMMENT_STATUS.visible)
deleted = db.Column(db.Boolean, default=False)
delete_reason = db.Column(db.String(512))
post_id = db.Column(db.Integer, db.ForeignKey('post.id')) post_id = db.Column(db.Integer, db.ForeignKey('post.id'))
post = db.relationship('Post', backref=db.backref('comments', lazy=True)) post = db.relationship('Post', backref=db.backref('comments', lazy=True))

@ -397,17 +397,35 @@ header {
section.comments { section.comments {
padding: 10px; padding: 10px;
@include media($bp-desktop) { @include media($bp-desktop) {
margin-left: $side-panel-width; margin-left: $side-panel-width;
} }
article { overflow: hidden; } > .comment_container {
h4 { margin-left: 10px;
margin-top: .5em;
margin-bottom: .5em; article { overflow: hidden; }
h4 {
// margin-top: .5em;
margin: 0;
margin-bottom: .5em;
}
p {
margin-top: .5em;
&.deleted {
color: red;
}
}
} }
p {
margin-top: .5em; > .form > form {
margin-left: 10px;
input:required {
box-shadow: none;
}
} }
} }
} }

@ -42,4 +42,22 @@
<h3>Rating</h3> <h3>Rating</h3>
<input type="checkbox" name="" id=""> <input type="checkbox" name="" id="">
</article> </article>
{% endmacro %} --> {% endmacro %} -->
{% macro render_comments() %}
<div class="comment_container">
{% for comment in comments %}
<article>
<h4>{{ comment.user.username }}</h4>
{% if not comment.deleted %}
<p>{{ comment.content }}</p>
{% else %}
<p class="deleted">{{ comment.delete_reason }}</p>
{% endif %}
</article>
{% endfor %}
{% if not comments %}
<p>No comments so far.</p>
{% endif %}
</div>
{% endmacro %}

@ -14,11 +14,11 @@
<body> <body>
<header> <header>
<a href="{{ url_for('main.index') }}" class="logo"> <a href="{{ url_for('main.index') }}" class="logo">
<span>YaDc</span> <span>{{ config.get('INSTANCE_NAME') }}</span>
</a> </a>
<nav id="main-nav"> <nav id="main-nav">
<a href="{{ url_for('post.posts') }}">Posts</a> <a href="{{ url_for('post.posts') }}">Posts</a>
<a href="{{ url_for('post.post_upload') }}">Upload</a> <a href="{{ url_for('post.upload') }}">Upload</a>
<div class="user"> <div class="user">
{% if current_user.is_anonymous %} {% if current_user.is_anonymous %}

@ -1,5 +1,6 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% from '_includes.html' import render_tags with context %} {% from '_includes.html' import render_tags, render_comments with context %}
{% from "_formhelpers.html" import errors %}
{% block content %} {% block content %}
<div class="important_subwrap"> <div class="important_subwrap">
@ -34,11 +35,24 @@
</section> </section>
</div> </div>
<section class="comments"> <section class="comments">
{% for comment in comments %} <h3>Comments</h3>
<article> {{ render_comments() }}
<h4>{{ comment.user.username }}</h4>
<p>{{ comment.content }}</p> {% if current_user.is_authenticated %}
</article> <div class="form">
{% endfor %} <h3>Reply</h3>
<form action="{{ url_for('post.comment') }}" method="post">
{{ comment_form.csrf_token }}
{{ comment_form.post_id() }}
<div>
{{ comment_form.content(cols=55, rows=6) }}
{{ errors(comment_form.content) }}
</div>
<div>{{ comment_form.submit() }}</div>
</form>
</div>
{% else %}
<h4>To comment, please log in.</h3>
{% endif %}
</section> </section>
{% endblock content %} {% endblock content %}
Loading…
Cancel
Save