Sfoglia il codice sorgente

[templates] Start redesigning the dashboard

Colin Powell 1 mese fa
parent
commit
2a254e28d0

+ 56 - 0
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

+ 16 - 62
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:
-
-            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]
+            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)
+
+            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"] = {

+ 136 - 18
vrobbler/templates/scrobbles/_last_scrobbles.html

@@ -1,7 +1,6 @@
 {% load humanize %}
 {% load naturalduration %}
 <div>
-    <h2>Last Scrobbles</h2>
     <p>Today <b>{{counts.today}}</b> | This Week <b>{{counts.week}}</b> | This Month <b>{{counts.month}}</b> | This Year <b>{{counts.year}}</b> | All Time <b>{{counts.alltime}}</b></p>
 </div>
 <div class="row">
@@ -30,6 +29,22 @@
             <button class="nav-link" id="profile-tab" data-bs-toggle="tab" data-bs-target="#latest-boardgames"
                 type="button" role="tab" aria-controls="profile" aria-selected="false">Board Games</button>
         </li>
+        <li class="nav-item" role="presentation">
+            <button class="nav-link" id="profile-tab" data-bs-toggle="tab" data-bs-target="#latest-webpages"
+                type="button" role="tab" aria-controls="profile" aria-selected="false">Web Pages</button>
+        </li>
+        <li class="nav-item" role="presentation">
+            <button class="nav-link" id="profile-tab" data-bs-toggle="tab" data-bs-target="#latest-beers"
+                type="button" role="tab" aria-controls="profile" aria-selected="false">Beers</button>
+        </li>
+        <li class="nav-item" role="presentation">
+            <button class="nav-link" id="profile-tab" data-bs-toggle="tab" data-bs-target="#latest-books"
+                type="button" role="tab" aria-controls="profile" aria-selected="false">Books</button>
+        </li>
+        <li class="nav-item" role="presentation">
+            <button class="nav-link" id="profile-tab" data-bs-toggle="tab" data-bs-target="#latest-tasks"
+                type="button" role="tab" aria-controls="profile" aria-selected="false">Tasks</button>
+        </li>
     </ul>
 
     <div class="tab-content" id="myTabContent2">
@@ -46,9 +61,10 @@
                         </tr>
                     </thead>
                     <tbody>
-                        {% for scrobble in object_list %}
+                        {{Track|length}}
+                        {% for scrobble in Track %}
                         <tr>
-                            <td>{{scrobble.timestamp|naturaltime}}</td>
+                            <td>{% if scrobble.in_progress %}Listening now{% else %}{{scrobble.timestamp|naturaltime}}{% endif %}</td>
                             {% if scrobble.track.album.cover_image %}
                             <td><a href="{{scrobble.track.album.get_absolute_url}}"><img src="{{scrobble.track.album.cover_image_small.url}}" width=25 height=25 style="border:1px solid black;" /></aa></td>
                             {% else %}
@@ -65,7 +81,6 @@
 
         <div class="tab-pane fade show" id="latest-watched" role="tabpanel"
             aria-labelledby="latest-watched-tab">
-            <h2>Latest watched</h2>
             <div class="table-responsive">
                 <table class="table table-striped table-sm">
                     <thead>
@@ -77,9 +92,9 @@
                         </tr>
                     </thead>
                     <tbody>
-                        {% for scrobble in video_scrobble_list %}
+                        {% for scrobble in Video %}
                         <tr>
-                            <td>{{scrobble.timestamp|naturaltime}}</td>
+                            <td>{% if scrobble.in_progress %}Watching now{% else %}{{scrobble.timestamp|naturaltime}}{% endif %}</td>
                             {% if scrobble.video.cover_image %}
                             <td><img src="{{scrobble.media_obj.cover_image_medium.url}}" width=25 height=25 style="border:1px solid black;" /></td>
                             {% else %}
@@ -105,15 +120,17 @@
                             <th scope="col">Title</th>
                             <th scope="col">Round</th>
                             <th scope="col">League</th>
+                            <th scope="col">Time watched</th>
                         </tr>
                     </thead>
                     <tbody>
-                        {% for scrobble in sport_scrobble_list %}
+                        {% for scrobble in SportEvent %}
                         <tr>
-                            <td>{{scrobble.timestamp|naturaltime}}</td>
+                            <td>{% if scrobble.in_progress %}Watching now{% else %}{{scrobble.timestamp|naturaltime}}{% endif %}</td>
                             <td>{{scrobble.sport_event.title}}</td>
                             <td>{{scrobble.sport_event.round.name}}</td>
                             <td>{{scrobble.sport_event.round.season.league}}</td>
+                            <td>{{scrobble.playback_position_seconds|natural_duration}}</td>
                         </tr>
                         {% endfor %}
                     </tbody>
@@ -123,7 +140,6 @@
 
         <div class="tab-pane fade show" id="latest-podcasted" role="tabpanel"
             aria-labelledby="latest-podcasted-tab">
-            <h2>Latest Podcasted</h2>
             <div class="table-responsive">
                 <table class="table table-striped table-sm">
                     <thead>
@@ -134,8 +150,9 @@
                         </tr>
                     </thead>
                     <tbody>
-                        {% for scrobble in podcast_scrobble_list %}
+                        {% for scrobble in PodcastEpisode %}
                         <tr>
+                            <td>{% if scrobble.in_progress %}Listening now{% else %}{{scrobble.timestamp|naturaltime}}{% endif %}</td>
                             <td>{{scrobble.timestamp|naturaltime}}</td>
                             <td>{{scrobble.podcast_episode.title}}</td>
                             <td>{{scrobble.podcast_episode.podcast}}</td>
@@ -148,7 +165,6 @@
 
         <div class="tab-pane fade show" id="latest-videogames" role="tabpanel"
             aria-labelledby="latest-videogames-tab">
-            <h2>Latest Video Games</h2>
             <div class="table-responsive">
                 <table class="table table-striped table-sm">
                     <thead>
@@ -156,14 +172,14 @@
                             <th scope="col">Date</th>
                             <th scope="col">Cover/Screenshot</th>
                             <th scope="col">Title</th>
-                            <th scope="col">Time played (mins)</th>
+                            <th scope="col">Time played</th>
                             <th scope="col">Percent complete</th>
                         </tr>
                     </thead>
                     <tbody>
-                        {% for scrobble in videogame_scrobble_list %}
+                        {% for scrobble in VideoGame %}
                         <tr>
-                            <td>{{scrobble.timestamp|naturaltime}}</td>
+                            <td>{% if scrobble.in_progress %}Sessioning now{% else %}{{scrobble.timestamp|naturaltime}}{% endif %}</td>
                             {% if scrobble.screenshot %}
                             <td><img src="{{scrobble.screenshot_medium.url}}" width=25 height=25 style="border:1px solid black;" /></td>
                             {% else %}
@@ -184,7 +200,6 @@
 
         <div class="tab-pane fade show" id="latest-boardgames" role="tabpanel"
             aria-labelledby="latest-boardgames-tab">
-            <h2>Latest Board Games</h2>
             <div class="table-responsive">
                 <table class="table table-striped table-sm">
                     <thead>
@@ -192,13 +207,65 @@
                             <th scope="col">Date</th>
                             <th scope="col">Cover</th>
                             <th scope="col">Title</th>
-                            <th scope="col">Time played (mins)</th>
+                            <th scope="col">Time played</th>
                         </tr>
                     </thead>
                     <tbody>
-                        {% for scrobble in boardgame_scrobble_list %}
+                        {% for scrobble in BoardGame %}
                         <tr>
-                            <td>{{scrobble.timestamp|naturaltime}}</td>
+                            <td>{% if scrobble.in_progress %}Tabling now{% else %}{{scrobble.timestamp|naturaltime}}{% endif %}</td>
+                            <td><img src="{{scrobble.media_obj.cover_medium.url}}" width=25 height=25 style="border:1px solid black;" /></td>
+                            <td><a href="{{scrobble.media_obj.get_absolute_url}}">{{scrobble.media_obj.title}}</a></td>
+                            <td>{{scrobble.playback_position_seconds|natural_duration}}</td>
+                        </tr>
+                        {% endfor %}
+                    </tbody>
+                </table>
+            </div>
+        </div>
+
+        <div class="tab-pane fade show" id="latest-webpages" role="tabpanel"
+            aria-labelledby="latest-webpages-tab">
+            <div class="table-responsive">
+                <table class="table table-striped table-sm">
+                    <thead>
+                        <tr>
+                            <th scope="col">Date</th>
+                            <th scope="col">Cover</th>
+                            <th scope="col">Title</th>
+                            <th scope="col">Time browsing</th>
+                        </tr>
+                    </thead>
+                    <tbody>
+                        {% for scrobble in WebPage %}
+                        <tr>
+                            <td>{% if scrobble.in_progress %}Browsing now{% else %}{{scrobble.timestamp|naturaltime}}{% endif %}</td>
+                            <td><img src="{{scrobble.media_obj.cover_medium.url}}" width=25 height=25 style="border:1px solid black;" /></td>
+                            <td><a href="{{scrobble.media_obj.get_absolute_url}}">{{scrobble.media_obj.title}}</a></td>
+                            <td>{{scrobble.playback_position_seconds|natural_duration}}</td>
+                        </tr>
+                        {% endfor %}
+                    </tbody>
+                </table>
+            </div>
+        </div>
+
+        <div class="tab-pane fade show" id="latest-beers" role="tabpanel"
+            aria-labelledby="latest-beers-tab">
+            <div class="table-responsive">
+                <table class="table table-striped table-sm">
+                    <thead>
+                        <tr>
+                            <th scope="col">Date</th>
+                            <th scope="col">Cover</th>
+                            <th scope="col">Title</th>
+                            <th scope="col">Time drinking</th>
+                        </tr>
+                    </thead>
+                    <tbody>
+                        {% for scrobble in Beer %}
+                        <tr>
+                            <td>{% if scrobble.in_progress %}Drinking now{% else %}{{scrobble.timestamp|naturaltime}}{% endif %}</td>
                             <td><img src="{{scrobble.media_obj.cover_medium.url}}" width=25 height=25 style="border:1px solid black;" /></td>
                             <td><a href="{{scrobble.media_obj.get_absolute_url}}">{{scrobble.media_obj.title}}</a></td>
                             <td>{{scrobble.playback_position_seconds|natural_duration}}</td>
@@ -208,5 +275,56 @@
                 </table>
             </div>
         </div>
+
+        <div class="tab-pane fade show" id="latest-books" role="tabpanel"
+            aria-labelledby="latest-books-tab">
+            <div class="table-responsive">
+                <table class="table table-striped table-sm">
+                    <thead>
+                        <tr>
+                            <th scope="col">Date</th>
+                            <th scope="col">Cover</th>
+                            <th scope="col">Title</th>
+                            <th scope="col">Time reading</th>
+                        </tr>
+                    </thead>
+                    <tbody>
+                        {% for scrobble in Book %}
+                        <tr>
+                            <td>{% if scrobble.in_progress %}Reading now{% else %}{{scrobble.timestamp|naturaltime}}{% endif %}</td>
+                            <td><img src="{scrobble.media_obj.cover_medium.url}}" width=25 height=25 style="border:1px solid black;" /></td>
+                            <td><a href="{{scrobble.media_obj.get_absolute_url}}">{{scrobble.media_obj.title}}</a></td>
+                            <td>{{scrobble.playback_position_seconds|natural_duration}}</td>
+                        </tr>
+                        {% endfor %}
+                    </tbody>
+                </table>
+            </div>
+        </div>
+
+        <div class="tab-pane fade show" id="latest-tasks" role="tabpanel"
+            aria-labelledby="latest-tasks-tab">
+            <div class="table-responsive">
+                <table class="table table-striped table-sm">
+                    <thead>
+                        <tr>
+                            <th scope="col">Date</th>
+                            <th scope="col">Title</th>
+                            <th scope="col">Time doing</th>
+                        </tr>
+                    </thead>
+                    <tbody>
+                        {% for scrobble in Task %}
+                        <tr>
+                            <td>{% if scrobble.in_progress %}Doing now{% else %}{{scrobble.timestamp|naturaltime}}{% endif %}</td>
+                            <td><a href="{{scrobble.media_obj.get_absolute_url}}">{{scrobble.media_obj.title}}</a></td>
+                            <td>{{scrobble.playback_position_seconds|natural_duration}}</td>
+                        </tr>
+                        {% endfor %}
+                    </tbody>
+                </table>
+            </div>
+        </div>
+
     </div>
 </div>