[scrobbles] Add admin list to index

This commit is contained in:
2026-03-08 17:55:45 -04:00
parent c43771c757
commit 3a79c17006
4 changed files with 106 additions and 9 deletions

View File

@ -92,7 +92,7 @@ fetching and simple saving.
:LOGBOOK:
CLOCK: [2025-07-09 Wed 09:55]--[2025-07-09 Wed 10:15] => 0:20
:END:
* Backlog [6/30]
* Backlog [8/32]
** TODO [#C] Create small utility to clean up tracks scrobbled with wonky playback times :vrobbler:personal:bug:music:scrobbles:
** TODO [#C] Move to using more robust mopidy-webhooks pacakge form pypi :utility:improvement:
:PROPERTIES:
@ -460,6 +460,14 @@ Turns out we're not looking up music tracks properly, again.
:END:
** TODO Add sentiment parsing for Scrobbles with notes :vrobbler:project:scrobbles:sentiment:
** TODO Check opencode about a way to present stats like movies per month :vrobbler:scrobbles:stats:personal:project:
** DONE Update admin page to be easier to use :vrobbler:djadmin:project:personal:
:PROPERTIES:
:ID: 0779be1f-1ad7-ddc7-8861-d3c7c833cbe9
:END:
** DONE Fix migrations and update repo :vrobbler:scrobbles:admin:personal:project:
:PROPERTIES:
:ID: ccbc2ef0-68bf-9ef7-dcaf-febab5ebefe2
:END:
** DONE Add recipe parsing for food lookups :vrobbler:foods:project:feature:personal:
:PROPERTIES:
:ID: 86456c78-247b-fb63-7ae8-d6d17e7666b1

View File

@ -54,23 +54,19 @@ class ImportBaseAdmin(admin.ModelAdmin):
@admin.register(AudioScrobblerTSVImport)
class AudioScrobblerTSVImportAdmin(ImportBaseAdmin):
...
class AudioScrobblerTSVImportAdmin(ImportBaseAdmin): ...
@admin.register(LastFmImport)
class LastFmImportAdmin(ImportBaseAdmin):
...
class LastFmImportAdmin(ImportBaseAdmin): ...
@admin.register(KoReaderImport)
class KoReaderImportAdmin(ImportBaseAdmin):
...
class KoReaderImportAdmin(ImportBaseAdmin): ...
@admin.register(RetroarchImport)
class RetroarchImportAdmin(ImportBaseAdmin):
...
class RetroarchImportAdmin(ImportBaseAdmin): ...
@admin.register(Genre)

View File

@ -1,5 +1,20 @@
from django.apps import AppConfig
from django.contrib import admin
class ScrobblesConfig(AppConfig):
name = "scrobbles"
def ready(self):
from scrobbles.models import Scrobble
original_index = admin.site.index
def custom_index(request, extra_context=None):
extra_context = extra_context or {}
extra_context["recent_scrobbles"] = Scrobble.objects.filter(
timestamp__isnull=False
).order_by("-timestamp")[:20]
return original_index(request, extra_context)
admin.site.index = custom_index

View File

@ -0,0 +1,78 @@
{% extends "admin/base_site.html" %}
{% load i18n static %}
{% block extrastyle %}{{ block.super }}<link rel="stylesheet" href="{% static "admin/css/dashboard.css" %}">{% endblock %}
{% block coltype %}colMS{% endblock %}
{% block bodyclass %}{{ block.super }} dashboard{% endblock %}
{% block nav-breadcrumbs %}{% endblock %}
{% block nav-sidebar %}{% endblock %}
{% block content %}
<div id="content-main">
{% if recent_scrobbles %}
<div class="app-scrobbles module">
<table>
<caption>
<a href="{% url 'admin:scrobbles_scrobble_changelist' %}" class="section">Recent Scrobbles</a>
</caption>
<thead>
<tr>
<th>Timestamp</th>
<th>Media</th>
<th>Type</th>
<th>User</th>
</tr>
</thead>
<tbody>
{% for scrobble in recent_scrobbles %}
<tr>
<td><a href="{% url 'admin:scrobbles_scrobble_change' scrobble.pk %}">{{ scrobble.timestamp|date:"Y-m-d H:i" }}</a></td>
<td>{{ scrobble.media_obj|truncatechars:50 }}</td>
<td>{{ scrobble.get_media_type_display }}</td>
<td>{{ scrobble.user|default:"-" }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endif %}
{% include "admin/app_list.html" with app_list=app_list show_changelinks=True %}
</div>
{% endblock %}
{% block sidebar %}
<div id="content-related">
<div class="module" id="recent-actions-module">
<h2>{% translate 'Recent actions' %}</h2>
<h3>{% translate 'My actions' %}</h3>
{% load log %}
{% get_admin_log 10 as admin_log for_user user %}
{% if not admin_log %}
<p>{% translate 'None available' %}</p>
{% else %}
<ul class="actionlist">
{% for entry in admin_log %}
<li class="{% if entry.is_addition %}addlink{% endif %}{% if entry.is_change %}changelink{% endif %}{% if entry.is_deletion %}deletelink{% endif %}">
{% if entry.is_deletion or not entry.get_admin_url %}
{{ entry.object_repr }}
{% else %}
<a href="{{ entry.get_admin_url }}">{{ entry.object_repr }}</a>
{% endif %}
<br>
{% if entry.content_type %}
<span class="mini quiet">{% filter capfirst %}{{ entry.content_type.name }}{% endfilter %}</span>
{% else %}
<span class="mini quiet">{% translate 'Unknown content' %}</span>
{% endif %}
</li>
{% endfor %}
</ul>
{% endif %}
</div>
</div>
{% endblock %}