diff --git a/kukv1.py b/kukv1.py index 6280f90..80f98fa 100644 --- a/kukv1.py +++ b/kukv1.py @@ -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':'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)) meals = [] + leaderboard = getLeaderboard() for row in r: meals.append(dict(row)) 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]['meal_time'] = meals[-1]['meal_date'].strftime('%H:%M') 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: meals[-1]['needs_confirmation'] = True else: meals[-1]['needs_confirmation'] = False + leaderboard = applyTempMeal(leaderboard, meals[-1]) r.close() 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): 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) @@ -161,8 +184,12 @@ def meal_planner(): @app.route('/searchusers') def search_users(): q = request.args.get('q') + s = request.args.get('s') query = 'select username from users where id>0 and username like :q;' - r = db_engine.execute(text(query), q=(q+'%')) + if s == '1': + r = db_engine.execute(text(query), q=(q+'%')) + else: + r = db_engine.execute(text(query), q=q) result = [] for row in r: result.append(list(row)[0]) @@ -173,9 +200,11 @@ def search_users(): def get_kuk_candidate(): date = datetime.datetime.strptime(request.args.get('date'), '%Y-%m-%d %H:%M') meal_eaters = request.args.get('eaters').split(',') - - # TODO: Implement - return 'davide' + u_meals = getUpcomingMeals() + leaderboard = getLeaderboard() + 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']) def login(): diff --git a/static/mealplanner_script.js b/static/mealplanner_script.js index 9005f29..d2fb95d 100644 --- a/static/mealplanner_script.js +++ b/static/mealplanner_script.js @@ -5,7 +5,7 @@ $( function() { $(".user-result-container").position({ my: "left top", at: "left bottom", - of: $('#search-user'), // or $("#otherdiv") + of: $('#search-user'), collision: "fit" }); $('.user-result-container').hide(); @@ -34,20 +34,23 @@ function plan_meal() { } function add_user() { + if (eaters.includes($('#search-user').val())) + return; $.ajax({ - url: "/searchusers?q=" + $('#search-user').val() + url: "/searchusers?q=" + $('#search-user').val() + "&s=0" }).done(function(results) { if (results == '[]') { alert('Invalid username'); return; } - names = results.substring(1, results.length-1).split(', '); - if (names.length > 1) { - alert('Please choose one.'); + var meal_date = $('#datepicker').datepicker('getDate'); + if (meal_date == null || $('#spinner-hour').val() == '' || $('#spinner-minute').val() == '') { + alert('Please select a date and a time.'); return; } - eaters.push(names[0].substring(1, names[0].length)); - var meal_date = $('#datepicker').datepicker('getDate'); + names = results.substring(1, results.length - 1).split(', '); + new_eater = names[0].substring(1, names[0].length - 1); + eaters.push(new_eater); var month = (meal_date.getMonth() + 1).toString(); if (month.length == 1) month = '0' + month; @@ -69,7 +72,26 @@ function add_user() { $('#est-cook').attr('src', 'static/' + estkuk + '.png') $('#est-cook').attr('title', estkuk) }); + e = '
\ +
\ + \ + ' + new_eater + '\ +
\ +
\ +
'; + $('#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) { @@ -82,7 +104,7 @@ function user_search() { if ($('#search-user').val() == '') return; $.ajax({ - url: "/searchusers?q=" + $('#search-user').val() + url: "/searchusers?q=" + $('#search-user').val() + "&s=1" }).done(function(results) { // Load results if (results == '[]') @@ -97,6 +119,12 @@ function user_search() { ' $('.user-result-container').append($(e)); }); + // $(".user-result-container").position({ + // my: "left top", + // at: "left bottom", + // of: $('#search-user'), + // collision: "fit" + // }); $('.user-result-container').show(); }); } \ No newline at end of file diff --git a/static/style.css b/static/style.css index 059609f..2390399 100644 --- a/static/style.css +++ b/static/style.css @@ -63,7 +63,7 @@ h2 { box-shadow: 2px 2px 5px 0px rgba(0,0,0,0.5); } -.flex-card img { +.flex-thumb { height: 80px; width: 80px; margin: 16px 20px; @@ -238,15 +238,15 @@ h2 { margin: 5px 0; } -.when { +.sub-flex { display: flex; } -.when * { +.sub-flex * { margin: auto 3px; } -#search-user, #flavor-text, #datepicker { +#search-user, #flavor-text, #datepicker, #deadline-amount { min-width: 0; padding: 0.5em; } diff --git a/templates/meal_planner.html b/templates/meal_planner.html index 75d7293..6166fef 100644 --- a/templates/meal_planner.html +++ b/templates/meal_planner.html @@ -28,7 +28,7 @@

Plan a meal

When

-
+
@ @@ -37,18 +37,28 @@

Choose a description

+

Can join until

+
+ + + before +

Estimated cook:

-
+

Add people

-
+
- + {{ current_user.name }}
-
+
-
+
diff --git a/templates/view_meal.html b/templates/view_meal.html index 33a5aee..b86b76e 100644 --- a/templates/view_meal.html +++ b/templates/view_meal.html @@ -33,7 +33,7 @@

Cook

{% if meal.kuk == "" %} - +

If nobody volunteers,
will cook.

VOLUNTEER
{% else %} @@ -45,7 +45,7 @@

Eaters

{% for eater in meal.eaters %}
- + {{ eater }}
{% endfor %}