[templates] Allow going back and forward in time
This commit is contained in:
@ -604,45 +604,39 @@ class Scrobble(TimeStampedModel):
|
||||
|
||||
@classmethod
|
||||
def for_year(cls, user, year):
|
||||
return cls.objects.filter(timestamp__year=year, user=user)
|
||||
return cls.objects.filter(timestamp__year=year, user=user).order_by(
|
||||
"-timestamp"
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def for_month(cls, user, year, month):
|
||||
return cls.objects.filter(
|
||||
timestamp__year=year, timestamp__month=month, user=user
|
||||
)
|
||||
).order_by("-timestamp")
|
||||
|
||||
@classmethod
|
||||
def for_day(cls, user, year, day, month):
|
||||
def for_day(cls, user, year, month, day):
|
||||
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
|
||||
)
|
||||
).order_by("-timestamp")
|
||||
|
||||
@classmethod
|
||||
def as_dict_by_type(cls, scrobble_qs: models.QuerySet) -> dict:
|
||||
scrobbles_by_type = defaultdict(list)
|
||||
|
||||
for scrobble in scrobble_qs:
|
||||
scrobbles_by_type[scrobble.media_type].append(scrobble)
|
||||
|
||||
return scrobbles_by_type
|
||||
|
||||
@classmethod
|
||||
def in_progress_for_user(cls, user_id: int) -> models.QuerySet:
|
||||
@ -847,7 +841,10 @@ class Scrobble(TimeStampedModel):
|
||||
@property
|
||||
def elapsed_time(self) -> int | None:
|
||||
if self.played_to_completion:
|
||||
return self.playback_position_seconds
|
||||
if self.playback_position_seconds:
|
||||
return self.playback_position_seconds
|
||||
if self.media_obj.run_time_seconds:
|
||||
return self.media_obj.run_time_seconds
|
||||
return (timezone.now() - self.timestamp).seconds
|
||||
|
||||
@property
|
||||
|
||||
@ -2,9 +2,9 @@ import calendar
|
||||
import json
|
||||
import logging
|
||||
from datetime import datetime, timedelta
|
||||
from dateutil.relativedelta import relativedelta
|
||||
|
||||
import pendulum
|
||||
from pendulum.parsing.exceptions import ParserError
|
||||
import pytz
|
||||
from django.apps import apps
|
||||
from django.contrib import messages
|
||||
@ -109,20 +109,92 @@ class RecentScrobbleList(ListView):
|
||||
user = self.request.user
|
||||
data["date"] = ""
|
||||
if user.is_authenticated:
|
||||
date = self.request.GET.get("date", "")
|
||||
today = timezone.localtime(timezone.now())
|
||||
self.queryset = self.get_queryset().filter(user=user)
|
||||
user_id = self.request.user.id
|
||||
year = today.year
|
||||
month = today.month
|
||||
day = today.day
|
||||
if date:
|
||||
|
||||
today = timezone.localtime(timezone.now())
|
||||
date_str = self.request.GET.get("date", "")
|
||||
date = today
|
||||
if date_str:
|
||||
try:
|
||||
data["date"] = pendulum.parse(date)
|
||||
year, month, day = date.split("-")
|
||||
date = pendulum.parse(date_str)
|
||||
except:
|
||||
pass
|
||||
|
||||
data = data | Scrobble.for_day_dict(user_id, year, month, day)
|
||||
if date_str:
|
||||
if date_str == "this_week" or "-W" in date_str:
|
||||
next_date = date + timedelta(weeks=+2)
|
||||
prev_date = date + timedelta(weeks=-1)
|
||||
if date.isocalendar()[1] < today.isocalendar()[1]:
|
||||
data[
|
||||
"next_link"
|
||||
] = f"?date={next_date.strftime('%Y-W%W')}"
|
||||
data["prev_link"] = f"?date={prev_date.strftime('%Y-W%W')}"
|
||||
data[
|
||||
"title"
|
||||
] = f"Week {date.strftime('%-W')} of {date.year}"
|
||||
data = data | Scrobble.as_dict_by_type(
|
||||
Scrobble.for_week(
|
||||
user_id, date.year, date.isocalendar()[1]
|
||||
)
|
||||
)
|
||||
elif date_str == "this_month" or date_str.count("-") == 1:
|
||||
next_date = date + relativedelta(months=1)
|
||||
prev_date = date + relativedelta(months=-1)
|
||||
if date.month < today.month:
|
||||
data[
|
||||
"next_link"
|
||||
] = f"?date={next_date.strftime('%Y-%m')}"
|
||||
data["title"] = f"{date.strftime('%B %Y')}"
|
||||
data["prev_link"] = f"?date={prev_date.strftime('%Y-%m')}"
|
||||
data = data | Scrobble.as_dict_by_type(
|
||||
Scrobble.for_month(user_id, date.year, date.month)
|
||||
)
|
||||
elif date_str == "today" or date_str.count("-") == 2:
|
||||
next_date = date + timedelta(days=1)
|
||||
prev_date = date - timedelta(days=1)
|
||||
data[
|
||||
"prev_link"
|
||||
] = f"?date={prev_date.strftime('%Y-%m-%d')}"
|
||||
if date < today:
|
||||
data[
|
||||
"next_link"
|
||||
] = f"?date={next_date.strftime('%Y-%m-%d')}"
|
||||
if date == today:
|
||||
data["title"] = "Today"
|
||||
else:
|
||||
data["title"] = f"{date.strftime('%Y-%m-%d')}"
|
||||
data[
|
||||
"today_link"
|
||||
] = f"?date={today.strftime('%Y-%m-%d')}"
|
||||
data = data | Scrobble.as_dict_by_type(
|
||||
Scrobble.for_day(
|
||||
user_id, date.year, date.month, date.day
|
||||
)
|
||||
)
|
||||
elif date_str == "this_year" or date_str.count("-") == 0:
|
||||
next_date = date + relativedelta(years=+1)
|
||||
prev_date = date + relativedelta(years=-1)
|
||||
data["next_link"] = ""
|
||||
if date.year < today.year:
|
||||
data["title"] = f"{date.strftime('%Y')}"
|
||||
data["next_link"] = f"?date={next_date.year}"
|
||||
data["title"] = f"{date.year}"
|
||||
data["prev_link"] = f"?date={prev_date.year}"
|
||||
data = data | Scrobble.as_dict_by_type(
|
||||
Scrobble.for_year(user_id, date.year)
|
||||
)
|
||||
else:
|
||||
next_date = today - timedelta(days=1)
|
||||
prev_date = today - timedelta(days=1)
|
||||
data["title"] = "Today"
|
||||
data["next_link"] = ""
|
||||
data["prev_link"] = f"?date={prev_date.strftime('%Y-%m-%d')}"
|
||||
data = data | Scrobble.as_dict_by_type(
|
||||
Scrobble.for_day(user_id, date.year, date.month, date.day)
|
||||
)
|
||||
data[
|
||||
"today_link"
|
||||
] = "" # f"?date={today.strftime('%Y-%m-%d')}"
|
||||
|
||||
data["active_imports"] = AudioScrobblerTSVImport.objects.filter(
|
||||
processing_started__isnull=False,
|
||||
@ -139,9 +211,7 @@ class RecentScrobbleList(ListView):
|
||||
return data
|
||||
|
||||
def get_queryset(self):
|
||||
return Scrobble.objects.filter(
|
||||
track__isnull=False, in_progress=False
|
||||
).order_by("-timestamp")[:15]
|
||||
return Scrobble.objects.all().order_by("-timestamp")
|
||||
|
||||
|
||||
class ScrobbleLongPlaysView(TemplateView):
|
||||
@ -453,6 +523,7 @@ def gps_webhook(request):
|
||||
|
||||
return Response({"scrobble_id": scrobble.id}, status=status.HTTP_200_OK)
|
||||
|
||||
|
||||
@csrf_exempt
|
||||
@api_view(["POST"])
|
||||
def emacs_webhook(request):
|
||||
@ -474,9 +545,9 @@ def emacs_webhook(request):
|
||||
if request.user.id:
|
||||
user_id = request.user.id
|
||||
|
||||
#scrobble = gpslogger_scrobble_location(data_dict, user_id)
|
||||
# scrobble = gpslogger_scrobble_location(data_dict, user_id)
|
||||
|
||||
#if not scrobble:
|
||||
# if not scrobble:
|
||||
# return Response({}, status=status.HTTP_200_OK)
|
||||
|
||||
return Response({"post_data": post_data}, status=status.HTTP_200_OK)
|
||||
|
||||
@ -1,305 +1,82 @@
|
||||
{% load humanize %}
|
||||
{% load naturalduration %}
|
||||
<div>
|
||||
<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 class="row">
|
||||
<div>
|
||||
<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>
|
||||
<div class="row">
|
||||
|
||||
<div class="col-md">
|
||||
{% if Track %}
|
||||
<div class="ab-pane fade show active" id="latest-listened" role="tabpanel"
|
||||
aria-labelledby="latest-listened-tab">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped table-sm">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Time</th>
|
||||
<th scope="col">Album</th>
|
||||
<th scope="col">Track</th>
|
||||
<th scope="col">Artist</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{Track|length}}
|
||||
{% for scrobble in Track %}
|
||||
<tr>
|
||||
<td>{% if scrobble.in_progress %}{{scrobble.media_obj.strings.verb}} now | <a class="right" href="{% url "scrobbles:finish" scrobble.uuid %}">Finish</a>{% 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 %}
|
||||
<td><a href="{{scrobble.track.album.get_absolute_url}}">{{scrobble.track.album.name}}</a></td>
|
||||
{% endif %}
|
||||
<td><a href="{{scrobble.track.get_absolute_url }}">{{scrobble.track.title}}</a></td>
|
||||
<td><a href="{{scrobble.track.artist.get_absolute_url }}">{{scrobble.track.artist.name}}</aa></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<h2>Music</h2>
|
||||
{% with scrobbles=Track %}
|
||||
{% include "scrobbles/_scrobble_table.html" %}
|
||||
{% endwith %}
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="col-md">
|
||||
|
||||
{% if Task %}
|
||||
<h2>Latest tasks</h2>
|
||||
{% with scrobbles=Task %}
|
||||
{% include "scrobbles/_scrobble_table.html" %}
|
||||
{% endwith %}
|
||||
{% endif %}
|
||||
|
||||
{% if Video %}
|
||||
<div class="tab-pane fade show" id="latest-watched" role="tabpanel"
|
||||
aria-labelledby="latest-watched-tab">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped table-sm">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Time</th>
|
||||
<th scope="col">Cover</th>
|
||||
<th scope="col">Title</th>
|
||||
<th scope="col">Series</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for scrobble in Video %}
|
||||
<tr>
|
||||
<td>{% if scrobble.in_progress %}{{scrobble.media_obj.strings.verb}} now | <a class="right" href="{% url "scrobbles:finish" scrobble.uuid %}">Finish</a>{% 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 %}
|
||||
<td></td>
|
||||
{% endif %}
|
||||
<td><a href="{{scrobble.video.get_absolute_url }}">{% if scrobble.video.tv_series%}S{{scrobble.video.season_number}}E{{scrobble.video.episode_number}} -{%endif %} {{scrobble.video.title}}</a></td>
|
||||
<td><a href="{{scrobble.video.tv_series.get_absolute_url }}">{% if scrobble.video.tv_series %}{{scrobble.video.tv_series}}</a>{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if SportEvent %}
|
||||
<div class="tab-pane fade show" id="latest-sports" role="tabpanel" aria-labelledby="latest-sports-tab">
|
||||
<h2>Latest Sports</h2>
|
||||
<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">Round</th>
|
||||
<th scope="col">League</th>
|
||||
<th scope="col">Time watched</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for scrobble in SportEvent %}
|
||||
<tr>
|
||||
<td>{% if scrobble.in_progress %}{{scrobble.media_obj.strings.verb}} now | <a class="right" href="{% url "scrobbles:finish" scrobble.uuid %}">Finish</a>{% 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.elapsed_time|natural_duration}}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if PodcastEpisode %}
|
||||
<div class="tab-pane fade show" id="latest-podcasted" role="tabpanel"
|
||||
aria-labelledby="latest-podcasted-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">Podcast</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for scrobble in PodcastEpisode %}
|
||||
<tr>
|
||||
<td>{% if scrobble.in_progress %}{{scrobble.media_obj.strings.verb}} now | <a class="right" href="{% url "scrobbles:finish" scrobble.uuid %}">Finish</a>{% else %}{{scrobble.timestamp|naturaltime}}{% endif %}</td>
|
||||
<td>{{scrobble.timestamp|naturaltime}}</td>
|
||||
<td>{{scrobble.podcast_episode.title}}</td>
|
||||
<td>{{scrobble.podcast_episode.podcast}}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if VideoGame %}
|
||||
<h4>Video games</h4>
|
||||
<div class="tab-pane fade show" id="latest-videogames" role="tabpanel"
|
||||
aria-labelledby="latest-videogames-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 played</th>
|
||||
<th scope="col">Percent complete</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for scrobble in VideoGame %}
|
||||
<tr>
|
||||
<td>{% if scrobble.in_progress %}{{scrobble.media_obj.strings.verb}} now | <a class="right" href="{% url "scrobbles:finish" scrobble.uuid %}">Finish</a>{% else %}{{scrobble.timestamp|naturaltime}}{% endif %}</td>
|
||||
{% if scrobble.media_obj.hltb_cover %}
|
||||
<td><img src="{{scrobble.media_obj.hltb_cover_medium.url}}" width=25 height=25 style="border:1px solid black;" /></td>
|
||||
{% endif %}
|
||||
<td><a href="{{scrobble.media_obj.get_absolute_url}}">{{scrobble.media_obj.title}}</a></td>
|
||||
<td>{{scrobble.elapsed_time|natural_duration}}</td>
|
||||
<td>{{scrobble.percent_played}}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% if BoardGame %}
|
||||
<h4>Board games</h4>
|
||||
<div class="tab-pane fade show" id="latest-boardgames" role="tabpanel"
|
||||
aria-labelledby="latest-boardgames-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 played</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for scrobble in BoardGame %}
|
||||
<tr>
|
||||
<td>{% if scrobble.in_progress %}{{scrobble.media_obj.strings.verb}} now | <a class="right" href="{% url "scrobbles:finish" scrobble.uuid %}">Finish</a>{% 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.elapsed_time|natural_duration}}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<h2>Videos</h2>
|
||||
{% with scrobbles=Video %}
|
||||
{% include "scrobbles/_scrobble_table.html" %}
|
||||
{% endwith %}
|
||||
{% endif %}
|
||||
|
||||
{% if WebPage %}
|
||||
<h4>Web pages</h4>
|
||||
<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">Title</th>
|
||||
<th scope="col">Time browsing</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for scrobble in WebPage %}
|
||||
<tr>
|
||||
<td>{% if scrobble.in_progress %}{{scrobble.media_obj.strings.verb}} now | <a class="right" href="{% url "scrobbles:finish" scrobble.uuid %}">Finish</a>{% else %}{{scrobble.timestamp|naturaltime}}{% endif %}</td>
|
||||
<td><a href="{{scrobble.media_obj.get_absolute_url}}">{{scrobble.media_obj.title}}</a></td>
|
||||
<td>{{scrobble.elapsed_time|natural_duration}}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
{% with scrobbles=WebPage %}
|
||||
{% include "scrobbles/_scrobble_table.html" %}
|
||||
{% endwith %}
|
||||
{% endif %}
|
||||
|
||||
{% if SportEvent %}
|
||||
<h2>Sports</h2>
|
||||
{% with scrobbles=SportEvent %}
|
||||
{% include "scrobbles/_scrobble_table.html" %}
|
||||
{% endwith %}
|
||||
{% endif %}
|
||||
|
||||
{% if PodcastEpisode %}
|
||||
<h2>Latest podcasts</h2>
|
||||
{% with scrobbles=PodcastEpisode %}
|
||||
{% include "scrobbles/_scrobble_table.html" %}
|
||||
{% endwith %}
|
||||
{% endif %}
|
||||
|
||||
{% if VideoGame %}
|
||||
<h4>Video games</h4>
|
||||
{% with scrobbles=VideoGame %}
|
||||
{% include "scrobbles/_scrobble_table.html" %}
|
||||
{% endwith %}
|
||||
{% endif %}
|
||||
|
||||
{% if BoardGame %}
|
||||
<h4>Board games</h4>
|
||||
{% with scrobbles=BoardGame %}
|
||||
{% include "scrobbles/_scrobble_table.html" %}
|
||||
{% endwith %}
|
||||
{% endif %}
|
||||
|
||||
{% if Beer %}
|
||||
<h4>Beers</h4>
|
||||
<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 %}{{scrobble.media_obj.strings.verb}} now | <a class="right" href="{% url "scrobbles:finish" scrobble.uuid %}">Finish</a>{% 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.elapsed_time|natural_duration}}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
{% with scrobbles=Beer %}
|
||||
{% include "scrobbles/_scrobble_table.html" %}
|
||||
{% endwith %}
|
||||
{% endif %}
|
||||
|
||||
{% if Book %}
|
||||
<h4>Books</h4>
|
||||
<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 %}{{scrobble.media_obj.strings.verb}} now | <a class="right" href="{% url "scrobbles:finish" scrobble.uuid %}">Finish</a>{% 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.elapsed_time|natural_duration}}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if Task %}
|
||||
<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 %}{{scrobble.media_obj.strings.verb}} now | <a class="right" href="{% url "scrobbles:finish" scrobble.uuid %}">Finish</a>{% else %}{{scrobble.timestamp|naturaltime}}{% endif %}</td>
|
||||
<td><a href="{{scrobble.media_obj.get_absolute_url}}">{{scrobble.media_obj.title}}</a></td>
|
||||
<td>{{scrobble.elapsed_time|natural_duration}}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
{% with scrobbles=Book %}
|
||||
{% include "scrobbles/_scrobble_table.html" %}
|
||||
{% endwith %}
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
|
||||
7
vrobbler/templates/scrobbles/_row.html
Normal file
7
vrobbler/templates/scrobbles/_row.html
Normal file
@ -0,0 +1,7 @@
|
||||
{% load humanize %}
|
||||
{% load naturalduration %}
|
||||
<tr>
|
||||
<td>{% if scrobble.in_progress %}{{scrobble.media_obj.strings.verb}} now | <a class="right" href="{% url "scrobbles:finish" scrobble.uuid %}">Finish</a>{% else %}{{scrobble.timestamp|naturaltime}}{% endif %}</td>
|
||||
<td><a href="{{scrobble.media_obj.get_absolute_url}}">{{scrobble.media_obj|truncatechars_html:50}}</a></td>
|
||||
<td>{{scrobble.elapsed_time|natural_duration}}</td>
|
||||
</tr>
|
||||
22
vrobbler/templates/scrobbles/_scrobble_table.html
Normal file
22
vrobbler/templates/scrobbles/_scrobble_table.html
Normal file
@ -0,0 +1,22 @@
|
||||
{% load humanize %}
|
||||
{% load naturalduration %}
|
||||
|
||||
<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">Title</th>
|
||||
<th scope="col">Time</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for scrobble in scrobbles %}
|
||||
{% include "scrobbles/_row.html" %}
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
@ -49,9 +49,28 @@
|
||||
<main class="col-md-9 ms-sm-auto col-lg-10 px-md-4">
|
||||
<div
|
||||
class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
|
||||
<h1 class="h2">{% if date %}{{date|naturaltime}}{% else %}Today{% endif %}</h1>
|
||||
<h1 class="h2">{% if date %}{{date|naturaltime}}{% else %}{{title}}{% endif %}</h1>
|
||||
<div class="btn-toolbar mb-2 mb-md-0">
|
||||
{% if user.is_authenticated %}
|
||||
<div class="btn-group me-2">
|
||||
{% if user.profile.lastfm_username and not user.profile.lastfm_auto_import %}
|
||||
<form action="{% url 'scrobbles:lastfm-import' %}" method="get">
|
||||
<button type="submit" class="btn btn-sm btn-outline-secondary">Last.fm Sync</button>
|
||||
</form>
|
||||
{% endif %}
|
||||
{% if prev_link %}
|
||||
<a type="button" class="btn btn-sm btn-outline-secondary" href="{{prev_link}}"
|
||||
data-bs-target="#">Previous</a>
|
||||
{% endif %}
|
||||
{% if today_link %}
|
||||
<a type="button" class="btn btn-sm btn-outline-secondary" href="{{today_link}}"
|
||||
data-bs-target="#">Today</a>
|
||||
{% endif %}
|
||||
{% if next_link %}
|
||||
<a type="button" class="btn btn-sm btn-outline-secondary" href="{{next_link}}"
|
||||
data-bs-target="#">Next</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="btn-group me-2">
|
||||
{% if user.profile.lastfm_username and not user.profile.lastfm_auto_import %}
|
||||
|
||||
@ -69,11 +88,13 @@
|
||||
<button type="button" class="btn btn-sm btn-outline-secondary dropdown-toggle" id="graphDateButton"
|
||||
data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<div data-feather="calendar"></div>
|
||||
This week
|
||||
{{title}}
|
||||
</button>
|
||||
<div class="dropdown-menu" data-bs-toggle="#graphDataChange" aria-labelledby="graphDateButton">
|
||||
<a class="dropdown-item" href="#">This month</a>
|
||||
<a class="dropdown-item" href="#">This year</a>
|
||||
<a class="dropdown-item" href="?date=today">Today</a>
|
||||
<a class="dropdown-item" href="?date=this_week">This week</a>
|
||||
<a class="dropdown-item" href="?date=this_month">This month</a>
|
||||
<a class="dropdown-item" href="?date=this_year">This year</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user