[scrobbles] Add total time to tag views
This commit is contained in:
@ -14,7 +14,7 @@ from django.contrib import messages
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator
|
||||
from django.db.models import Count, Max, Q
|
||||
from django.db.models import Count, Max, Q, Sum
|
||||
from django.db.models.query import QuerySet
|
||||
from rest_framework.authentication import TokenAuthentication
|
||||
from rest_framework.authtoken.models import Token
|
||||
@ -367,6 +367,7 @@ class ScrobbleListView(LoginRequiredMixin, ListView):
|
||||
else:
|
||||
tag_list = []
|
||||
self.tag_list = tag_list
|
||||
self._full_queryset = qs
|
||||
return qs
|
||||
|
||||
def _compute_overlap_groups(self, scrobbles):
|
||||
@ -433,6 +434,13 @@ class ScrobbleListView(LoginRequiredMixin, ListView):
|
||||
ctx["tag_list"] = getattr(self, "tag_list", [])
|
||||
scrobbles = list(ctx.get("object_list", []))
|
||||
ctx["overlap_map"] = self._compute_overlap_groups(scrobbles)
|
||||
full_qs = getattr(self, "_full_queryset", None)
|
||||
if full_qs is not None and getattr(self, "tag_list", []):
|
||||
total = (
|
||||
full_qs.aggregate(total=Sum("playback_position_seconds"))["total"]
|
||||
or 0
|
||||
)
|
||||
ctx["total_time_seconds"] = total
|
||||
return ctx
|
||||
|
||||
|
||||
|
||||
@ -8,21 +8,20 @@ def natural_duration(value):
|
||||
if not value:
|
||||
return
|
||||
value = int(value)
|
||||
total_minutes = int(value / 60)
|
||||
hours = int(total_minutes / 60)
|
||||
minutes = total_minutes - (hours * 60)
|
||||
seconds = value % 60
|
||||
value_str = ""
|
||||
if seconds:
|
||||
value_str = f"{seconds} seconds"
|
||||
if minutes:
|
||||
if value_str:
|
||||
value_str = f"{minutes} minutes, " + value_str
|
||||
else:
|
||||
value_str = f"{minutes} minutes"
|
||||
days = int(value / 86400)
|
||||
remainder = value % 86400
|
||||
hours = int(remainder / 3600)
|
||||
minutes = int((remainder % 3600) / 60)
|
||||
seconds = remainder % 60
|
||||
parts = []
|
||||
if days:
|
||||
parts.append(f"{days} day{'s' if days != 1 else ''}")
|
||||
if hours:
|
||||
if value_str:
|
||||
value_str = f"{hours} hours, " + value_str
|
||||
else:
|
||||
value_str = f"{hours} hours"
|
||||
return value_str
|
||||
parts.append(f"{hours} hour{'s' if hours != 1 else ''}")
|
||||
if minutes:
|
||||
parts.append(f"{minutes} minute{'s' if minutes != 1 else ''}")
|
||||
if seconds or not parts:
|
||||
parts.append(f"{seconds} second{'s' if seconds != 1 else ''}")
|
||||
if len(parts) == 1:
|
||||
return parts[0]
|
||||
return ", ".join(parts[:-1]) + " and " + parts[-1]
|
||||
|
||||
@ -9,6 +9,9 @@
|
||||
<h1 class="h2">All Scrobbles</h1>
|
||||
{% if tag_list %}
|
||||
<h6 class="text-muted">Tagged {{ tag_list|join:", " }}</h6>
|
||||
{% if total_time_seconds %}
|
||||
<p class="text-muted small mb-0">Total time: {{ total_time_seconds|natural_duration }}</p>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user