basic admin interface done
This commit is contained in:
@@ -2,14 +2,15 @@ import os
|
||||
|
||||
from flask import (
|
||||
Blueprint, render_template,
|
||||
flash, request, url_for, redirect, abort, g, send_from_directory, current_app)
|
||||
flash, request, url_for, redirect, abort, send_from_directory, current_app)
|
||||
from werkzeug.utils import secure_filename
|
||||
|
||||
from calender.auth import login_required
|
||||
from calender.db import get_db
|
||||
|
||||
bp = Blueprint('calender', __name__)
|
||||
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'}
|
||||
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif', 'webm', 'mp4', 'bmp'}
|
||||
|
||||
|
||||
# Todo admin interface for managing submit, comments, submission date
|
||||
|
||||
@@ -17,16 +18,29 @@ ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'}
|
||||
def index():
|
||||
db = get_db()
|
||||
posts = db.execute(
|
||||
'SELECT p.id, title, body, created, author_id, username, nickname, file'
|
||||
' FROM post p JOIN user u ON p.author_id = u.id'
|
||||
'SELECT p.id, title, body, created, nickname, file, chosen, type'
|
||||
' FROM post p'
|
||||
' ORDER BY created DESC'
|
||||
).fetchall()
|
||||
# noinspection PyUnresolvedReferences
|
||||
return render_template('calender/index.html', posts=posts)
|
||||
|
||||
|
||||
@bp.route('/create', methods=('GET', 'POST'))
|
||||
@bp.route('/admin')
|
||||
@login_required
|
||||
def admin():
|
||||
db = get_db()
|
||||
posts = db.execute(
|
||||
'SELECT p.id, title, body, created, nickname, file, chosen, type'
|
||||
' FROM post p'
|
||||
' ORDER BY created DESC'
|
||||
).fetchall()
|
||||
# noinspection PyUnresolvedReferences
|
||||
return render_template('calender/admin.html', posts=posts)
|
||||
|
||||
|
||||
@bp.route('/create', methods=('GET', 'POST'))
|
||||
# @login_required
|
||||
def create():
|
||||
if request.method == 'POST':
|
||||
title = request.form['title']
|
||||
@@ -52,14 +66,16 @@ def create():
|
||||
flash(error)
|
||||
else:
|
||||
if file and allowed_file(file.filename):
|
||||
file_type = check_file_type(file.filename)
|
||||
filename = secure_filename(file.filename)
|
||||
file.save(os.path.join(current_app.config['UPLOAD_FOLDER'], filename))
|
||||
|
||||
db = get_db()
|
||||
db.execute(
|
||||
'INSERT INTO post (title, body, author_id, nickname, file)'
|
||||
' VALUES (?, ?, ?, ?, ?)',
|
||||
(title, body, g.user['id'], nickname, url_for('calender.uploaded_file',
|
||||
filename=filename))
|
||||
'INSERT INTO post (title, body, nickname, file, chosen, type)'
|
||||
' VALUES (?, ?, ?, ?, ?, ?)',
|
||||
(title, body, nickname, url_for('calender.uploaded_file',
|
||||
filename=filename), False, file_type)
|
||||
)
|
||||
db.commit()
|
||||
# return redirect(url_for('calender.uploaded_file',filename=filename))
|
||||
@@ -70,8 +86,8 @@ def create():
|
||||
|
||||
def get_post(id, check_author=True):
|
||||
post = get_db().execute(
|
||||
'SELECT p.id, title, body, created, author_id, username, nickname, file'
|
||||
' FROM post p JOIN user u ON p.author_id = u.id'
|
||||
'SELECT p.id, title, body, created, nickname, file, chosen, type'
|
||||
' FROM post p'
|
||||
' WHERE p.id = ?',
|
||||
(id,)
|
||||
).fetchone()
|
||||
@@ -79,8 +95,8 @@ def get_post(id, check_author=True):
|
||||
if post is None:
|
||||
abort(404, "Post id {0} doesn't exist.".format(id))
|
||||
|
||||
if check_author and post['author_id'] != g.user['id']:
|
||||
abort(403)
|
||||
# if check_author and post['author_id'] != g.user['id']:
|
||||
# abort(403)
|
||||
|
||||
return post
|
||||
|
||||
@@ -92,7 +108,9 @@ def update(id):
|
||||
|
||||
if request.method == 'POST':
|
||||
title = request.form['title']
|
||||
nickname = request.form['nickname']
|
||||
body = request.form['body']
|
||||
chosen = request.form['chosen']
|
||||
error = None
|
||||
|
||||
if not title:
|
||||
@@ -103,9 +121,9 @@ def update(id):
|
||||
else:
|
||||
db = get_db()
|
||||
db.execute(
|
||||
'UPDATE post SET title = ?, body = ?'
|
||||
'UPDATE post SET title = ?, body = ?, nickname = ?, chosen = ?'
|
||||
' WHERE id = ?',
|
||||
(title, body, id)
|
||||
(title, body, nickname, chosen, id)
|
||||
)
|
||||
db.commit()
|
||||
return redirect(url_for('calender.index'))
|
||||
@@ -128,6 +146,13 @@ def allowed_file(filename):
|
||||
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
|
||||
|
||||
|
||||
def check_file_type(filename):
|
||||
if filename.rsplit('.', 1)[1].lower() in ['webm', 'mp4']:
|
||||
return 'video'
|
||||
else:
|
||||
return 'image'
|
||||
|
||||
|
||||
@bp.route('/uploads/<filename>')
|
||||
def uploaded_file(filename):
|
||||
return send_from_directory(current_app.config['UPLOAD_FOLDER'],
|
||||
|
||||
@@ -9,11 +9,11 @@ CREATE TABLE user (
|
||||
|
||||
CREATE TABLE post (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
author_id INTEGER NOT NULL,
|
||||
created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
title TEXT NOT NULL,
|
||||
nickname TEXT NOT NULL,
|
||||
body TEXT NOT NULL,
|
||||
file TEXT NOT NULL,
|
||||
FOREIGN KEY (author_id) REFERENCES user (id)
|
||||
chosen INTEGER NOT NULL ,
|
||||
type TEXT NOT NULL
|
||||
);
|
||||
|
||||
@@ -8,11 +8,11 @@
|
||||
<div>
|
||||
<h6>Submit your meme for the next day now! Feel free to create and submit your own creations. </h6>
|
||||
<br>
|
||||
{% if g.user %}
|
||||
|
||||
<a class="action" href="{{ url_for('calender.create') }}">
|
||||
<button>Submit a Meme</button>
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -20,6 +20,7 @@
|
||||
{% block content %}
|
||||
<div class="container w3-center">
|
||||
{% for post in posts %}
|
||||
{% if post['chosen'] == 1 %}
|
||||
<div class="item">
|
||||
<article class="post">
|
||||
<header>
|
||||
@@ -29,17 +30,22 @@
|
||||
<div class="about">by {{ post['username'] }}
|
||||
on {{ post['created'].strftime('%Y-%m-%d') }}</div>
|
||||
</div>
|
||||
{% if g.user['id'] == post['author_id'] %}
|
||||
<a class="action" href="{{ url_for('calender.update', id=post['id']) }}">Edit</a>
|
||||
{% endif %}
|
||||
</header>
|
||||
{% if post['type'] == 'image' %}
|
||||
<img class="file" src="{{ post['file'] }}">
|
||||
{% endif %}
|
||||
{% if post['type'] == 'video' %}
|
||||
<video class="file" preload="none" controls="" width="500">
|
||||
<source src="{{ post['file'] }}">
|
||||
</video>
|
||||
{% endif %}
|
||||
<p class="body">{{ post['body'] }}</p>
|
||||
</article>
|
||||
{% if not loop.last %}
|
||||
<hr>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
@@ -4,12 +4,30 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<form method="post">
|
||||
<form method=post enctype=multipart/form-data>
|
||||
<label for="title">Title</label>
|
||||
<input name="title" id="title"
|
||||
value="{{ request.form['title'] or post['title'] }}" required>
|
||||
<label for="nickname">Nickname</label>
|
||||
<input name="nickname" id="nickname" value="{{ request.form['nickname'] or post['nickname'] }}" required>
|
||||
<label for="body">Body</label>
|
||||
<textarea name="body" id="body">{{ request.form['body'] or post['body'] }}</textarea>
|
||||
<label for="file">Body</label>
|
||||
{% if post['type'] == 'image' %}
|
||||
<img class="file" src="{{ post['file'] }}">
|
||||
{% endif %}
|
||||
{% if post['type'] == 'video' %}
|
||||
<video class="file" preload="none" controls="" width="500">
|
||||
<source src="{{ post['file'] }}">
|
||||
</video>
|
||||
{% endif %}
|
||||
<div>
|
||||
<p>Choose a mp4, webm, gif , png or jpg file.(max 25MB)</p>
|
||||
<input type="file" placeholder="meme" name="file" id="file"
|
||||
value="{{ request.form['file'] or post['file'] }}">
|
||||
</div>
|
||||
<label for="chosen">Chosen</label><br>
|
||||
<input id="chosen" name="chosen" value="{{ request.form['chosen'] or post['chosen'] }}">
|
||||
<input type="submit" value="Save">
|
||||
</form>
|
||||
<hr>
|
||||
|
||||
Reference in New Issue
Block a user