Compare commits
No commits in common. "c814b4c2cb29e591deb047b1b99b7ec45f662535" and "9a332593f49c7146568331811201641964d55714" have entirely different histories.
c814b4c2cb
...
9a332593f4
|
@ -18,7 +18,6 @@ steps:
|
||||||
repo: registry.kucharczyk.xyz/timetracker
|
repo: registry.kucharczyk.xyz/timetracker
|
||||||
tags:
|
tags:
|
||||||
- latest
|
- latest
|
||||||
- 1.1.0
|
|
||||||
depends_on:
|
depends_on:
|
||||||
- "test"
|
- "test"
|
||||||
when:
|
when:
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
## 1.1.0 / 2023-10-09 00:01+02:00
|
## Unreleased
|
||||||
|
|
||||||
### New
|
### New
|
||||||
* Add game overview page (https://git.kucharczyk.xyz/lukas/timetracker/issues/8)
|
* Add game overview page (https://git.kucharczyk.xyz/lukas/timetracker/issues/8)
|
||||||
|
|
|
@ -6,7 +6,7 @@ RUN npm install && \
|
||||||
|
|
||||||
FROM python:3.10.9-slim-bullseye
|
FROM python:3.10.9-slim-bullseye
|
||||||
|
|
||||||
ENV VERSION_NUMBER 1.1.0
|
ENV VERSION_NUMBER 1.0.3
|
||||||
ENV PROD 1
|
ENV PROD 1
|
||||||
ENV PYTHONUNBUFFERED=1
|
ENV PYTHONUNBUFFERED=1
|
||||||
|
|
||||||
|
|
|
@ -36,9 +36,9 @@ def format_duration(
|
||||||
minute_seconds = 60
|
minute_seconds = 60
|
||||||
hour_seconds = 60 * minute_seconds
|
hour_seconds = 60 * minute_seconds
|
||||||
day_seconds = 24 * hour_seconds
|
day_seconds = 24 * hour_seconds
|
||||||
safe_duration = _safe_timedelta(duration)
|
duration = _safe_timedelta(duration)
|
||||||
# we don't need float
|
# we don't need float
|
||||||
seconds_total = int(safe_duration.total_seconds())
|
seconds_total = int(duration.total_seconds())
|
||||||
# timestamps where end is before start
|
# timestamps where end is before start
|
||||||
if seconds_total < 0:
|
if seconds_total < 0:
|
||||||
seconds_total = 0
|
seconds_total = 0
|
||||||
|
|
|
@ -73,14 +73,11 @@ class Platform(models.Model):
|
||||||
|
|
||||||
|
|
||||||
class SessionQuerySet(models.QuerySet):
|
class SessionQuerySet(models.QuerySet):
|
||||||
def total_duration_formatted(self):
|
def total_duration(self):
|
||||||
return format_duration(self.total_duration_unformatted())
|
|
||||||
|
|
||||||
def total_duration_unformatted(self):
|
|
||||||
result = self.aggregate(
|
result = self.aggregate(
|
||||||
duration=Sum(F("duration_calculated") + F("duration_manual"))
|
duration=Sum(F("duration_calculated") + F("duration_manual"))
|
||||||
)
|
)
|
||||||
return result["duration"]
|
return format_duration(result["duration"])
|
||||||
|
|
||||||
|
|
||||||
class Session(models.Model):
|
class Session(models.Model):
|
||||||
|
@ -119,7 +116,7 @@ class Session(models.Model):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def duration_sum(self) -> str:
|
def duration_sum(self) -> str:
|
||||||
return Session.objects.all().total_duration_formatted()
|
return Session.objects.all().total_duration()
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
if self.timestamp_start != None and self.timestamp_end != None:
|
if self.timestamp_start != None and self.timestamp_end != None:
|
||||||
|
|
|
@ -771,38 +771,35 @@ select {
|
||||||
top: 0.75rem;
|
top: 0.75rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx-2 {
|
|
||||||
margin-left: 0.5rem;
|
|
||||||
margin-right: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx-auto {
|
.mx-auto {
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.my-2 {
|
|
||||||
margin-top: 0.5rem;
|
|
||||||
margin-bottom: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.my-4 {
|
.my-4 {
|
||||||
margin-top: 1rem;
|
margin-top: 1rem;
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mb-1 {
|
.mx-2 {
|
||||||
|
margin-left: 0.5rem;
|
||||||
|
margin-right: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.my-1 {
|
||||||
|
margin-top: 0.25rem;
|
||||||
margin-bottom: 0.25rem;
|
margin-bottom: 0.25rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.my-2 {
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
.mb-4 {
|
.mb-4 {
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ml-2 {
|
|
||||||
margin-left: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mr-4 {
|
.mr-4 {
|
||||||
margin-right: 1rem;
|
margin-right: 1rem;
|
||||||
}
|
}
|
||||||
|
@ -811,6 +808,30 @@ select {
|
||||||
margin-top: 1rem;
|
margin-top: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mt-1 {
|
||||||
|
margin-top: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mt-2 {
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mb-2 {
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mb-1 {
|
||||||
|
margin-bottom: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ml-1 {
|
||||||
|
margin-left: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ml-2 {
|
||||||
|
margin-left: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
.block {
|
.block {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
@ -827,6 +848,10 @@ select {
|
||||||
display: table;
|
display: table;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.list-item {
|
||||||
|
display: list-item;
|
||||||
|
}
|
||||||
|
|
||||||
.hidden {
|
.hidden {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
@ -847,18 +872,30 @@ select {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.w-5 {
|
||||||
|
width: 1.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
.max-w-screen-lg {
|
.max-w-screen-lg {
|
||||||
max-width: 1024px;
|
max-width: 1024px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.max-w-sm {
|
|
||||||
max-width: 24rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.max-w-xs {
|
.max-w-xs {
|
||||||
max-width: 20rem;
|
max-width: 20rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.max-w-lg {
|
||||||
|
max-width: 32rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.max-w-3xl {
|
||||||
|
max-width: 48rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.max-w-sm {
|
||||||
|
max-width: 24rem;
|
||||||
|
}
|
||||||
|
|
||||||
@keyframes spin {
|
@keyframes spin {
|
||||||
to {
|
to {
|
||||||
transform: rotate(360deg);
|
transform: rotate(360deg);
|
||||||
|
@ -869,6 +906,10 @@ select {
|
||||||
animation: spin 1s linear infinite;
|
animation: spin 1s linear infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.list-disc {
|
||||||
|
list-style-type: disc;
|
||||||
|
}
|
||||||
|
|
||||||
.flex-col {
|
.flex-col {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
@ -912,6 +953,16 @@ select {
|
||||||
border-color: rgb(229 231 235 / var(--tw-border-opacity));
|
border-color: rgb(229 231 235 / var(--tw-border-opacity));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.border-red-300 {
|
||||||
|
--tw-border-opacity: 1;
|
||||||
|
border-color: rgb(252 165 165 / var(--tw-border-opacity));
|
||||||
|
}
|
||||||
|
|
||||||
|
.border-red-500 {
|
||||||
|
--tw-border-opacity: 1;
|
||||||
|
border-color: rgb(239 68 68 / var(--tw-border-opacity));
|
||||||
|
}
|
||||||
|
|
||||||
.border-slate-500 {
|
.border-slate-500 {
|
||||||
--tw-border-opacity: 1;
|
--tw-border-opacity: 1;
|
||||||
border-color: rgb(100 116 139 / var(--tw-border-opacity));
|
border-color: rgb(100 116 139 / var(--tw-border-opacity));
|
||||||
|
@ -927,6 +978,11 @@ select {
|
||||||
background-color: rgb(255 255 255 / var(--tw-bg-opacity));
|
background-color: rgb(255 255 255 / var(--tw-bg-opacity));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.bg-slate-400 {
|
||||||
|
--tw-bg-opacity: 1;
|
||||||
|
background-color: rgb(148 163 184 / var(--tw-bg-opacity));
|
||||||
|
}
|
||||||
|
|
||||||
.p-4 {
|
.p-4 {
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
}
|
}
|
||||||
|
@ -962,9 +1018,12 @@ select {
|
||||||
font-family: IBM Plex Mono, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
font-family: IBM Plex Mono, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-3xl {
|
.font-serif {
|
||||||
font-size: 1.875rem;
|
font-family: IBM Plex Serif, ui-serif, Georgia, Cambria, "Times New Roman", Times, serif;
|
||||||
line-height: 2.25rem;
|
}
|
||||||
|
|
||||||
|
.font-sans {
|
||||||
|
font-family: IBM Plex Sans, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-4xl {
|
.text-4xl {
|
||||||
|
@ -977,11 +1036,6 @@ select {
|
||||||
line-height: 1.5rem;
|
line-height: 1.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-lg {
|
|
||||||
font-size: 1.125rem;
|
|
||||||
line-height: 1.75rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-xl {
|
.text-xl {
|
||||||
font-size: 1.25rem;
|
font-size: 1.25rem;
|
||||||
line-height: 1.75rem;
|
line-height: 1.75rem;
|
||||||
|
@ -992,10 +1046,62 @@ select {
|
||||||
line-height: 1rem;
|
line-height: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.text-2xl {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
line-height: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-9xl {
|
||||||
|
font-size: 8rem;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-8xl {
|
||||||
|
font-size: 6rem;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-7xl {
|
||||||
|
font-size: 4.5rem;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-6xl {
|
||||||
|
font-size: 3.75rem;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-5xl {
|
||||||
|
font-size: 3rem;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-lg {
|
||||||
|
font-size: 1.125rem;
|
||||||
|
line-height: 1.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-3xl {
|
||||||
|
font-size: 1.875rem;
|
||||||
|
line-height: 2.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
.font-semibold {
|
.font-semibold {
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.font-bold {
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.capitalize {
|
||||||
|
text-transform: capitalize;
|
||||||
|
}
|
||||||
|
|
||||||
|
.italic {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
.text-slate-300 {
|
.text-slate-300 {
|
||||||
--tw-text-opacity: 1;
|
--tw-text-opacity: 1;
|
||||||
color: rgb(203 213 225 / var(--tw-text-opacity));
|
color: rgb(203 213 225 / var(--tw-text-opacity));
|
||||||
|
@ -1011,10 +1117,23 @@ select {
|
||||||
color: rgb(253 224 71 / var(--tw-text-opacity));
|
color: rgb(253 224 71 / var(--tw-text-opacity));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.text-gray-600 {
|
||||||
|
--tw-text-opacity: 1;
|
||||||
|
color: rgb(75 85 99 / var(--tw-text-opacity));
|
||||||
|
}
|
||||||
|
|
||||||
.underline {
|
.underline {
|
||||||
text-decoration-line: underline;
|
text-decoration-line: underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.decoration-red-500 {
|
||||||
|
text-decoration-color: #ef4444;
|
||||||
|
}
|
||||||
|
|
||||||
|
.decoration-slate-400 {
|
||||||
|
text-decoration-color: #94a3b8;
|
||||||
|
}
|
||||||
|
|
||||||
.decoration-slate-500 {
|
.decoration-slate-500 {
|
||||||
text-decoration-color: #64748b;
|
text-decoration-color: #64748b;
|
||||||
}
|
}
|
||||||
|
@ -1284,17 +1403,11 @@ th label {
|
||||||
color: rgb(255 255 255 / var(--tw-text-opacity));
|
color: rgb(255 255 255 / var(--tw-text-opacity));
|
||||||
}
|
}
|
||||||
|
|
||||||
:is(.dark .dark\:text-slate-400) {
|
|
||||||
--tw-text-opacity: 1;
|
|
||||||
color: rgb(148 163 184 / var(--tw-text-opacity));
|
|
||||||
}
|
|
||||||
|
|
||||||
:is(.dark .dark\:text-slate-500) {
|
|
||||||
--tw-text-opacity: 1;
|
|
||||||
color: rgb(100 116 139 / var(--tw-text-opacity));
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 640px) {
|
@media (min-width: 640px) {
|
||||||
|
.sm\:ml-2 {
|
||||||
|
margin-left: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
.sm\:inline {
|
.sm\:inline {
|
||||||
display: inline;
|
display: inline;
|
||||||
}
|
}
|
||||||
|
@ -1307,6 +1420,10 @@ th label {
|
||||||
max-width: 28rem;
|
max-width: 28rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.sm\:max-w-lg {
|
||||||
|
max-width: 32rem;
|
||||||
|
}
|
||||||
|
|
||||||
.sm\:max-w-xl {
|
.sm\:max-w-xl {
|
||||||
max-width: 36rem;
|
max-width: 36rem;
|
||||||
}
|
}
|
||||||
|
@ -1358,11 +1475,11 @@ th label {
|
||||||
display: table-cell;
|
display: table-cell;
|
||||||
}
|
}
|
||||||
|
|
||||||
.lg\:max-w-3xl {
|
|
||||||
max-width: 48rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.lg\:max-w-lg {
|
.lg\:max-w-lg {
|
||||||
max-width: 32rem;
|
max-width: 32rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.lg\:max-w-3xl {
|
||||||
|
max-width: 48rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="text-slate-300 mx-auto max-w-screen-lg text-center">
|
<div class="text-slate-300 mx-auto max-w-screen-lg text-center">
|
||||||
{% if session_count > 0 %}
|
{% if session_count > 0 %}
|
||||||
You have played a total of {{ session_count }} sessions for a total of {{ total_duration_formatted }}.
|
You have played a total of {{ session_count }} sessions for a total of {{ total_duration }}.
|
||||||
{% elif not game_available or not platform_available %}
|
{% elif not game_available or not platform_available %}
|
||||||
There are no games in the database. Start by clicking "New Game" and "New Platform".
|
There are no games in the database. Start by clicking "New Game" and "New Platform".
|
||||||
{% elif not purchase_available %}
|
{% elif not purchase_available %}
|
||||||
|
|
|
@ -6,15 +6,10 @@
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="dark:text-white max-w-sm sm:max-w-xl lg:max-w-3xl mx-auto">
|
<div class="dark:text-white max-w-sm sm:max-w-xl lg:max-w-3xl mx-auto">
|
||||||
<h1 class="text-4xl">{{ game.name }} <span class="dark:text-slate-500">(#{{ game.pk }})</span></h1>
|
<h1 class="text-4xl">{{ game.name }} (#{{ game.pk }})</h1>
|
||||||
<h2 class="text-lg my-2 ml-2">
|
<h2 class="text-lg my-2 ml-2">{{ total_playtime }} ({{ first_session.timestamp_start | date:"M Y"}} — {{ last_session.timestamp_start | date:"M Y"}}) </h2>
|
||||||
{{ total_hours }} <span class="dark:text-slate-500">total</span>
|
|
||||||
{{ session_average }} <span class="dark:text-slate-500">avg</span>
|
|
||||||
({{ first_session.timestamp_start | date:"M Y"}}
|
|
||||||
—
|
|
||||||
{{ last_session.timestamp_start | date:"M Y"}}) </h2>
|
|
||||||
<hr class="border-slate-500">
|
<hr class="border-slate-500">
|
||||||
<h1 class="text-3xl mt-4 mb-1">Editions <span class="dark:text-slate-500">({{ editions.count }})</span></h1>
|
<h1 class="text-3xl mt-4 mb-1">Editions</h1>
|
||||||
<ul>
|
<ul>
|
||||||
{% for edition in editions %}
|
{% for edition in editions %}
|
||||||
<li class="sm:pl-2">
|
<li class="sm:pl-2">
|
||||||
|
@ -29,13 +24,13 @@
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
<h1 class="text-3xl mt-4 mb-1">Purchases <span class="dark:text-slate-500">({{ purchases.count }})</span></h1>
|
<h1 class="text-3xl mt-4 mb-1">Purchases</h1>
|
||||||
<ul>
|
<ul>
|
||||||
{% for purchase in purchases %}
|
{% for purchase in purchases %}
|
||||||
<li class="sm:pl-2">{{ purchase.platform }} ({{ purchase.get_ownership_type_display }}, {{ purchase.date_purchased | date:"Y" }}, {{ purchase.price }} {{ purchase.price_currency}})</li>
|
<li class="sm:pl-2">{{ purchase.platform }} ({{ purchase.get_ownership_type_display }}, {{ purchase.date_purchased | date:"Y" }}, {{ purchase.price }} {{ purchase.price_currency}})</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
<h1 class="text-3xl mt-4 mb-1">Sessions <span class="dark:text-slate-500">({{ sessions.count }})</span></h1>
|
<h1 class="text-3xl mt-4 mb-1">Sessions</h1>
|
||||||
<ul>
|
<ul>
|
||||||
{% for session in sessions %}
|
{% for session in sessions %}
|
||||||
<li class="sm:pl-2">{{ session.timestamp_start | date:"d/m/Y" }} ({{ session.device.get_type_display | default:"Unknown" }}, {{ session.duration_formatted }})</li>
|
<li class="sm:pl-2">{{ session.timestamp_start | date:"d/m/Y" }} ({{ session.device.get_type_display | default:"Unknown" }}, {{ session.duration_formatted }})</li>
|
||||||
|
|
|
@ -2,7 +2,6 @@ from datetime import datetime, timedelta
|
||||||
from zoneinfo import ZoneInfo
|
from zoneinfo import ZoneInfo
|
||||||
|
|
||||||
from common.time import now as now_with_tz
|
from common.time import now as now_with_tz
|
||||||
from common.time import format_duration
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.shortcuts import redirect, render
|
from django.shortcuts import redirect, render
|
||||||
|
|
||||||
|
@ -101,12 +100,7 @@ def view_game(request, game_id=None):
|
||||||
context["sessions"] = Session.objects.filter(
|
context["sessions"] = Session.objects.filter(
|
||||||
purchase__edition__game_id=game_id
|
purchase__edition__game_id=game_id
|
||||||
).order_by("-timestamp_start")
|
).order_by("-timestamp_start")
|
||||||
context["total_hours"] = int(
|
context["total_playtime"] = context["sessions"].total_duration()
|
||||||
format_duration(context["sessions"].total_duration_unformatted(), "%H")
|
|
||||||
)
|
|
||||||
context["session_average"] = round(
|
|
||||||
(context["total_hours"]) / int(context["sessions"].count()), 1
|
|
||||||
)
|
|
||||||
# here first and last is flipped
|
# here first and last is flipped
|
||||||
# because sessions are ordered from newest to oldest
|
# because sessions are ordered from newest to oldest
|
||||||
# so the most recent are on top
|
# so the most recent are on top
|
||||||
|
@ -203,7 +197,7 @@ def list_sessions(
|
||||||
session.timestamp_end = datetime.now(ZoneInfo(settings.TIME_ZONE))
|
session.timestamp_end = datetime.now(ZoneInfo(settings.TIME_ZONE))
|
||||||
session.unfinished = True
|
session.unfinished = True
|
||||||
|
|
||||||
context["total_duration"] = dataset.total_duration_formatted()
|
context["total_duration"] = dataset.total_duration()
|
||||||
context["dataset"] = dataset
|
context["dataset"] = dataset
|
||||||
# cannot use dataset[0] here because that might be only partial QuerySet
|
# cannot use dataset[0] here because that might be only partial QuerySet
|
||||||
context["last"] = Session.objects.all().order_by("timestamp_start").last()
|
context["last"] = Session.objects.all().order_by("timestamp_start").last()
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "timetracker"
|
name = "timetracker"
|
||||||
version = "1.1.0"
|
version = "1.0.3"
|
||||||
description = "A simple time tracker."
|
description = "A simple time tracker."
|
||||||
authors = ["Lukáš Kucharczyk <lukas@kucharczyk.xyz>"]
|
authors = ["Lukáš Kucharczyk <lukas@kucharczyk.xyz>"]
|
||||||
license = "GPL"
|
license = "GPL"
|
||||||
|
|
Loading…
Reference in New Issue