Skip to content

Commit

Permalink
Display stats on coffee.html
Browse files Browse the repository at this point in the history
  • Loading branch information
hackenbergstefan committed Aug 17, 2024
1 parent c6c24d8 commit 21d80a6
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 22 deletions.
2 changes: 1 addition & 1 deletion coffeebuddy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy.exc import OperationalError

__version__ = "1.2.1"
__version__ = "1.3.0"

db = SQLAlchemy()
login_manager = flask_login.LoginManager()
Expand Down
66 changes: 49 additions & 17 deletions coffeebuddy/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from sqlalchemy import text


def db_weekday(column):
def db_weekday(column) -> str:
"""Helper to extract weekday for different database backends"""
if flask.current_app.db.engine.name == "postgresql":
return sqlalchemy.func.extract("dow", column)
Expand Down Expand Up @@ -230,6 +230,7 @@ def drinks_this_week(self) -> Tuple[List[str], List[int]]:
def drinks_last_weeks(
self,
since=timedelta(weeks=12),
group_by="week",
) -> Tuple[List[str], List[int]]:
db = flask.current_app.db
now = date.today()
Expand All @@ -238,23 +239,42 @@ def drinks_last_weeks(
datetime.combine(now - timedelta(now.weekday()), datetime.min.time())
- since
)
data = tuple(
zip(
*db.session.execute(
db.select(
db_weekday(Drink.timestamp).label("weekday"),
db.func.count(db.func.Date(Drink.timestamp)) / number_of_weeks,
)
.where(
(Drink.userid == self.id)
& (db.func.Date(Drink.timestamp) >= since)
)
.group_by("weekday")
.order_by("weekday")
).all()
if group_by == "week":
data = tuple(
zip(
*db.session.execute(
db.select(
db_weekday(Drink.timestamp).label("weekday"),
db.func.count(db.func.Date(Drink.timestamp))
/ number_of_weeks,
)
.where(
(Drink.userid == self.id)
& (db.func.Date(Drink.timestamp) >= since)
)
.group_by("weekday")
.order_by("weekday")
).all()
)
)
return [weekday(int(i)) for i in data[0]], list(data[1])
elif group_by == "day":
return tuple(
zip(
*db.session.execute(
db.select(
db.func.Date(Drink.timestamp).label("day"),
db.func.count(db.func.Date(Drink.timestamp)),
)
.where(
(Drink.userid == self.id)
& (db.func.Date(Drink.timestamp) >= since)
)
.group_by("day")
.order_by("day")
).all()
)
)
)
return [weekday(int(i)) for i in data[0]], list(data[1])

@staticmethod
def drinks_last_weeks_all(since=timedelta(weeks=12)) -> Tuple[List[str], List[int]]:
Expand Down Expand Up @@ -288,6 +308,18 @@ def drinks_last_weeks_all(since=timedelta(weeks=12)) -> Tuple[List[str], List[in
)
return [weekday(int(i)) for i in data[0]], list(data[1])

def drinks_avg_today(self) -> float:
db = flask.current_app.db
today_weekday = str(date.today().weekday())

data = db.session.scalars(
db.select(db.func.count("*"))
.where(Drink.userid == self.id)
.where(db_weekday(db.func.Date(Drink.timestamp)) == today_weekday)
.group_by(db.func.Date(Drink.timestamp))
).all()
return sum(data) / len(data) if data else 0


class Drink(flask.current_app.db.Model):
id = flask.current_app.db.Column(flask.current_app.db.Integer, primary_key=True)
Expand Down
11 changes: 11 additions & 0 deletions coffeebuddy/route_coffee.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
import datetime

import flask

from coffeebuddy.model import Drink, User, escapefromhex


def last_mondays(weeks=4):
now = datetime.datetime.now().date()
monday = now - datetime.timedelta(days=now.weekday())
return [monday - datetime.timedelta(weeks=i) for i in range(weeks)]


def init():
@flask.current_app.route("/coffee.html", methods=["GET", "POST"])
def coffee():
Expand Down Expand Up @@ -41,4 +49,7 @@ def coffee():
"coffee.html",
user=user,
referer=flask.request.form if flask.request.method == "POST" else [],
today_name=datetime.datetime.now().strftime("%A"),
datetime=datetime,
last_mondays=last_mondays(),
)
78 changes: 74 additions & 4 deletions coffeebuddy/templates/coffee.html
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,64 @@
{% endif %}
});
</script>
<script>
$.getScript("https://cdnjs.cloudflare.com/ajax/libs/plotly.js/2.34.0/plotly.min.js", () => {
const drinks_last_weeks = {{ user.drinks_last_weeks(since=datetime.timedelta(weeks=4), group_by="day") | tojson }};
const data = [
{
x: drinks_last_weeks[0],
y: drinks_last_weeks[1],
type: 'bar',
marker: {
color: 'rgba(171, 55, 122, 0.6)',
},
},
];
const shapes = [
{% for monday in last_mondays %}
{
type: 'line',
x0: '{{ monday }}',
y0: 0,
x1: '{{ monday }}',
yref: 'paper',
y1: 1,
line: {
color: 'grey',
width: 1.5,
dash: 'dot'
}
},
{% endfor %}
];
layout = {
plot_bgcolor: 'rgba(0,0,0,0)',
paper_bgcolor: 'rgba(0,0,0,0)',
margin: {
t: 0,
b: 50,
l: 30,
r: 0,
},
xaxis: {
rangebreaks: [{
bounds: ['sat', 'mon'],
pattern: 'day of week'
}],
tickformat: '%d %b',
dtick: 7 * 86400000.0,
},
yaxis: {
dtick: 1,
},
barcornerradius: 4,
bargap: 0.01,
shapes: shapes,
};
Plotly.newPlot('stats', data, layout);
});
</script>
</script>
<style>
.btnbar {
width: 200px;
Expand Down Expand Up @@ -149,14 +207,13 @@
</div>
</form>
</div>
<div class="d-flex flex-column flex-grow text-center w-100 mx-5 my-4">
<div class="d-flex flex-column flex-grow text-center mx-5 my-4">
<div class="text-left">
<h3>Hi</h3>
<h1 id="user-name">{{ user.prename }} {{ user.name }}</h1>
<code class="h5">{{ hexstr(user.tag) }}</code>
</div>
<div class="my-auto">
<div id="stats" class="flex-grow-1"></div>
<div class="my-auto align-self-end">
<form method="post">
<button id="btn-coffee" type="submit" class="btn-coffee" name="coffee" value="coffee">
<div id="btn-coffee-icon" class="display-1 fas fa-coffee"></div>
Expand All @@ -165,7 +222,20 @@ <h1 id="user-name">{{ user.prename }} {{ user.name }}</h1>
</form>
</div>
</div>
<div class="d-flex m-4" style="width: 500px;">
<div class="d-flex flex-column m-4" style="width: 350px;">
<div class="h4 pb-2 mb-4 border-bottom border-dark">Your <div class="fas fa-coffee"></div> in numbers</div>
<div class="h4">Today you already had</div>
<div class="h3 color-berry font-weight-bold">{{ user.drinks_today | length }}</div>
<div class="my-3"></div>

<div class="h5">On {{ today_name }} you usually have</div>
<div class="h4 color-berry font-weight-bold">{{ '%0.1f' | format(user.drinks_avg_today()) }}</div>
<div class="my-3"></div>

<div class="h5">Your last month</div>
<div id="stats" class="w-100" style="height: 200px">
</div>
</div>
</div>
</div>
<canvas id="matrix"></canvas>
Expand Down

0 comments on commit 21d80a6

Please sign in to comment.