From 11a6d3690e6e8b404291bf59477671163df51b00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20K=C3=B6gl?= Date: Sat, 30 Dec 2017 21:38:43 +0100 Subject: [PATCH 1/2] Show trending podcasts --- .../templates/directory/trending.html | 64 +++++++++++++++++++ mygpo/directory/urls.py | 4 ++ mygpo/directory/views.py | 29 +++++++++ mygpo/web/templatetags/menu.py | 1 + 4 files changed, 98 insertions(+) create mode 100644 mygpo/directory/templates/directory/trending.html diff --git a/mygpo/directory/templates/directory/trending.html b/mygpo/directory/templates/directory/trending.html new file mode 100644 index 000000000..93c2cd3f2 --- /dev/null +++ b/mygpo/directory/templates/directory/trending.html @@ -0,0 +1,64 @@ +{% extends "base.html" %} + +{% load i18n %} +{% load podcasts %} +{% load charts %} +{% load math %} +{% load utils %} +{% load static %} + +{% load menu %} +{% block mainmenu %}{{ "/trending/"|main_menu }}{% endblock %} +{% block sectionmenu %}{{ "/trending/"|section_menu }}{% endblock %} + +{% block title %}{% trans "Trending Podcasts" %}{% endblock %} + +{% block header %} +

{% trans "Trending Podcasts" %}

+{% endblock %} + +{% block content %} + + + + + + + + + {% for podcast in podcasts %} + + + + + + + + {% empty %} + + + + {% endfor %} +
{% trans "Podcast" %}{% trans "Subscribers" %}
+ {% ifchanged podcast.subscriber_count %} + {{ forloop.counter }} + {% endifchanged %} + + + {% podcast_group_link podcast %} + {% vertical_bar podcast.subscriber_count max_subscribers %}
+ {% trans "Currently not available" %} +
+ +{% endblock %} + + +{% block sidebar %} + +
+

{% trans "Client Access" %}

+ +

Access http://{{ view.site }}{% url "toplist-opml" 30 "opml" %} for the Top-30.

+
+ +{% endblock %} diff --git a/mygpo/directory/urls.py b/mygpo/directory/urls.py index ef2d15880..3d693db51 100644 --- a/mygpo/directory/urls.py +++ b/mygpo/directory/urls.py @@ -9,6 +9,10 @@ views.PodcastToplistView.as_view(), name='toplist'), + url(r'^trending/$', + views.TrendingPodcastsView.as_view(), + name='trending'), + url(r'^toplist/episodes$', views.EpisodeToplistView.as_view(), name='episode-toplist'), diff --git a/mygpo/directory/views.py b/mygpo/directory/views.py index e292dd8d7..cea48b37f 100644 --- a/mygpo/directory/views.py +++ b/mygpo/directory/views.py @@ -3,6 +3,7 @@ from math import ceil from collections import Counter +from datetime import datetime, timedelta from django.http import HttpResponseNotFound, Http404, HttpResponseRedirect from django.urls import reverse @@ -28,6 +29,7 @@ from mygpo.directory.tags import Topics from mygpo.categories.models import Category from mygpo.podcastlists.models import PodcastList +from mygpo.subscriptions.models import Subscription from mygpo.data.feeddownloader import (verify_podcast_url, NoEpisodesException, UpdatePodcastException) from mygpo.data.tasks import update_podcasts @@ -393,3 +395,30 @@ def licenses(self): counter = Counter({l['license']: l['id__count'] for l in values}) return counter.most_common() + + +class TrendingPodcastsView(PodcastListView): + """ Podcast with most recent subscribers """ + + template_name = 'directory/trending.html' + + def get_queryset(self): + starttime = datetime.utcnow()-timedelta(days=7) + max_entries = 20 + subscriptions = Subscription.objects.filter(created__gte=starttime) + + # With the following line this error would be raised: + # annotate() + distinct(fields) is not implemented. + # + #subscriptions = subscriptions.distinct('podcast', 'user') + trending = subscriptions.values('podcast')\ + .annotate(users=Count('user'))\ + .order_by('-users') + + podcast_ids = [entry['podcast'] for entry in trending] + podcasts = Podcast.objects.filter(id__in=podcast_ids) + + # TODO: order by number of recent subscribers? + podcasts = podcasts.order_by('-latest_episode_timestamp') + + return podcasts diff --git a/mygpo/web/templatetags/menu.py b/mygpo/web/templatetags/menu.py index 8ac8d68ff..50553c1a5 100644 --- a/mygpo/web/templatetags/menu.py +++ b/mygpo/web/templatetags/menu.py @@ -30,6 +30,7 @@ )), (_('Discover'), ( ('/directory/', _('Directory')), + ('/trending/', _('Trending')), ('/podcast/', _('Podcast')), ('/search/', _('Search')), ('/missing/', _('Missing Podcast')), From d155f40f135e5eb3f06af889e87b34636c824a45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20K=C3=B6gl?= Date: Wed, 15 Aug 2018 22:27:59 +0200 Subject: [PATCH 2/2] Improve query for trending podcasts --- mygpo/directory/views.py | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/mygpo/directory/views.py b/mygpo/directory/views.py index cea48b37f..fa6f974c7 100644 --- a/mygpo/directory/views.py +++ b/mygpo/directory/views.py @@ -405,20 +405,14 @@ class TrendingPodcastsView(PodcastListView): def get_queryset(self): starttime = datetime.utcnow()-timedelta(days=7) max_entries = 20 - subscriptions = Subscription.objects.filter(created__gte=starttime) - # With the following line this error would be raised: - # annotate() + distinct(fields) is not implemented. - # - #subscriptions = subscriptions.distinct('podcast', 'user') - trending = subscriptions.values('podcast')\ - .annotate(users=Count('user'))\ - .order_by('-users') + podcasts = Podcast.objects.annotate( + subscriptions=Sum(Case( + When(subscription__created__gte=starttime, then=Value(1)), + default=Value(0), + output_field=IntegerField()))) - podcast_ids = [entry['podcast'] for entry in trending] - podcasts = Podcast.objects.filter(id__in=podcast_ids) + trending = podcasts.exclude(subscriptions__lt=1) + trending = trending.order_by('-subscriptions') - # TODO: order by number of recent subscribers? - podcasts = podcasts.order_by('-latest_episode_timestamp') - - return podcasts + return trending