From a5510d7294f25af066d477e394dc68cd5d0dbba8 Mon Sep 17 00:00:00 2001 From: Colin Powell Date: Thu, 7 May 2026 15:48:41 -0400 Subject: [PATCH] [templates] Limit home scrobbles to 20 by default, configurable --- vrobbler/apps/profiles/forms.py | 1 + .../0031_add_home_scrobble_limit.py | 18 +++++++++++ vrobbler/apps/profiles/models.py | 2 ++ vrobbler/apps/scrobbles/views.py | 31 ++++++++++++++++--- .../templates/profiles/settings_form.html | 5 +++ 5 files changed, 53 insertions(+), 4 deletions(-) create mode 100644 vrobbler/apps/profiles/migrations/0031_add_home_scrobble_limit.py diff --git a/vrobbler/apps/profiles/forms.py b/vrobbler/apps/profiles/forms.py index 200b9db..b2cad4c 100644 --- a/vrobbler/apps/profiles/forms.py +++ b/vrobbler/apps/profiles/forms.py @@ -34,6 +34,7 @@ class UserProfileForm(forms.ModelForm): "redirect_to_webpage", "enable_public_widgets", "widget_custom_css", + "home_scrobble_limit", ] widgets = { "lastfm_password": forms.PasswordInput(render_value=True), diff --git a/vrobbler/apps/profiles/migrations/0031_add_home_scrobble_limit.py b/vrobbler/apps/profiles/migrations/0031_add_home_scrobble_limit.py new file mode 100644 index 0000000..25d5984 --- /dev/null +++ b/vrobbler/apps/profiles/migrations/0031_add_home_scrobble_limit.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.29 on 2026-05-07 19:26 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("profiles", "0030_userprofile_widget_custom_css"), + ] + + operations = [ + migrations.AddField( + model_name="userprofile", + name="home_scrobble_limit", + field=models.IntegerField(default=20), + ), + ] diff --git a/vrobbler/apps/profiles/models.py b/vrobbler/apps/profiles/models.py index 0b75aa7..753d8cb 100644 --- a/vrobbler/apps/profiles/models.py +++ b/vrobbler/apps/profiles/models.py @@ -64,6 +64,8 @@ class UserProfile(TimeStampedModel): enable_public_widgets = models.BooleanField(default=False) widget_custom_css = models.TextField(**BNULL) + home_scrobble_limit = models.IntegerField(default=20) + def __str__(self): return f"User profile for {self.user}" diff --git a/vrobbler/apps/scrobbles/views.py b/vrobbler/apps/scrobbles/views.py index 36fb6f7..3fd0494 100644 --- a/vrobbler/apps/scrobbles/views.py +++ b/vrobbler/apps/scrobbles/views.py @@ -212,6 +212,11 @@ class RecentScrobbleList(ListView): self.queryset = self.get_queryset().filter(user=user) user_id = self.request.user.id + # Get user's home scrobble limit (default 20) + home_limit = 20 + if hasattr(user, 'profile') and user.profile.home_scrobble_limit: + home_limit = user.profile.home_scrobble_limit + today = timezone.localtime(timezone.now()) date_str = self.request.GET.get("date", "") date = today @@ -228,9 +233,13 @@ class RecentScrobbleList(ListView): 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( + scrobbles_dict = Scrobble.as_dict_by_type( Scrobble.for_week(user_id, date.year, date.isocalendar()[1]) ) + for key in list(scrobbles_dict.keys()): + if not key.endswith("_count") and not key.endswith("_time"): + scrobbles_dict[key] = scrobbles_dict[key][:home_limit] + data = data | scrobbles_dict elif date_str == "this_month" or date_str.count("-") == 1: next_date = date + relativedelta(months=1) prev_date = date + relativedelta(months=-1) @@ -238,9 +247,13 @@ class RecentScrobbleList(ListView): 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( + scrobbles_dict = Scrobble.as_dict_by_type( Scrobble.for_month(user_id, date.year, date.month) ) + for key in list(scrobbles_dict.keys()): + if not key.endswith("_count") and not key.endswith("_time"): + scrobbles_dict[key] = scrobbles_dict[key][:home_limit] + data = data | scrobbles_dict elif date_str == "today" or date_str.count("-") == 2: next_date = date + timedelta(days=1) prev_date = date - timedelta(days=1) @@ -264,18 +277,28 @@ class RecentScrobbleList(ListView): 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( + scrobbles_dict = Scrobble.as_dict_by_type( Scrobble.for_year(user_id, date.year) ) + for key in list(scrobbles_dict.keys()): + if not key.endswith("_count") and not key.endswith("_time"): + scrobbles_dict[key] = scrobbles_dict[key][:home_limit] + data = data | scrobbles_dict 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( + # Get scrobbles grouped by type, limit to 20 per type + scrobbles_dict = Scrobble.as_dict_by_type( Scrobble.for_day(user_id, date.year, date.month, date.day) ) + # Limit each media type to 20 most recent + for key in list(scrobbles_dict.keys()): + if not key.endswith("_count") and not key.endswith("_time"): + scrobbles_dict[key] = scrobbles_dict[key][:20] + data = data | scrobbles_dict data["today_link"] = "" # f"?date={today.strftime('%Y-%m-%d')}" data["active_imports"] = AudioScrobblerTSVImport.objects.filter( diff --git a/vrobbler/templates/profiles/settings_form.html b/vrobbler/templates/profiles/settings_form.html index 87b11c1..46c928a 100644 --- a/vrobbler/templates/profiles/settings_form.html +++ b/vrobbler/templates/profiles/settings_form.html @@ -129,6 +129,11 @@ {% endif %} + {% elif field.name == "home_scrobble_limit" %} +

+ {{ field.label_tag }} + {{ field }} +

{% else %}

{{ field.label_tag }}