bgneal@60
|
1 """
|
bgneal@60
|
2 Automatic admin definitions for the videos application.
|
bgneal@60
|
3
|
bgneal@60
|
4 """
|
bgneal@60
|
5 import datetime
|
bgneal@60
|
6 import urlparse
|
bgneal@60
|
7
|
bgneal@62
|
8 try:
|
bgneal@62
|
9 from urlparse import parse_qs
|
bgneal@62
|
10 except ImportError:
|
bgneal@62
|
11 from cgi import parse_qs # for Python 2.5
|
bgneal@62
|
12
|
bgneal@60
|
13 from django.contrib import admin
|
bgneal@60
|
14 from django.contrib import messages
|
bgneal@60
|
15 from gdata.youtube.service import YouTubeService
|
bgneal@60
|
16
|
bgneal@60
|
17 from videos.models import Playlist
|
bgneal@60
|
18
|
bgneal@60
|
19
|
bgneal@60
|
20 class PlaylistAdmin(admin.ModelAdmin):
|
bgneal@60
|
21 list_display = ['__unicode__', 'playlist_url', 'sync_date']
|
bgneal@60
|
22 readonly_fields = ['playlist_title', 'video_list', 'sync_date']
|
bgneal@60
|
23 actions = ['sync']
|
bgneal@60
|
24
|
bgneal@60
|
25 def sync(self, request, queryset):
|
bgneal@60
|
26 for playlist in queryset:
|
bgneal@60
|
27 self.sync_playlist(request, playlist)
|
bgneal@60
|
28
|
bgneal@60
|
29 sync.short_description = 'Synchronize with YouTube'
|
bgneal@60
|
30
|
bgneal@60
|
31 def sync_playlist(self, request, playlist):
|
bgneal@60
|
32 """
|
bgneal@60
|
33 Retrieve the title and list of videos for a
|
bgneal@60
|
34 YouTube playlist.
|
bgneal@60
|
35
|
bgneal@60
|
36 """
|
bgneal@60
|
37 # Find the playlist ID:
|
bgneal@60
|
38 parts = urlparse.urlparse(playlist.playlist_url)
|
bgneal@62
|
39 query = parse_qs(parts.query)
|
bgneal@60
|
40 if 'list' not in query:
|
bgneal@60
|
41 messages.error(request, 'Invalid playlist %s' %
|
bgneal@60
|
42 playlist.playlist_url)
|
bgneal@60
|
43 return
|
bgneal@60
|
44
|
bgneal@60
|
45 playlist_id = query['list'][0]
|
bgneal@60
|
46 if not playlist_id.startswith('PL'):
|
bgneal@60
|
47 messages.error(request, 'Invalid playlist ID in %s' %
|
bgneal@60
|
48 playlist.playlist_url)
|
bgneal@60
|
49 return
|
bgneal@60
|
50 playlist_id = playlist_id[2:]
|
bgneal@60
|
51
|
bgneal@60
|
52 # Get the playlist feed:
|
bgneal@60
|
53 yt = YouTubeService()
|
bgneal@60
|
54 feed = yt.GetYouTubePlaylistVideoFeed(playlist_id=playlist_id)
|
bgneal@60
|
55 feed_title = feed.title.text
|
bgneal@60
|
56 expected_count = int(feed.total_results.text)
|
bgneal@60
|
57
|
bgneal@60
|
58 # Get all the videos in the feed; this may take multiple requests:
|
bgneal@60
|
59 vids = []
|
bgneal@60
|
60 while True:
|
bgneal@60
|
61 vids.extend(feed.entry)
|
bgneal@60
|
62 next_link = feed.GetNextLink()
|
bgneal@60
|
63 if not next_link:
|
bgneal@60
|
64 break
|
bgneal@60
|
65 feed = yt.Query(next_link.href)
|
bgneal@60
|
66
|
bgneal@60
|
67 if len(vids) != expected_count:
|
bgneal@60
|
68 messages.error(request, "%s: expected %d videos, got %d" %
|
bgneal@60
|
69 (playlist.playlist_url, expected_count, len(vids)))
|
bgneal@60
|
70
|
bgneal@60
|
71 # Find the video ID for each video
|
bgneal@60
|
72
|
bgneal@60
|
73 vid_ids = []
|
bgneal@60
|
74 for vid in vids:
|
bgneal@60
|
75 for link in vid.link:
|
bgneal@60
|
76 parts = urlparse.urlparse(link.href)
|
bgneal@62
|
77 query = parse_qs(parts.query)
|
bgneal@60
|
78 if 'v' in query:
|
bgneal@60
|
79 vid_ids.append(query['v'][0])
|
bgneal@60
|
80 break
|
bgneal@60
|
81 else:
|
bgneal@60
|
82 messages.error(request, "%s: video id not found for %s" %
|
bgneal@60
|
83 (playlist.playlist_url, vid.title.text))
|
bgneal@60
|
84
|
bgneal@60
|
85 # Okay, save what we got
|
bgneal@60
|
86 playlist.playlist_title = feed_title
|
bgneal@60
|
87 playlist.video_list = ",".join(vid_ids)
|
bgneal@60
|
88 playlist.sync_date = datetime.datetime.now()
|
bgneal@60
|
89 playlist.save()
|
bgneal@60
|
90
|
bgneal@60
|
91 messages.info(request, "Synchronized %s (%s)" % (feed_title,
|
bgneal@60
|
92 playlist.playlist_url))
|
bgneal@60
|
93
|
bgneal@60
|
94
|
bgneal@60
|
95 admin.site.register(Playlist, PlaylistAdmin)
|