Commit 2c60a20c authored by Mathis Dedial's avatar Mathis Dedial
Browse files

Integrate vote view into template

Split up 'vote' endpoint into 'vote' and 'list'
for easier LDAP integration later on
parent 1e36663e
......@@ -7,7 +7,7 @@
Create your a burger for the 125th anniversary of the AMIV!
</p>
<form method="post">
<form method="POST">
<div id="creator">
<!-- Info Section -->
<section class="bg-primary text-white text-center" id="info">
......
{% extends 'base.html' %} {% block content %}
<div class="list-group">
{% for burger in burger_list %}
<li class="list-group-item d-flex align-items-center justify-content-between">
<div>
<b>{{ burger.name }}</b>
<br>
<span>{{ burger.description }}</span>
<p class="lead">
Create your a burger for the 125th anniversary of the AMIV!
</p>
<section class="bg-primary text-white text-center" id="info">
<div class="container">
<h2 class="text-center text-uppercase text-white">Create a Burger</h2>
<hr class="star-light">
<div class="text-center">
<h5>You can create your own AMIV anniversary burger below. Everyone can vote on the submitted burgers to decide which
one is the best. The most popular burger will be available at the canteen Polyterasse on .....</h5>
</span>
</div>
<div>
<ul>
<li>
<b>Bread:</b> {{ bread.get(burger.bread) }}</li>
<li>
<b>Patty:</b> {{ patty.get(burger.patty) }}</li>
<li>
<b>Toppings:</b>
<ul>
{% for topping in burger.toppings.split(', ') %}
<li>{{ toppings.get(topping|int) }}</li>
{% endfor %}
</ul>
</li>
<li>
<b>Side:</b> {{ side.get(burger.side) }}</li>
</ul>
</div>
</section>
<section class="masthead text-center">
<div class="container">
<h3>Burger Gallery</h3>
<hr class="star-dark">
<p class="highlight"></p>
<div class="list-group">
{% for burger in burger_list %}
<li class="list-group-item d-flex align-items-center justify-content-between">
<!-- Ranking -->
<h3 class="text-secondary">
{{ loop.index }}.
</h3>
<div class="d-flex align-items-center justify-content-between">
<!-- Name & Ingredients -->
<div class="text-left w-50">
<h4 class="text-primary">{{ burger.name }}</h4>
<p class="mb-0">
{{ patty.get(burger.patty) }}
in a {{ bread.get(burger.bread) }}
with
{% for topping in burger.toppings.split(', ') %}
{{ toppings.get(topping|int) }}{{ ', ' if not loop.last }}
{% endfor %}
and a side of {{ side.get(burger.side) }}.
</p>
</div>
<!-- Description and username -->
<blockquote class="blockquote text-center mb-0 w-50">
<p class="mb-0">
{{ burger.description }}
</p>
<footer class="blockquote-footer">{{ burger.nethz }}</footer>
</blockquote>
</div>
<!-- Voting -->
<div>
<h4 class="text-secondary mb-3">{{ burger.vote_count }} Votes</h4>
<form action="/vote" method="POST">
{% if not burger.vote_id %}
<button class="btn btn-primary" type="submit">
<img src="static/images/like.png" alt="Like"> Like
</button>
<input type="hidden" name="action" value="like"> {% else %}
<button class="btn btn-muted" type="submit">Unlike</button>
<input type="hidden" name="action" value="unlike"> {% endif %}
<input type="hidden" name="burger_id" value="{{ burger.id }}">
</form>
</div>
</li>
{% endfor %}
</div>
<span class="badge badge-success badge-pill">{{ burger.vote_count }}</span>
<form method="POST">
{% if not burger.vote_id %}
<button class="btn btn-success" type="submit">Like</button>
<input type="hidden" name="action" value="like">
{% else %}
<button class="btn btn-danger" type="submit">Unlike</button>
<input type="hidden" name="action" value="unlike">
{% endif %}
<input type="hidden" name="burger_id" value="{{ burger.id }}">
</form>
</li>
{% endfor %}
</div>
{% endblock content %}
</div>
</section>
{% endblock content %}
\ No newline at end of file
......@@ -8,76 +8,74 @@ from sqlalchemy.sql import text
from .mappings import BREAD, PATTY, TOPPINGS, SIDE
from .models import db, Burger, Vote
@app.route('/', methods=['GET', 'POST'])
def vote():
@app.route('/')
def list():
'''
Front page. Shows a list of all burgers
'''
def render_list():
'''
Helper function which gets the latest state from the database before rendering the template.
Useful since we don't want to send multiple queries for a single request.
'''
# Fetch list of burgers with corresponding vote info
# Could probably also be done with SQLAlchemy but too lazy to look up how
querystring = text('SELECT burger.id AS id, name, description, burger.nethz AS nethz, timestamp, bread, patty, toppings, side, COUNT(vote_1.id) AS vote_count, vote_2.id AS vote_id '
'FROM burger '
'LEFT JOIN vote AS vote_1 ON vote_1.burger_id=burger.id '
'LEFT JOIN vote AS vote_2 ON vote_2.burger_id=burger.id AND vote_2.nethz = :nethz '
'ORDER BY vote_count ')
burger_list = db.engine.execute(querystring, nethz=g.user).fetchall()
return render_template('vote.html',
burger_list=burger_list,
bread=BREAD,
patty=PATTY,
toppings=TOPPINGS,
side=SIDE)
# Fetch list of burgers with corresponding vote info
# Could probably also be done with SQLAlchemy but too lazy to look up how
# TODO: Query has a bug. Only burgers created by the user himself are returned.
querystring = text('SELECT burger.id AS id, name, description, burger.nethz AS nethz, timestamp, bread, patty, toppings, side, COUNT(vote_1.id) AS vote_count, vote_2.id AS vote_id '
'FROM burger '
'LEFT JOIN vote AS vote_1 ON vote_1.burger_id=burger.id '
'LEFT JOIN vote AS vote_2 ON vote_2.burger_id=burger.id AND vote_2.nethz = :nethz '
'ORDER BY vote_count ')
burger_list = db.engine.execute(querystring, nethz=g.user).fetchall()
return render_template('vote.html',
burger_list=burger_list,
bread=BREAD,
patty=PATTY,
toppings=TOPPINGS,
side=SIDE)
@app.route('/vote', methods=['POST'])
def vote():
'''
Handles POST requests for voting
'''
def die(message):
'''
Display an error-level flash message and return
'''
flash(message, 'error')
return render_list()
# Handle like / unlike actions first
if request.method == 'POST':
return redirect(url_for('list'))
# Check if the burger_id is valid
burger_id = request.form.get('burger_id')
if not burger_id or not Burger.query.get(burger_id):
return die('Invalid burger ID')
# User is casting their vote
if request.form.get('action') == 'like':
# Check if the user hasn't already voted for the same burger
if Vote.query.filter_by(nethz=g.user, burger_id=burger_id).first():
return die('You have already liked this burger.')
# Add vote
vote = Vote(
nethz=g.user,
burger_id=burger_id,
)
db.session.add(vote)
db.session.commit()
flash('Thanks for voting!', 'success')
# Check if the burger_id is valid
burger_id = request.form.get('burger_id')
if not burger_id or not Burger.query.get(burger_id):
return die('Invalid burger ID')
# User is casting their vote
if request.form.get('action') == 'like':
# Check if the user hasn't already voted for the same burger
if Vote.query.filter_by(nethz=g.user, burger_id=burger_id).first():
return die('You have already liked this burger.')
# Add vote
vote = Vote(
nethz=g.user,
burger_id=burger_id,
)
db.session.add(vote)
db.session.commit()
flash('Thanks for voting!', 'success')
# User is revoking their vote
elif request.form.get('action') == 'unlike':
# Find the vote
vote = Vote.query.filter_by(nethz=g.user, burger_id=burger_id).first()
# User is revoking their vote
elif request.form.get('action') == 'unlike':
# Find the vote
vote = Vote.query.filter_by(nethz=g.user, burger_id=burger_id).first()
if vote:
# Delete the vote
db.session.delete(vote)
db.session.commit()
if vote:
# Delete the vote
db.session.delete(vote)
db.session.commit()
flash('Your like has been removed.', 'success')
flash('Your like has been removed.', 'success')
return redirect(url_for('list'))
return render_list()
@app.route('/new', methods=['GET', 'POST'])
def create():
......@@ -92,10 +90,10 @@ def create():
flash(message, 'error')
return render_template('creator.html')
# A new burger was submitted
if request.method == 'POST':
# A new burger was submitted
# Perform field validation
bread = request.form.get('bread')
if not bread:
return die('Please select a bread for your burger.')
......@@ -138,8 +136,7 @@ def create():
db.session.add(burger)
db.session.commit()
# Redirect the user to the detail page of the new burger
flash('Congrats on your new burger!', 'success')
return redirect(url_for('detail', burger_id=burger.id))
return redirect(url_for('list'))
return render_template('creator.html')
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment