From 856cd80f2b12c2251b5e43ea1f78cffb2a1ad466 Mon Sep 17 00:00:00 2001 From: Stefan Koegl Date: Wed, 9 Jun 2010 22:05:05 +0200 Subject: [PATCH] implement API for podcast directory --- mygpo/api/advanced/directory.py | 116 ++++++++++++++++++++++++++++++++++++++++ mygpo/data/models.py | 17 ++++-- mygpo/urls.py | 4 ++ mygpo/web/views/public.py | 9 +--- 4 files changed, 135 insertions(+), 11 deletions(-) create mode 100644 mygpo/api/advanced/directory.py diff --git a/mygpo/api/advanced/directory.py b/mygpo/api/advanced/directory.py new file mode 100644 index 00000000..9e703a88 --- /dev/null +++ b/mygpo/api/advanced/directory.py @@ -0,0 +1,116 @@ +# +# This file is part of my.gpodder.org. +# +# my.gpodder.org is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# my.gpodder.org is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public +# License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with my.gpodder.org. If not, see . +# + +from mygpo.api.basic_auth import require_valid_user, check_username +from django.http import HttpResponse, HttpResponseBadRequest, HttpResponseForbidden, Http404, HttpResponseNotAllowed +from mygpo.api.httpresponse import JsonResponse +from mygpo.exceptions import ParameterMissing +from django.shortcuts import get_object_or_404 +from mygpo.api.sanitizing import sanitize_url +from mygpo.api.models import Device, Podcast, Episode, ToplistEntry +from mygpo.api.models.episodes import Chapter +from mygpo.data.models import PodcastTag +from django.utils.translation import ugettext as _ +from datetime import datetime, timedelta +from mygpo.log import log +from mygpo.utils import parse_time +import dateutil.parser +from django.contrib.sites.models import Site +from django.views.decorators.csrf import csrf_exempt + +try: + #try to import the JSON module (if we are on Python 2.6) + import json + + # Python 2.5 seems to have a different json module + if not 'dumps' in dir(json): + raise ImportError + +except ImportError: + # No JSON module available - fallback to simplejson (Python < 2.6) + print "No JSON module available - fallback to simplejson (Python < 2.6)" + import simplejson as json + + +@csrf_exempt +def top_tags(request, count): + tags = PodcastTag.objects.top_tags(int(count)) + resp = [] + for t in tags: + resp.append( { + 'tag': t.tag, + 'usage': t.entries + } ) + return JsonResponse(resp) + + +@csrf_exempt +def tag_podcasts(request, tag, count): + resp = [] + for p in PodcastTag.objects.podcasts_for_tag(tag)[:int(count)]: + resp.append( podcast_data(p.get_podcast()) ) + + return JsonResponse(resp) + + +def podcast_info(request): + url = sanitize_url(request.GET.get('url', '')) + podcast = get_object_or_404(Podcast, url=url) + resp = podcast_data(podcast) + + return JsonResponse(resp) + + +def episode_info(request): + podcast_url = sanitize_url(request.GET.get('podcast', '')) + episode_url = sanitize_url(request.GET.get('url', ''), podcast=False, episode=True) + print podcast_url + print episode_url + episode = get_object_or_404(Episode, url=episode_url, podcast__url=podcast_url) + + resp = episode_data(episode) + return JsonResponse(resp) + + +def podcast_data(podcast): + site = Site.objects.get_current() + if podcast.group: + e = ToplistEntry.objects.get(podcast_group=podcast.group) + else: + e = ToplistEntry.objects.get(podcast=podcast) + return { + "url": podcast.url, + "title": podcast.title, + "description": podcast.description, + "subscribers": e.subscriptions, + "logo_url": podcast.logo_url, + "website": podcast.link, + "mygpo_link": 'http://%s/podcast/%s' % (site.domain, podcast.id), + } + +def episode_data(episode): + site = Site.objects.get_current() + + return { + "title": episode.title, + "url": episode.url, + "podcast_title": episode.podcast.title, + "podcast_url": episode.podcast.url, + "description": episode.description, + "website": episode.link, + "mygpo_link": 'http://%s/episode/%s' % (site.domain, episode.id), + } diff --git a/mygpo/data/models.py b/mygpo/data/models.py index 5e97db3d..3e002557 100644 --- a/mygpo/data/models.py +++ b/mygpo/data/models.py @@ -1,12 +1,21 @@ from django.db import models from django.contrib.auth.models import User -from mygpo.api.models import Podcast, Episode, Device - +from mygpo.api.models import Podcast, Episode, Device, ToplistEntry +from mygpo import settings class PodcastTagManager(models.Manager): - def top_tags(self): - return self.raw("select *, count(id) as entries from podcast_tags group by tag order by entries desc") + def top_tags(self, total): + tags = self.raw("select *, count(id) as entries from podcast_tags group by tag order by entries desc")[:total] + + tags = filter(lambda x: not x.tag.startswith('http://'), tags) + + excluded_tags = getattr(settings, 'DIRECTORY_EXCLUDED_TAGS', []) + return filter(lambda x: not x.tag in excluded_tags, tags) + + def podcasts_for_tag(self, tag): + return ToplistEntry.objects.filter(podcast__podcasttag__tag=tag).order_by('-subscriptions').distinct() + class PodcastTag(models.Model): tag = models.CharField(max_length=100) diff --git a/mygpo/urls.py b/mygpo/urls.py index 6aa84365..e94c6481 100644 --- a/mygpo/urls.py +++ b/mygpo/urls.py @@ -110,6 +110,10 @@ urlpatterns = patterns('', (r'^api/2/auth/(?P\w+)/(?P[\w.-]+)/login\.json', 'mygpo.api.advanced.auth.login'), (r'^api/2/auth/(?P\w+)/(?P[\w.-]+)/logout\.json', 'mygpo.api.advanced.auth.logout'), (r'^api/2/auth/(?P\w+)/(?P[\w.-]+)/validate\.json', 'mygpo.api.advanced.auth.validate'), + (r'^api/2/tags/(?P\d+)\.json', 'mygpo.api.advanced.directory.top_tags'), + (r'^api/2/tag/(?P[^/]+)/(?P\d+)\.json', 'mygpo.api.advanced.directory.tag_podcasts'), + (r'^api/2/data/podcast\.json', 'mygpo.api.advanced.directory.podcast_info'), + (r'^api/2/data/episode\.json', 'mygpo.api.advanced.directory.episode_info'), (r'^api/2/chapters/(?P\w+)\.json', 'mygpo.api.advanced.episode.chapters'), diff --git a/mygpo/web/views/public.py b/mygpo/web/views/public.py index 16c37eb9..5e90cc85 100644 --- a/mygpo/web/views/public.py +++ b/mygpo/web/views/public.py @@ -31,16 +31,11 @@ from django.core.paginator import Paginator, InvalidPage, EmptyPage @manual_gc def browse(request, num_categories=10, num_tags_cloud=90, podcasts_per_category=10): total = int(num_categories) + int(num_tags_cloud) - top_tags = PodcastTag.objects.top_tags()[:total] - - top_tags = filter(lambda x: not x.tag.startswith('http://'), top_tags) - - excluded_tags = getattr(settings, 'DIRECTORY_EXCLUDED_TAGS', []) - top_tags = filter(lambda x: not x.tag in excluded_tags, top_tags) + top_tags = PodcastTag.objects.top_tags(total) categories = [] for tag in top_tags[:num_categories]: - entries = ToplistEntry.objects.filter(podcast__podcasttag__tag=tag.tag).order_by('-subscriptions').distinct()[:podcasts_per_category] + entries = PodcastTag.objects.podcasts_for_tag(tag.tag)[:podcasts_per_category] categories.append({ 'tag': tag.tag, 'entries': entries -- 2.11.4.GIT