From: Michal Sojka Date: Tue, 18 Aug 2020 18:13:29 +0000 (+0200) Subject: Add event logging X-Git-Url: https://rtime.felk.cvut.cz/gitweb/coffee/coffee-flask.git/commitdiff_plain/cc4dee6ece87d554e7a5d81cc54be7d9df8e0b6e?hp=e5c5ffd4df1886ecb028399e8dca68f2e55d379c Add event logging This allows users to log various events such as coffee machine or milk container cleaning. Also, all users can see when was the last occurrence of the particular event. [Credits: This is a modified version of a patch from Jarda Klapálek.] --- diff --git a/app.py b/app.py index 0e0564a..14a2684 100644 --- a/app.py +++ b/app.py @@ -115,11 +115,14 @@ def user(): counts=counts, identifiers=db.list_user_identifiers(uid), iid=session["iid"], - stamp=time.time() + stamp=time.time(), + last_events=db.last_events() ) # TODO: Replace stamp parameter with proper cache control HTTP # headers in response - return render_template('user.html', stamp=time.time()) + return render_template('user.html', stamp=time.time(), + last_events=db.last_events(), + ) @app.route('/user/rename') @@ -265,6 +268,14 @@ def coffee_add(): return redirect(url_for('user')) +@app.route("/event", methods=["POST"]) +def event_add(): + json = request.json + print("User '%(uid)s' registered event %(event_name)s at %(time)s" % json) + db.add_event(json["uid"], json["event_name"], json["time"]) + return redirect(url_for('user')) + + # TODO: Remove me - unused @app.route("/coffee/count") def coffee_count(): diff --git a/coffee_db.py b/coffee_db.py index 25551f9..bc53024 100644 --- a/coffee_db.py +++ b/coffee_db.py @@ -99,6 +99,15 @@ def add_coffee(uid, flavor, time=None): c.execute("insert or ignore into coffees (id, flavor, time) values (?,?,?)", (uid, flavor, time)) close_db(conn) + +def add_event(uid, event_name, time): + conn, c = open_db() + c.execute("""insert into events (user_id, event_type, time) + values (?, (SELECT id FROM event_types WHERE name = ?), ?)""", + (uid, event_name, time)) + close_db(conn) + + def flavors(): conn, c = open_db() res = list(c.execute("select distinct name, ord from flavors")) @@ -193,3 +202,15 @@ def drink_count(uid=None, start=None, stop=None): "left join identifiers ids on co.id = ids.id where " + " and ".join(clauses) + " group by fl.type " "order by fl.ord asc", args)) + + +def last_events(): + """Return mapping with event names as keys and SQLite time string of + the last event as values. + """ + conn, c = open_db() + res = dict(c.execute("""select name, MAX(time) + from events as e left join event_types as et on e.event_type = et.id + group by name""")) + close_db(conn) + return res diff --git a/templates/main.js b/templates/main.js index 417dc40..67e6db7 100644 --- a/templates/main.js +++ b/templates/main.js @@ -8,6 +8,7 @@ var logoutTimer; var reloadTimer = undefined; var id_user; // ID of the user who is to be accounted for the next coffee var identifier_registration = false; // true if identifier is supposed to be registered for user +var eventMsg = undefined; // Feedback message about the last event performed by the user console.log("hello from flask"); //sendJSON("{\"type\":\"empty\"}"); @@ -46,9 +47,13 @@ function updateUI() return; } + if (eventMsg !== undefined) { + update("eventMsg", eventMsg); + eventMsg = undefined; + } if (id_user !== undefined) { document.getElementById("nextStep").innerHTML = "Now select a beverage on the coffee machine…"; - } else { + } else if (flavorChosen !== undefined) { document.getElementById("nextStep").innerHTML = "Enjoy your " + flavorChosen + "!"; } @@ -171,6 +176,7 @@ function logout() { id_user = undefined; timeToLogout = undefined; identifier_registration = false; + window.scrollTo(0, 0); // Scroll up } function countingTimeLogout(count_time) @@ -212,6 +218,21 @@ function addCoffee(flavor, time = new Date()) { } } + +function addEvent(event_name, action_msg, time = new Date()) { + var data = JSON.stringify({ + time: time.toISOString(), + event_name: event_name, + uid: id_user + }); + if (id_user) { + eventMsg = "You have " + action_msg + ". Thanks!" + ajax("POST", "event", data, "user"); + window.scrollTo(0, 0); // Scroll up + } +} + + function addIdentifier_start() { identifier_registration = true; document.getElementById("addIdentifier").disabled = true; diff --git a/templates/user.html b/templates/user.html index 5ad7b90..0a8597b 100644 --- a/templates/user.html +++ b/templates/user.html @@ -1,3 +1,36 @@ + + {% if name %}
@@ -5,6 +38,7 @@

Hello, {{ name }}!

+

{% if counts|length > 0 %} @@ -77,3 +111,45 @@ {% endif %} + +
+ + {%- macro event_box(title, events) -%} +
+

{{title | capitalize}}

+ {#- The first item in the list is used as button label, last item in the overview -#} + {%- set verb = { + "COFFEE_MACHINE_CLEANED": ["cleaned"], + "COFFEE_PACK_OPENED": ["opened"], + "LAST_COFFEE_PACK_OPENED": ["last opened"], + "MILK_CONTAINER_CLEANED": ["cleaned (water)", "cleaned"], + "MILK_CONTAINER_CLEANED_WITH_TABLET": ["cleaned (tablet)"], + } + -%} + {% if name -%} {# User logged in - show action buttons #} + {%- for event in events %} +
+ + ({{ last_events[event] | humanize if event in last_events else "never" }}) +
+ {%- endfor -%} + {%- else -%} {# Nobody logged in - show overview with summary times #} + {# Calculate maximum timestamp of all relevant events #} + {%- set when = last_events.items() | selectattr(0, 'in', + events) | map(attribute=1) | max | humanize -%} + {%- if when -%} + {{ verb[events[0]]|last }} {{ when }} + {%- else -%} + never {{ verb[events[0]]|last }} + {%- endif -%} + {%- endif %} +
+ {%- endmacro %} +
+

{{ ("Record
event" if name else "Events") | safe }}:

+ {{ event_box('coffee machine', ['COFFEE_MACHINE_CLEANED'] ) }} + {{ event_box('coffee pack', ['COFFEE_PACK_OPENED'] ) }} + {{ event_box('milk container', ['MILK_CONTAINER_CLEANED', 'MILK_CONTAINER_CLEANED_WITH_TABLET'] ) }} +
+