comparison bns_website/videos/admin.py @ 60:a0d3bc630ebd

For issue #8, create a videos application to randomize videos in the playlist. This commit now adds a dependency to the Google Python GData library. The admin enters a playlist URL in the admin. Then the admin uses an admin action to synchronize the playlist with YouTube. This reads the playlist title and retrieves the video list from YouTube. The view function reads all the playlist objects to get the complete list of videos, then shuffles them up. The template generates Javascript to create a YouTube player with the shuffled list. A fixture is included for convenience and for the tests. I also committed a test tool I wrote to prove out this idea in case it is useful for future enhancements or experimentation.
author Brian Neal <bgneal@gmail.com>
date Sat, 19 Nov 2011 14:19:00 -0600
parents
children 93e9e7b3d2ae
comparison
equal deleted inserted replaced
59:f8858447adda 60:a0d3bc630ebd
1 """
2 Automatic admin definitions for the videos application.
3
4 """
5 import datetime
6 import urlparse
7
8 from django.contrib import admin
9 from django.contrib import messages
10 from gdata.youtube.service import YouTubeService
11
12 from videos.models import Playlist
13
14
15 class PlaylistAdmin(admin.ModelAdmin):
16 list_display = ['__unicode__', 'playlist_url', 'sync_date']
17 readonly_fields = ['playlist_title', 'video_list', 'sync_date']
18 actions = ['sync']
19
20 def sync(self, request, queryset):
21 for playlist in queryset:
22 self.sync_playlist(request, playlist)
23
24 sync.short_description = 'Synchronize with YouTube'
25
26 def sync_playlist(self, request, playlist):
27 """
28 Retrieve the title and list of videos for a
29 YouTube playlist.
30
31 """
32 # Find the playlist ID:
33 parts = urlparse.urlparse(playlist.playlist_url)
34 query = urlparse.parse_qs(parts.query)
35 if 'list' not in query:
36 messages.error(request, 'Invalid playlist %s' %
37 playlist.playlist_url)
38 return
39
40 playlist_id = query['list'][0]
41 if not playlist_id.startswith('PL'):
42 messages.error(request, 'Invalid playlist ID in %s' %
43 playlist.playlist_url)
44 return
45 playlist_id = playlist_id[2:]
46
47 # Get the playlist feed:
48 yt = YouTubeService()
49 feed = yt.GetYouTubePlaylistVideoFeed(playlist_id=playlist_id)
50 feed_title = feed.title.text
51 expected_count = int(feed.total_results.text)
52
53 # Get all the videos in the feed; this may take multiple requests:
54 vids = []
55 while True:
56 vids.extend(feed.entry)
57 next_link = feed.GetNextLink()
58 if not next_link:
59 break
60 feed = yt.Query(next_link.href)
61
62 if len(vids) != expected_count:
63 messages.error(request, "%s: expected %d videos, got %d" %
64 (playlist.playlist_url, expected_count, len(vids)))
65
66 # Find the video ID for each video
67
68 vid_ids = []
69 for vid in vids:
70 for link in vid.link:
71 parts = urlparse.urlparse(link.href)
72 query = urlparse.parse_qs(parts.query)
73 if 'v' in query:
74 vid_ids.append(query['v'][0])
75 break
76 else:
77 messages.error(request, "%s: video id not found for %s" %
78 (playlist.playlist_url, vid.title.text))
79
80 # Okay, save what we got
81 playlist.playlist_title = feed_title
82 playlist.video_list = ",".join(vid_ids)
83 playlist.sync_date = datetime.datetime.now()
84 playlist.save()
85
86 messages.info(request, "Synchronized %s (%s)" % (feed_title,
87 playlist.playlist_url))
88
89
90 admin.site.register(Playlist, PlaylistAdmin)