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