bgneal@60: """ bgneal@60: Automatic admin definitions for the videos application. bgneal@60: bgneal@60: """ bgneal@60: import datetime bgneal@60: import urlparse bgneal@60: bgneal@62: try: bgneal@62: from urlparse import parse_qs bgneal@62: except ImportError: bgneal@62: from cgi import parse_qs # for Python 2.5 bgneal@62: bgneal@60: from django.contrib import admin bgneal@60: from django.contrib import messages bgneal@60: from gdata.youtube.service import YouTubeService bgneal@60: bgneal@60: from videos.models import Playlist bgneal@60: bgneal@60: bgneal@60: class PlaylistAdmin(admin.ModelAdmin): bgneal@60: list_display = ['__unicode__', 'playlist_url', 'sync_date'] bgneal@60: readonly_fields = ['playlist_title', 'video_list', 'sync_date'] bgneal@60: actions = ['sync'] bgneal@60: bgneal@60: def sync(self, request, queryset): bgneal@60: for playlist in queryset: bgneal@60: self.sync_playlist(request, playlist) bgneal@60: bgneal@60: sync.short_description = 'Synchronize with YouTube' bgneal@60: bgneal@60: def sync_playlist(self, request, playlist): bgneal@60: """ bgneal@60: Retrieve the title and list of videos for a bgneal@60: YouTube playlist. bgneal@60: bgneal@60: """ bgneal@60: # Find the playlist ID: bgneal@60: parts = urlparse.urlparse(playlist.playlist_url) bgneal@62: query = parse_qs(parts.query) bgneal@60: if 'list' not in query: bgneal@60: messages.error(request, 'Invalid playlist %s' % bgneal@60: playlist.playlist_url) bgneal@60: return bgneal@60: bgneal@60: playlist_id = query['list'][0] bgneal@60: if not playlist_id.startswith('PL'): bgneal@60: messages.error(request, 'Invalid playlist ID in %s' % bgneal@60: playlist.playlist_url) bgneal@60: return bgneal@60: playlist_id = playlist_id[2:] bgneal@60: bgneal@60: # Get the playlist feed: bgneal@60: yt = YouTubeService() bgneal@60: feed = yt.GetYouTubePlaylistVideoFeed(playlist_id=playlist_id) bgneal@60: feed_title = feed.title.text bgneal@60: expected_count = int(feed.total_results.text) bgneal@60: bgneal@60: # Get all the videos in the feed; this may take multiple requests: bgneal@60: vids = [] bgneal@60: while True: bgneal@60: vids.extend(feed.entry) bgneal@60: next_link = feed.GetNextLink() bgneal@60: if not next_link: bgneal@60: break bgneal@60: feed = yt.Query(next_link.href) bgneal@60: bgneal@60: if len(vids) != expected_count: bgneal@60: messages.error(request, "%s: expected %d videos, got %d" % bgneal@60: (playlist.playlist_url, expected_count, len(vids))) bgneal@60: bgneal@60: # Find the video ID for each video bgneal@60: bgneal@60: vid_ids = [] bgneal@60: for vid in vids: bgneal@60: for link in vid.link: bgneal@60: parts = urlparse.urlparse(link.href) bgneal@62: query = parse_qs(parts.query) bgneal@60: if 'v' in query: bgneal@60: vid_ids.append(query['v'][0]) bgneal@60: break bgneal@60: else: bgneal@60: messages.error(request, "%s: video id not found for %s" % bgneal@60: (playlist.playlist_url, vid.title.text)) bgneal@60: bgneal@60: # Okay, save what we got bgneal@60: playlist.playlist_title = feed_title bgneal@60: playlist.video_list = ",".join(vid_ids) bgneal@60: playlist.sync_date = datetime.datetime.now() bgneal@60: playlist.save() bgneal@60: bgneal@60: messages.info(request, "Synchronized %s (%s)" % (feed_title, bgneal@60: playlist.playlist_url)) bgneal@60: bgneal@60: bgneal@60: admin.site.register(Playlist, PlaylistAdmin)