view bns_website/videos/admin.py @ 61:1d2473f4bcaa

Fix bug in template that prevented the embedded video player from playing the entire playlist.
author Brian Neal <bgneal@gmail.com>
date Sat, 19 Nov 2011 14:39:28 -0600
parents a0d3bc630ebd
children 93e9e7b3d2ae
line wrap: on
line source
"""
Automatic admin definitions for the videos application.

"""
import datetime
import urlparse

from django.contrib import admin
from django.contrib import messages
from gdata.youtube.service import YouTubeService

from videos.models import Playlist


class PlaylistAdmin(admin.ModelAdmin):
    list_display = ['__unicode__', 'playlist_url', 'sync_date']
    readonly_fields = ['playlist_title', 'video_list', 'sync_date']
    actions = ['sync']

    def sync(self, request, queryset):
        for playlist in queryset:
            self.sync_playlist(request, playlist)

    sync.short_description = 'Synchronize with YouTube'

    def sync_playlist(self, request, playlist):
        """
        Retrieve the title and list of videos for a
        YouTube playlist.

        """
        # Find the playlist ID:
        parts = urlparse.urlparse(playlist.playlist_url)
        query = urlparse.parse_qs(parts.query)
        if 'list' not in query:
            messages.error(request, 'Invalid playlist %s' %
                    playlist.playlist_url)
            return

        playlist_id = query['list'][0]
        if not playlist_id.startswith('PL'):
            messages.error(request, 'Invalid playlist ID in %s' %
                    playlist.playlist_url)
            return
        playlist_id = playlist_id[2:]

        # Get the playlist feed:
        yt = YouTubeService()
        feed = yt.GetYouTubePlaylistVideoFeed(playlist_id=playlist_id)
        feed_title = feed.title.text
        expected_count = int(feed.total_results.text)

        # Get all the videos in the feed; this may take multiple requests:
        vids = []
        while True:
            vids.extend(feed.entry)
            next_link = feed.GetNextLink()
            if not next_link:
                break
            feed = yt.Query(next_link.href)

        if len(vids) != expected_count:
            messages.error(request, "%s: expected %d videos, got %d" %
                    (playlist.playlist_url, expected_count, len(vids)))

        # Find the video ID for each video

        vid_ids = []
        for vid in vids:
            for link in vid.link:
                parts = urlparse.urlparse(link.href)
                query = urlparse.parse_qs(parts.query)
                if 'v' in query:
                    vid_ids.append(query['v'][0])
                    break
            else:
                messages.error(request, "%s: video id not found for %s" %
                        (playlist.playlist_url, vid.title.text))

        # Okay, save what we got
        playlist.playlist_title = feed_title
        playlist.video_list = ",".join(vid_ids)
        playlist.sync_date = datetime.datetime.now()
        playlist.save()

        messages.info(request, "Synchronized %s (%s)" % (feed_title,
            playlist.playlist_url))


admin.site.register(Playlist, PlaylistAdmin)