diff --git a/vrobbler/apps/scrobbles/models.py b/vrobbler/apps/scrobbles/models.py
index d206900..50b99e4 100644
--- a/vrobbler/apps/scrobbles/models.py
+++ b/vrobbler/apps/scrobbles/models.py
@@ -2,6 +2,7 @@ import calendar
import datetime
import json
import logging
+from collections import defaultdict
from typing import Optional
from uuid import uuid4
@@ -514,6 +515,10 @@ class Scrobble(TimeStampedModel):
MOOD = "Mood", "Mood"
BRICKSET = "BrickSet", "Brick set"
+ @classmethod
+ def list(cls):
+ return list(map(lambda c: c.value, cls))
+
uuid = models.UUIDField(editable=False, **BNULL)
video = models.ForeignKey(Video, on_delete=models.DO_NOTHING, **BNULL)
track = models.ForeignKey(Track, on_delete=models.DO_NOTHING, **BNULL)
@@ -597,6 +602,57 @@ class Scrobble(TimeStampedModel):
long_play_seconds = models.BigIntegerField(**BNULL)
long_play_complete = models.BooleanField(**BNULL)
+ @classmethod
+ def for_year(cls, user, year):
+ return cls.objects.filter(timestamp__year=year, user=user)
+
+ @classmethod
+ def for_month(cls, user, year, month):
+ return cls.objects.filter(
+ timestamp__year=year, timestamp__month=month, user=user
+ )
+
+ @classmethod
+ def for_day(cls, user, year, day, month):
+ return cls.objects.filter(
+ timestamp__year=year,
+ timestamp__month=month,
+ timestamp__day=day,
+ user=user,
+ )
+
+ @classmethod
+ def for_day_dict(
+ cls, user_id: int, year: int, month: int, day: int
+ ) -> dict:
+ scrobbles_by_type = defaultdict(list)
+ scrobbles = cls.objects.filter(
+ timestamp__year=year,
+ timestamp__month=month,
+ timestamp__day=day,
+ user_id=user_id,
+ ).order_by("-timestamp")
+
+ for scrobble in scrobbles:
+ scrobbles_by_type[scrobble.media_type].append(scrobble)
+
+ return scrobbles_by_type
+
+ @classmethod
+ def for_week(cls, user, year, week):
+ return cls.objects.filter(
+ timestamp__year=year, timestamp__week=week, user=user
+ )
+
+ @classmethod
+ def in_progress_for_user(cls, user_id: int) -> models.QuerySet:
+ return cls.objects.filter(
+ user=user_id,
+ in_progress=True,
+ played_to_completion=False,
+ is_paused=False,
+ )
+
@property
def last_serial_scrobble(self) -> Optional["Scrobble"]:
from scrobbles.models import Scrobble
diff --git a/vrobbler/apps/scrobbles/views.py b/vrobbler/apps/scrobbles/views.py
index 3c6434b..0391642 100644
--- a/vrobbler/apps/scrobbles/views.py
+++ b/vrobbler/apps/scrobbles/views.py
@@ -3,9 +3,9 @@ import json
import logging
from datetime import datetime, timedelta
+import pendulum
import pytz
from django.apps import apps
-from django.conf import settings
from django.contrib import messages
from django.contrib.auth.mixins import LoginRequiredMixin
from django.db.models import Count, Q
@@ -52,7 +52,6 @@ from scrobbles.tasks import (
from scrobbles.utils import (
get_long_plays_completed,
get_long_plays_in_progress,
- get_recently_played_board_games,
)
logger = logging.getLogger(__name__)
@@ -107,32 +106,19 @@ class RecentScrobbleList(ListView):
def get_context_data(self, **kwargs):
data = super().get_context_data(**kwargs)
user = self.request.user
+ data["date"] = ""
if user.is_authenticated:
+ date = self.request.GET.get("date", "")
+ today = timezone.localtime(timezone.now())
+ user_id = self.request.user.id
+ year = today.year
+ month = today.month
+ day = today.day
+ if date:
+ year, month, day = date.split("-")
+ data["date"] = pendulum.parse(date)
- completed_for_user = Scrobble.objects.filter(
- played_to_completion=True, user=user
- )
- data["long_play_in_progress"] = get_long_plays_in_progress(user)
- data["play_again"] = get_recently_played_board_games(user)
- data["video_scrobble_list"] = completed_for_user.filter(
- video__isnull=False
- ).order_by("-timestamp")[:15]
-
- data["podcast_scrobble_list"] = completed_for_user.filter(
- podcast_episode__isnull=False
- ).order_by("-timestamp")[:15]
-
- data["sport_scrobble_list"] = completed_for_user.filter(
- sport_event__isnull=False
- ).order_by("-timestamp")[:15]
-
- data["videogame_scrobble_list"] = completed_for_user.filter(
- video_game__isnull=False
- ).order_by("-timestamp")[:15]
-
- data["boardgame_scrobble_list"] = completed_for_user.filter(
- board_game__isnull=False
- ).order_by("-timestamp")[:15]
+ data = data | Scrobble.for_day_dict(user_id, year, month, day)
data["active_imports"] = AudioScrobblerTSVImport.objects.filter(
processing_started__isnull=False,
@@ -698,45 +684,13 @@ class ChartRecordView(TemplateView):
media_type = self.request.GET.get("media", "Track")
user = self.request.user
params = {}
+ context_data["chart_type"] = self.request.GET.get(
+ "chart_type", "maloja"
+ )
context_data["artist_charts"] = {}
if not date:
limit = 20
- artist_params = {"user": user, "media_type": "Artist"}
- context_data["current_artist_charts"] = {
- "today": live_charts(
- **artist_params, chart_period="today", limit=limit
- ),
- "week": live_charts(
- **artist_params, chart_period="week", limit=limit
- ),
- "month": live_charts(
- **artist_params, chart_period="month", limit=limit
- ),
- "year": live_charts(
- **artist_params, chart_period="year", limit=limit
- ),
- "all": live_charts(**artist_params, limit=limit),
- }
-
- track_params = {"user": user, "media_type": "Track"}
- context_data["current_track_charts"] = {
- "today": live_charts(
- **track_params, chart_period="today", limit=limit
- ),
- "week": live_charts(
- **track_params, chart_period="week", limit=limit
- ),
- "month": live_charts(
- **track_params, chart_period="month", limit=limit
- ),
- "year": live_charts(
- **track_params, chart_period="year", limit=limit
- ),
- "all": live_charts(**track_params, limit=limit),
- }
-
- limit = 14
artist = {"user": user, "media_type": "Artist", "limit": limit}
# This is weird. They don't display properly as QuerySets, so we cast to lists
context_data["chart_keys"] = {
diff --git a/vrobbler/templates/scrobbles/_last_scrobbles.html b/vrobbler/templates/scrobbles/_last_scrobbles.html
index 4ea2041..55392c6 100644
--- a/vrobbler/templates/scrobbles/_last_scrobbles.html
+++ b/vrobbler/templates/scrobbles/_last_scrobbles.html
@@ -1,7 +1,6 @@
{% load humanize %}
{% load naturalduration %}
-
Last Scrobbles
Today {{counts.today}} | This Week {{counts.week}} | This Month {{counts.month}} | This Year {{counts.year}} | All Time {{counts.alltime}}
@@ -30,6 +29,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
@@ -46,9 +61,10 @@
- {% for scrobble in object_list %}
+ {{Track|length}}
+ {% for scrobble in Track %}
- | {{scrobble.timestamp|naturaltime}} |
+ {% if scrobble.in_progress %}Listening now{% else %}{{scrobble.timestamp|naturaltime}}{% endif %} |
{% if scrobble.track.album.cover_image %}
 |
{% else %}
@@ -65,7 +81,6 @@
-
Latest watched
@@ -77,9 +92,9 @@
- {% for scrobble in video_scrobble_list %}
+ {% for scrobble in Video %}
- | {{scrobble.timestamp|naturaltime}} |
+ {% if scrobble.in_progress %}Watching now{% else %}{{scrobble.timestamp|naturaltime}}{% endif %} |
{% if scrobble.video.cover_image %}
 |
{% else %}
@@ -105,15 +120,17 @@
Title |
Round |
League |
+ Time watched |
- {% for scrobble in sport_scrobble_list %}
+ {% for scrobble in SportEvent %}
- | {{scrobble.timestamp|naturaltime}} |
+ {% if scrobble.in_progress %}Watching now{% else %}{{scrobble.timestamp|naturaltime}}{% endif %} |
{{scrobble.sport_event.title}} |
{{scrobble.sport_event.round.name}} |
{{scrobble.sport_event.round.season.league}} |
+ {{scrobble.playback_position_seconds|natural_duration}} |
{% endfor %}
@@ -123,7 +140,6 @@
-
Latest Podcasted
@@ -134,8 +150,9 @@
- {% for scrobble in podcast_scrobble_list %}
+ {% for scrobble in PodcastEpisode %}
+ | {% if scrobble.in_progress %}Listening now{% else %}{{scrobble.timestamp|naturaltime}}{% endif %} |
{{scrobble.timestamp|naturaltime}} |
{{scrobble.podcast_episode.title}} |
{{scrobble.podcast_episode.podcast}} |
@@ -148,7 +165,6 @@
-
Latest Video Games
@@ -156,14 +172,14 @@
| Date |
Cover/Screenshot |
Title |
- Time played (mins) |
+ Time played |
Percent complete |
- {% for scrobble in videogame_scrobble_list %}
+ {% for scrobble in VideoGame %}
- | {{scrobble.timestamp|naturaltime}} |
+ {% if scrobble.in_progress %}Sessioning now{% else %}{{scrobble.timestamp|naturaltime}}{% endif %} |
{% if scrobble.screenshot %}
 |
{% else %}
@@ -184,7 +200,6 @@
-
Latest Board Games
@@ -192,13 +207,13 @@
| Date |
Cover |
Title |
- Time played (mins) |
+ Time played |
- {% for scrobble in boardgame_scrobble_list %}
+ {% for scrobble in BoardGame %}
- | {{scrobble.timestamp|naturaltime}} |
+ {% if scrobble.in_progress %}Tabling now{% else %}{{scrobble.timestamp|naturaltime}}{% endif %} |
 |
{{scrobble.media_obj.title}} |
{{scrobble.playback_position_seconds|natural_duration}} |
@@ -208,5 +223,108 @@
+
+
+
+
+
+
+ | Date |
+ Cover |
+ Title |
+ Time browsing |
+
+
+
+ {% for scrobble in WebPage %}
+
+ | {% if scrobble.in_progress %}Browsing now{% else %}{{scrobble.timestamp|naturaltime}}{% endif %} |
+  |
+ {{scrobble.media_obj.title}} |
+ {{scrobble.playback_position_seconds|natural_duration}} |
+
+ {% endfor %}
+
+
+
+
+
+
+
+
+
+
+ | Date |
+ Cover |
+ Title |
+ Time drinking |
+
+
+
+ {% for scrobble in Beer %}
+
+ | {% if scrobble.in_progress %}Drinking now{% else %}{{scrobble.timestamp|naturaltime}}{% endif %} |
+  |
+ {{scrobble.media_obj.title}} |
+ {{scrobble.playback_position_seconds|natural_duration}} |
+
+ {% endfor %}
+
+
+
+
+
+
+
+
+
+
+ | Date |
+ Cover |
+ Title |
+ Time reading |
+
+
+
+ {% for scrobble in Book %}
+
+ | {% if scrobble.in_progress %}Reading now{% else %}{{scrobble.timestamp|naturaltime}}{% endif %} |
+  |
+ {{scrobble.media_obj.title}} |
+ {{scrobble.playback_position_seconds|natural_duration}} |
+
+ {% endfor %}
+
+
+
+
+
+
+
+
+
+
+ | Date |
+ Title |
+ Time doing |
+
+
+
+ {% for scrobble in Task %}
+
+ | {% if scrobble.in_progress %}Doing now{% else %}{{scrobble.timestamp|naturaltime}}{% endif %} |
+ {{scrobble.media_obj.title}} |
+ {{scrobble.playback_position_seconds|natural_duration}} |
+
+ {% endfor %}
+
+
+
+
+