From db220d5de5b4c1c4cc003de828750463a066bf24 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Stefan=20K=C3=B6gl?= Date: Sat, 22 Sep 2012 11:22:39 +0200 Subject: [PATCH] move all PodcastList db queries into separate module --- mygpo/api/advanced/lists.py | 6 +- mygpo/db/couchdb/podcastlist.py | 68 +++++++++++++++++++++++ mygpo/directory/views.py | 9 +-- mygpo/share/models.py | 120 +++++++++------------------------------- mygpo/share/userpage.py | 4 +- mygpo/share/views.py | 11 ++-- mygpo/web/views/__init__.py | 5 +- 7 files changed, 115 insertions(+), 108 deletions(-) create mode 100644 mygpo/db/couchdb/podcastlist.py rewrite mygpo/share/models.py (66%) diff --git a/mygpo/api/advanced/lists.py b/mygpo/api/advanced/lists.py index 6414e2ed..ae8a03d3 100644 --- a/mygpo/api/advanced/lists.py +++ b/mygpo/api/advanced/lists.py @@ -36,6 +36,8 @@ from mygpo.api.simple import parse_subscription, format_podcast_list, \ from mygpo.share.views import list_decorator from mygpo.users.models import User from mygpo.db.couchdb.podcast import podcasts_by_id, podcast_for_url +from mygpo.db.couchdb.podcastlist import podcastlist_for_user_slug, \ + podcastlists_for_user @@ -58,7 +60,7 @@ def create(request, username, format): if not slug: return HttpResponseBadRequest('Invalid title') - plist = PodcastList.for_user_slug(request.user._id, slug) + plist = podcastlist_for_user_slug(request.user._id, slug) if plist: return HttpResponse('List already exists', status=409) @@ -101,7 +103,7 @@ def get_lists(request, username): if not user: raise Http404 - lists = PodcastList.for_user(user._id) + lists = podcastlists_for_user(user._id) site = RequestSite(request) diff --git a/mygpo/db/couchdb/podcastlist.py b/mygpo/db/couchdb/podcastlist.py new file mode 100644 index 00000000..ec5e9084 --- /dev/null +++ b/mygpo/db/couchdb/podcastlist.py @@ -0,0 +1,68 @@ +from random import random + +from mygpo.share.models import PodcastList +from mygpo.cache import cache_result + + + +def podcastlist_for_user_slug(user_id, slug): + + r = PodcastList.view('podcastlists/by_user_slug', + key = [user_id, slug], + include_docs = True, + ) + return r.first() if r else None + + + +def podcastlists_for_user(user_id): + + r = PodcastList.view('podcastlists/by_user_slug', + startkey = [user_id, None], + endkey = [user_id, {}], + include_docs = True, + ) + return list(r) + + + +@cache_result(timeout=60*69) +def podcastlists_by_rating(**kwargs): + r = PodcastList.view('podcastlists/by_rating', + descending = True, + include_docs = True, + stale = 'update_after', + **kwargs + ) + return list(r) + + + +@cache_result(timeout=60*60) +def podcastlist_count(with_rating=True): + view = 'podcastlists/by_rating' if with_rating else \ + 'podcastlists/by_user_slug' + + return PodcastList.view(view, + limit = 0, + stale = 'update_after', + ).total_rows + + + +def random_podcastlists(chunk_size=1): + + while True: + rnd = random() + res = PodcastList.view('podcastlists/random', + startkey = rnd, + include_docs = True, + limit = chunk_size, + stale = 'ok', + ) + + if not res: + break + + for r in res: + yield r diff --git a/mygpo/directory/views.py b/mygpo/directory/views.py index 6ac3bc31..196b3dda 100644 --- a/mygpo/directory/views.py +++ b/mygpo/directory/views.py @@ -17,11 +17,12 @@ from mygpo.directory.toplist import PodcastToplist, EpisodeToplist, \ from mygpo.directory.search import search_podcasts from mygpo.web import utils from mygpo.directory.tags import Topics -from mygpo.share.models import PodcastList from mygpo.users.models import User from mygpo.db.couchdb.podcast import get_podcast_languages, podcasts_by_id, \ random_podcasts, podcasts_to_dict from mygpo.db.couchdb.directory import category_for_tag +from mygpo.db.couchdb.podcastlist import random_podcastlists, \ + podcastlist_count, podcastlists_by_rating @vary_on_cookie @@ -68,7 +69,7 @@ class Directory(View): def get_random_list(self, podcasts_per_list=5): - random_list = next(PodcastList.random(), None) + random_list = next(random_podcastlists(), None) list_owner = None if random_list: random_list = proxy_object(random_list) @@ -189,7 +190,7 @@ def podcast_lists(request, page_size=20): except ValueError: page = 1 - lists = PodcastList.by_rating(skip=(page-1) * page_size, limit=page_size) + lists = podcastlists_by_rating(skip=(page-1) * page_size, limit=page_size) def _prepare_list(l): @@ -200,7 +201,7 @@ def podcast_lists(request, page_size=20): lists = map(_prepare_list, lists) - num_pages = int(ceil(PodcastList.count() / float(page_size))) + num_pages = int(ceil(podcastlist_count() / float(page_size))) page_list = utils.get_page_list(1, num_pages, page, 15) diff --git a/mygpo/share/models.py b/mygpo/share/models.py dissimilarity index 66% index 6ae9d610..de7078de 100644 --- a/mygpo/share/models.py +++ b/mygpo/share/models.py @@ -1,93 +1,27 @@ -from random import random - -from couchdbkit.ext.django.schema import * - -from django.template.defaultfilters import slugify - -from mygpo.core.proxy import DocumentABCMeta -from mygpo.users.models import RatingMixin -from mygpo.cache import cache_result - - - -class PodcastList(Document, RatingMixin): - """ A list of Podcasts that a user creates for the purpose of sharing """ - - __metaclass__ = DocumentABCMeta - - title = StringProperty(required=True) - slug = StringProperty(required=True) - podcasts = StringListProperty() - user = StringProperty(required=True) - random_key = FloatProperty(default=random) - - - - @classmethod - def for_user_slug(cls, user_id, slug): - - r = cls.view('podcastlists/by_user_slug', - key = [user_id, slug], - include_docs = True, - ) - return r.first() if r else None - - - @classmethod - def for_user(cls, user_id): - - r = cls.view('podcastlists/by_user_slug', - startkey = [user_id, None], - endkey = [user_id, {}], - include_docs = True, - ) - return list(r) - - - @classmethod - @cache_result(timeout=60*69) - def by_rating(cls, **kwargs): - r = cls.view('podcastlists/by_rating', - descending = True, - include_docs = True, - stale = 'update_after', - **kwargs - ) - return r.iterator() - - - @classmethod - @cache_result(timeout=60*60) - def count(cls, with_rating=True): - view = 'podcastlists/by_rating' if with_rating else \ - 'podcastlists/by_user_slug' - - return cls.view(view, - limit = 0, - stale = 'update_after', - ).total_rows - - - @classmethod - def random(cls, chunk_size=1): - - while True: - rnd = random() - res = cls.view('podcastlists/random', - startkey = rnd, - include_docs = True, - limit = chunk_size, - stale = 'ok', - ) - - if not res: - break - - for r in res: - yield r - - - - def __repr__(self): - return '<{cls} "{title}" by {user}>'.format( - cls=self.__class__.__name__, title=self.title, user=self.user) +from random import random + +from couchdbkit.ext.django.schema import * + +from django.template.defaultfilters import slugify + +from mygpo.core.proxy import DocumentABCMeta +from mygpo.users.models import RatingMixin +from mygpo.cache import cache_result + + + +class PodcastList(Document, RatingMixin): + """ A list of Podcasts that a user creates for the purpose of sharing """ + + __metaclass__ = DocumentABCMeta + + title = StringProperty(required=True) + slug = StringProperty(required=True) + podcasts = StringListProperty() + user = StringProperty(required=True) + random_key = FloatProperty(default=random) + + + def __repr__(self): + return '<{cls} "{title}" by {user}>'.format( + cls=self.__class__.__name__, title=self.title, user=self.user) diff --git a/mygpo/share/userpage.py b/mygpo/share/userpage.py index 36d3bcac..9d166130 100644 --- a/mygpo/share/userpage.py +++ b/mygpo/share/userpage.py @@ -6,7 +6,6 @@ from django.shortcuts import render from django.views.generic.base import View from django.utils.decorators import method_decorator -from mygpo.share.models import PodcastList from mygpo.users.models import User from mygpo.users.models import HistoryEntry from mygpo.decorators import requires_token @@ -16,6 +15,7 @@ from mygpo.web.views import GeventView from mygpo.db.couchdb.episode import favorite_episodes_for_user from mygpo.db.couchdb.user import get_latest_episodes, \ get_num_played_episodes, get_seconds_played +from mygpo.db.couchdb.podcastlist import podcastlists_for_user @@ -51,7 +51,7 @@ class UserpageView(GeventView): def get_podcast_lists(self, user): - return list(PodcastList.for_user(user._id)) + return podcastlists_for_user(user._id) def get_subscriptions(self, user): diff --git a/mygpo/share/views.py b/mygpo/share/views.py index 1b7c1f34..0b92f71e 100644 --- a/mygpo/share/views.py +++ b/mygpo/share/views.py @@ -23,7 +23,8 @@ from mygpo.decorators import repeat_on_conflict from mygpo.data.feeddownloader import update_podcasts from mygpo.userfeeds.feeds import FavoriteFeed from mygpo.db.couchdb.podcast import podcasts_by_id, podcast_for_url - +from mygpo.db.couchdb.podcastlist import podcastlist_for_user_slug, \ + podcastlists_for_user def list_decorator(must_own=False): @@ -38,7 +39,7 @@ def list_decorator(must_own=False): if must_own and request.user != user: return HttpResponseForbidden() - plist = PodcastList.for_user_slug(user._id, listname) + plist = podcastlist_for_user_slug(user._id, listname) if plist is None: raise Http404 @@ -59,7 +60,7 @@ def search(request, username, listname): @login_required def lists_own(request): - lists = PodcastList.for_user(request.user._id) + lists = podcastlists_for_user(request.user._id) return render(request, 'lists.html', { 'lists': lists @@ -72,7 +73,7 @@ def lists_user(request, username): if not user: raise Http404 - lists = PodcastList.for_user(user._id) + lists = podcastlists_for_user(user._id) return render(request, 'lists_user.html', { 'lists': lists, @@ -124,7 +125,7 @@ def create_list(request): title=title)) return HttpResponseRedirect(reverse('lists-overview')) - plist = PodcastList.for_user_slug(request.user._id, slug) + plist = podcastlist_for_user_slug(request.user._id, slug) if plist is None: plist = PodcastList() diff --git a/mygpo/web/views/__init__.py b/mygpo/web/views/__init__.py index 6682c25b..aebe63dc 100644 --- a/mygpo/web/views/__init__.py +++ b/mygpo/web/views/__init__.py @@ -42,12 +42,12 @@ from mygpo.users.models import Suggestions, History, HistoryEntry, DeviceDoesNot from mygpo.users.models import PodcastUserState, User from mygpo.web import utils from mygpo.utils import flatten, parse_range -from mygpo.share.models import PodcastList from mygpo.db.couchdb.episode import favorite_episodes_for_user from mygpo.db.couchdb.podcast import podcast_by_id, \ podcast_for_oldid, random_podcasts from mygpo.db.couchdb.user import suggestions_for_user from mygpo.db.couchdb.directory import tags_for_user +from mygpo.db.couchdb.podcastlist import podcastlists_for_user @vary_on_cookie @@ -105,7 +105,8 @@ def dashboard(request, episode_count=10): if tags_for_user(request.user): checklist.append('tags') - if PodcastList.for_user(request.user._id): + # TODO add podcastlist_count_for_user + if podcastlists_for_user(request.user._id): checklist.append('lists') if request.user.published_objects: -- 2.11.4.GIT