Marek Baczynski 6 years ago
commit 0829704105

@ -60,9 +60,10 @@ def getUpcomingMeals():
# meals.append({'id':2, 'kuk':'marek', 'eaters':['davide','sven','david', 'wille'], 'flavor_text':'Grzybowa', 'date':'Sunday 25rd of November', 'selection_deadline':'3 Days 23 hours', 'status':0}) # meals.append({'id':2, 'kuk':'marek', 'eaters':['davide','sven','david', 'wille'], 'flavor_text':'Grzybowa', 'date':'Sunday 25rd of November', 'selection_deadline':'3 Days 23 hours', 'status':0})
# meals.append({'id':2, 'kuk':'marek', 'eaters':['davide','sven','david', 'wille'], 'flavor_text':'Grzybowa', 'date':'Sunday 25rd of November', 'selection_deadline':'3 Days 23 hours', 'status':0}) # meals.append({'id':2, 'kuk':'marek', 'eaters':['davide','sven','david', 'wille'], 'flavor_text':'Grzybowa', 'date':'Sunday 25rd of November', 'selection_deadline':'3 Days 23 hours', 'status':0})
# meals.append({'id':2, 'kuk':'marek', 'eaters':['davide','sven','david', 'wille'], 'flavor_text':'Grzybowa', 'date':'Monday 26rd of November', 'selection_deadline':'3 Days 23 hours', 'status':0}) # meals.append({'id':2, 'kuk':'marek', 'eaters':['davide','sven','david', 'wille'], 'flavor_text':'Grzybowa', 'date':'Monday 26rd of November', 'selection_deadline':'3 Days 23 hours', 'status':0})
query = 'select foo.id, username as kuk, meal_date, array_agg as eaters, selection_deadline from (select meals.id, kuk, meal_date, selection_deadline, array_agg(username) from meals join users on users.id = any(meals.eaters) where meals.status=0 group by meals.id order by meal_date) as foo join users on kuk=users.id;' query = 'select foo.id, username as kuk, meal_date, array_agg as eaters, selection_deadline, is_lazy from (select is_lazy, meals.id, kuk, meal_date, selection_deadline, array_agg(username) from meals join users on users.id = any(meals.eaters) where meals.status=0 group by meals.id order by meal_date) as foo join users on kuk=users.id;'
r = db_engine.execute(text(query)) r = db_engine.execute(text(query))
meals = [] meals = []
leaderboard = getLeaderboard()
for row in r: for row in r:
meals.append(dict(row)) meals.append(dict(row))
seconds_to_deadline = (meals[-1]['selection_deadline'] - datetime.datetime.now()).total_seconds() seconds_to_deadline = (meals[-1]['selection_deadline'] - datetime.datetime.now()).total_seconds()
@ -77,14 +78,36 @@ def getUpcomingMeals():
meals[-1]['friendly_selection_deadline'] = str(round(seconds_to_deadline / 60)) + ' minutes' meals[-1]['friendly_selection_deadline'] = str(round(seconds_to_deadline / 60)) + ' minutes'
meals[-1]['meal_time'] = meals[-1]['meal_date'].strftime('%H:%M') meals[-1]['meal_time'] = meals[-1]['meal_date'].strftime('%H:%M')
meals[-1]['meal_friendly_date'] = meals[-1]['meal_date'].strftime('%A %d %B') meals[-1]['meal_friendly_date'] = meals[-1]['meal_date'].strftime('%A %d %B')
meals[-1]['candidate'] = 'davide' meals[-1]['candidate'] = [l['name'] for l in leaderboard if l['name'] in meals[-1]['eaters']][0]
if (meals[-1]['meal_date'] - datetime.datetime.now()).total_seconds() < 0: if (meals[-1]['meal_date'] - datetime.datetime.now()).total_seconds() < 0:
meals[-1]['needs_confirmation'] = True meals[-1]['needs_confirmation'] = True
else: else:
meals[-1]['needs_confirmation'] = False meals[-1]['needs_confirmation'] = False
leaderboard = applyTempMeal(leaderboard, meals[-1])
r.close() r.close()
return meals return meals
def applyTempMeal(leaderboard, meal):
ld = leaderboard[:]
m = meal.copy()
if m['kuk'] == '':
m['kuk'] = m['candidate']
m['eaters'].remove(m['candidate'])
for i in range(len(ld)):
if ld[i]['name'] == m['kuk']:
if m['is_lazy']:
ld[i]['score'] += LAZY_KUK_POINTS[len(m['eaters'])]
else:
ld[i]['score'] += KUK_POINTS[len(m['eaters'])]
ld[i]['last_meal'] = m['meal_date']
elif ld[i]['name'] in m['eaters']:
if m['is_lazy']:
ld[i]['score'] -= LAZY_KUK_POINTS[len(m['eaters'])] / len(m['eaters'])
else:
ld[i]['score'] -= KUK_POINTS[len(m['eaters'])] / len(m['eaters'])
return sorted(ld, key=lambda i:(i['score'], i['last_meal'] or datetime.datetime(1970, 1, 1, 0, 0)))
def getMeal(meal_id): def getMeal(meal_id):
query = 'select foo.id, username as kuk, meal_date, array_agg as eaters, selection_deadline from (select meals.id, kuk, meal_date, selection_deadline, array_agg(username) from meals join users on users.id = any(meals.eaters) where meals.id=:meal_id group by meals.id order by meal_date) as foo join users on kuk=users.id;' query = 'select foo.id, username as kuk, meal_date, array_agg as eaters, selection_deadline from (select meals.id, kuk, meal_date, selection_deadline, array_agg(username) from meals join users on users.id = any(meals.eaters) where meals.id=:meal_id group by meals.id order by meal_date) as foo join users on kuk=users.id;'
r = db_engine.execute(text(query), meal_id=meal_id) r = db_engine.execute(text(query), meal_id=meal_id)
@ -161,8 +184,12 @@ def meal_planner():
@app.route('/searchusers') @app.route('/searchusers')
def search_users(): def search_users():
q = request.args.get('q') q = request.args.get('q')
s = request.args.get('s')
query = 'select username from users where id>0 and username like :q;' query = 'select username from users where id>0 and username like :q;'
if s == '1':
r = db_engine.execute(text(query), q=(q+'%')) r = db_engine.execute(text(query), q=(q+'%'))
else:
r = db_engine.execute(text(query), q=q)
result = [] result = []
for row in r: for row in r:
result.append(list(row)[0]) result.append(list(row)[0])
@ -173,9 +200,11 @@ def search_users():
def get_kuk_candidate(): def get_kuk_candidate():
date = datetime.datetime.strptime(request.args.get('date'), '%Y-%m-%d %H:%M') date = datetime.datetime.strptime(request.args.get('date'), '%Y-%m-%d %H:%M')
meal_eaters = request.args.get('eaters').split(',') meal_eaters = request.args.get('eaters').split(',')
u_meals = getUpcomingMeals()
# TODO: Implement leaderboard = getLeaderboard()
return 'davide' for meal in u_meals:
leaderboard = applyTempMeal(leaderboard, meal)
return [e['name'] for e in leaderboard if e['name'] in eaters][0]
@app.route('/login', methods=['GET', 'POST']) @app.route('/login', methods=['GET', 'POST'])
def login(): def login():

@ -5,7 +5,7 @@ $( function() {
$(".user-result-container").position({ $(".user-result-container").position({
my: "left top", my: "left top",
at: "left bottom", at: "left bottom",
of: $('#search-user'), // or $("#otherdiv") of: $('#search-user'),
collision: "fit" collision: "fit"
}); });
$('.user-result-container').hide(); $('.user-result-container').hide();
@ -34,20 +34,23 @@ function plan_meal() {
} }
function add_user() { function add_user() {
if (eaters.includes($('#search-user').val()))
return;
$.ajax({ $.ajax({
url: "/searchusers?q=" + $('#search-user').val() url: "/searchusers?q=" + $('#search-user').val() + "&s=0"
}).done(function(results) { }).done(function(results) {
if (results == '[]') { if (results == '[]') {
alert('Invalid username'); alert('Invalid username');
return; return;
} }
names = results.substring(1, results.length-1).split(', '); var meal_date = $('#datepicker').datepicker('getDate');
if (names.length > 1) { if (meal_date == null || $('#spinner-hour').val() == '' || $('#spinner-minute').val() == '') {
alert('Please choose one.'); alert('Please select a date and a time.');
return; return;
} }
eaters.push(names[0].substring(1, names[0].length)); names = results.substring(1, results.length - 1).split(', ');
var meal_date = $('#datepicker').datepicker('getDate'); new_eater = names[0].substring(1, names[0].length - 1);
eaters.push(new_eater);
var month = (meal_date.getMonth() + 1).toString(); var month = (meal_date.getMonth() + 1).toString();
if (month.length == 1) if (month.length == 1)
month = '0' + month; month = '0' + month;
@ -69,9 +72,28 @@ function add_user() {
$('#est-cook').attr('src', 'static/' + estkuk + '.png') $('#est-cook').attr('src', 'static/' + estkuk + '.png')
$('#est-cook').attr('title', estkuk) $('#est-cook').attr('title', estkuk)
}); });
e = '<div class="add-people-container" id="for-user-' + new_eater + '">\
<div class="flex-card" style="margin: 0">\
<img src="static/' + new_eater + '.png">\
<span class="username">' + new_eater + '</span>\
</div>\
<div class="small-round-button" onclick="remove_user(\'' + new_eater + '\')"><i class="fa fa-minus" aria-hidden="true"></i></div>\
</div>';
$('#add-user').before(e);
$('.small-round-button').show();
}); });
} }
function remove_user(name) {
eaters = eaters.filter(function(value, index, arr){
return value != name;
});
$('#for-user-' + name).remove();
if ($('#eaters-list > div').length == 2) {
$('.small-round-button').hide();
}
}
function fill_box(name) { function fill_box(name) {
$('#search-user').val(name); $('#search-user').val(name);
$('.user-result-container').hide(); $('.user-result-container').hide();
@ -82,7 +104,7 @@ function user_search() {
if ($('#search-user').val() == '') if ($('#search-user').val() == '')
return; return;
$.ajax({ $.ajax({
url: "/searchusers?q=" + $('#search-user').val() url: "/searchusers?q=" + $('#search-user').val() + "&s=1"
}).done(function(results) { }).done(function(results) {
// Load results // Load results
if (results == '[]') if (results == '[]')
@ -97,6 +119,12 @@ function user_search() {
</div>' </div>'
$('.user-result-container').append($(e)); $('.user-result-container').append($(e));
}); });
// $(".user-result-container").position({
// my: "left top",
// at: "left bottom",
// of: $('#search-user'),
// collision: "fit"
// });
$('.user-result-container').show(); $('.user-result-container').show();
}); });
} }

@ -63,7 +63,7 @@ h2 {
box-shadow: 2px 2px 5px 0px rgba(0,0,0,0.5); box-shadow: 2px 2px 5px 0px rgba(0,0,0,0.5);
} }
.flex-card img { .flex-thumb {
height: 80px; height: 80px;
width: 80px; width: 80px;
margin: 16px 20px; margin: 16px 20px;
@ -238,15 +238,15 @@ h2 {
margin: 5px 0; margin: 5px 0;
} }
.when { .sub-flex {
display: flex; display: flex;
} }
.when * { .sub-flex * {
margin: auto 3px; margin: auto 3px;
} }
#search-user, #flavor-text, #datepicker { #search-user, #flavor-text, #datepicker, #deadline-amount {
min-width: 0; min-width: 0;
padding: 0.5em; padding: 0.5em;
} }

@ -28,7 +28,7 @@
<h1 style="margin: 40px;">Plan a meal</h1> <h1 style="margin: 40px;">Plan a meal</h1>
<div class="flex-card-vert"> <div class="flex-card-vert">
<h3>When</h3> <h3>When</h3>
<div class="when"> <div class="sub-flex" id="when">
<input type="text" id="datepicker" name="date" style="flex: 7;"> <input type="text" id="datepicker" name="date" style="flex: 7;">
<span style="flex: 0.5;">@</span> <span style="flex: 0.5;">@</span>
<input type="text" id="spinner-hour" name="hour" style="flex: 4;"> <input type="text" id="spinner-hour" name="hour" style="flex: 4;">
@ -37,18 +37,28 @@
</div> </div>
<h3>Choose a description</h3> <h3>Choose a description</h3>
<input type="text" name="flavor_text" id="flavor-text"> <input type="text" name="flavor_text" id="flavor-text">
<h3>Can join until</h3>
<div class="sub-flex" id="deadline">
<input type="text" name="deadline-amount" id="deadline-amount" pattern="[0-9]+">
<select id="deadline-unit">
<option value="m">Minutes</option>
<option value="h" selected>Hours</option>
<option value="d">Days</option>
</select>
<span>before</span>
</div>
<h3>Estimated cook: <img src="{{url_for('static', filename=current_user.name + '.png')}}" id="est-cook" class="flex-small-thumb" title="{{current_user.name}}"></h3> <h3>Estimated cook: <img src="{{url_for('static', filename=current_user.name + '.png')}}" id="est-cook" class="flex-small-thumb" title="{{current_user.name}}"></h3>
</div> </div>
<div class="flex-card-vert"> <div class="flex-card-vert" id="eaters-list">
<h3>Add people</h3> <h3>Add people</h3>
<div class="add-people-container"> <div class="add-people-container" id="for-user-{{current_user.name}}">
<div class="flex-card" style="margin: 0"> <div class="flex-card" style="margin: 0">
<img src="{{url_for('static', filename=current_user.name + '.png')}}"> <img src="{{url_for('static', filename=current_user.name + '.png')}}" class="flex-thumb">
<span class="username">{{ current_user.name }}</span> <span class="username">{{ current_user.name }}</span>
</div> </div>
<div class="small-round-button"><i class="fa fa-minus" aria-hidden="true"></i></div> <div class="small-round-button" style="display: none;" onclick="remove_user('{{current_user.name}}')"><i class="fa fa-minus" aria-hidden="true"></i></div>
</div> </div>
<div class="add-people-container"> <div class="add-people-container" id="add-user">
<input type="text" id="search-user"> <input type="text" id="search-user">
<div class="user-result-container"></div> <div class="user-result-container"></div>
<div class="round-button" onclick="add_user()"><i class="fa fa-plus" aria-hidden="true"></i></div> <div class="round-button" onclick="add_user()"><i class="fa fa-plus" aria-hidden="true"></i></div>

@ -33,7 +33,7 @@
<h2>Cook</h2> <h2>Cook</h2>
<div class="flex-card"> <div class="flex-card">
{% if meal.kuk == "" %} {% if meal.kuk == "" %}
<img src="{{url_for('static', filename='question.png')}}"> <img src="{{url_for('static', filename='question.png')}}" class="flex-thumb">
<p>If nobody volunteers,<br><img class="flex-small-thumb" src="{{url_for('static', filename=meal.candidate + '.png')}}" title="{{meal.candidate}}" align="middle"> will cook.</p> <p>If nobody volunteers,<br><img class="flex-small-thumb" src="{{url_for('static', filename=meal.candidate + '.png')}}" title="{{meal.candidate}}" align="middle"> will cook.</p>
<div class="rect-button" onclick="location.href='/volunteer';" style="background-color: #EE7500;">VOLUNTEER</div> <div class="rect-button" onclick="location.href='/volunteer';" style="background-color: #EE7500;">VOLUNTEER</div>
{% else %} {% else %}
@ -45,7 +45,7 @@
<h2>Eaters</h2> <h2>Eaters</h2>
{% for eater in meal.eaters %} {% for eater in meal.eaters %}
<div class="flex-card"> <div class="flex-card">
<img src="{{url_for('static', filename=eater + '.png')}}"> <img src="{{url_for('static', filename=eater + '.png')}}" class="flex-thumb">
<span class="username">{{ eater }}</span> <span class="username">{{ eater }}</span>
</div> </div>
{% endfor %} {% endfor %}

Loading…
Cancel
Save