From 35b3576ef8022d1cbacdb8db847583ca284c18bd Mon Sep 17 00:00:00 2001 From: =?utf8?q?Stefan=20K=C3=B6gl?= Date: Sat, 11 Oct 2014 11:19:38 +0200 Subject: [PATCH] [Migration] remove / rewrite get_num_listened_episodes --- mygpo/db/couchdb/user.py | 24 ---------------------- .../migrations/0006_episodehistory_index.py | 18 ++++++++++++++++ mygpo/history/models.py | 4 ++++ mygpo/history/stats.py | 17 +++++++++++++++ mygpo/users/subscriptions.py | 6 +++--- 5 files changed, 42 insertions(+), 27 deletions(-) create mode 100644 mygpo/history/migrations/0006_episodehistory_index.py create mode 100644 mygpo/history/stats.py diff --git a/mygpo/db/couchdb/user.py b/mygpo/db/couchdb/user.py index 1802adff..93f7c9ed 100644 --- a/mygpo/db/couchdb/user.py +++ b/mygpo/db/couchdb/user.py @@ -4,30 +4,6 @@ from mygpo.db import QueryParameterMissing @cache_result(timeout=60) -def get_num_listened_episodes(user): - - if not user: - raise QueryParameterMissing('user') - - udb = get_userdata_database() - r = udb.view('listeners/by_user_podcast', - startkey = [user.profile.uuid.hex, None], - endkey = [user.profile.uuid.hex, {}], - reduce = True, - group_level = 2, - stale = 'update_after', - ) - - return map(_wrap_num_listened, r) - - -def _wrap_num_listened(obj): - count = obj['value'] - podcast = obj['key'][1] - return (podcast, count) - - -@cache_result(timeout=60) def get_num_played_episodes(user, since=None, until={}): """ Number of played episodes in interval """ diff --git a/mygpo/history/migrations/0006_episodehistory_index.py b/mygpo/history/migrations/0006_episodehistory_index.py new file mode 100644 index 00000000..57d8e3c5 --- /dev/null +++ b/mygpo/history/migrations/0006_episodehistory_index.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('history', '0005_episodehistoryentry'), + ] + + operations = [ + migrations.AlterIndexTogether( + name='episodehistoryentry', + index_together=set([('user', 'action', 'episode'), ('user', 'client', 'episode', 'action', 'timestamp')]), + ), + ] diff --git a/mygpo/history/models.py b/mygpo/history/models.py index e0e28316..1f201501 100644 --- a/mygpo/history/models.py +++ b/mygpo/history/models.py @@ -1,4 +1,5 @@ from __future__ import unicode_literals +from collections import Counter from django.db import models from django.conf import settings @@ -105,6 +106,9 @@ class EpisodeHistoryEntry(models.Model): class Meta: index_together = [ ['user', 'client', 'episode', 'action', 'timestamp'], + + # see query in played_episode_counts() + ['user', 'action', 'episode'], ] ordering = ['-timestamp'] diff --git a/mygpo/history/stats.py b/mygpo/history/stats.py new file mode 100644 index 00000000..5752d3cc --- /dev/null +++ b/mygpo/history/stats.py @@ -0,0 +1,17 @@ +from collections import Counter + +from mygpo.history.models import EpisodeHistoryEntry + + +def played_episode_counts(user): + """ number of played episodes per podcast for the given user """ + # retrieve list of unique episodes that the user has played. + # for each episode only it's podcast is returned, because we don't care + # about which episodes exactly have been played, only the number + podcasts = EpisodeHistoryEntry.objects\ + .filter(user=user, + action=EpisodeHistoryEntry.PLAY)\ + .order_by('episode__id')\ + .distinct('episode__id')\ + .values_list('episode__podcast', flat=True) + return Counter(podcasts) diff --git a/mygpo/users/subscriptions.py b/mygpo/users/subscriptions.py index 780453b6..e8460a50 100644 --- a/mygpo/users/subscriptions.py +++ b/mygpo/users/subscriptions.py @@ -3,7 +3,7 @@ from operator import itemgetter from mygpo.utils import linearize from mygpo.podcasts.models import Podcast -from mygpo.db.couchdb.user import get_num_listened_episodes +from mygpo.history.stats import played_episode_counts class PodcastSorter(object): @@ -52,9 +52,9 @@ class PodcastPercentageListenedSorter(PodcastSorter): SORT_KEY = lambda podcast: podcast.percent_listened - counts = dict(get_num_listened_episodes(self.user)) + counts = played_episode_counts(self.user) for podcast in self.podcasts: - c = counts.get(podcast.get_id(), 0) + c = counts.get(podcast.id, 0) if podcast.episode_count: podcast.percent_listened = c / float(podcast.episode_count) podcast.episodes_listened = c -- 2.11.4.GIT