47f65b36ed435789f823abf0f0f0b29fae1d92e9
1 from datetime
import date
, timedelta
, datetime
3 from django
.http
import HttpResponseBadRequest
, HttpResponseRedirect
, Http404
4 from django
.db
import IntegrityError
5 from django
.shortcuts
import get_object_or_404
, render_to_response
6 from django
.template
import RequestContext
7 from django
.contrib
.auth
.decorators
import login_required
8 from django
.contrib
.sites
.models
import Site
9 from django
.utils
.translation
import ugettext
as _
11 from mygpo
.api
.models
import Podcast
, Episode
, EpisodeAction
, Device
, SubscriptionAction
, Subscription
, SUBSCRIBE_ACTION
, UNSUBSCRIBE_ACTION
, SyncGroup
12 from mygpo
.web
.forms
import PrivacyForm
, SyncForm
13 from mygpo
.data
.models
import Listener
, PodcastTag
14 from mygpo
.decorators
import manual_gc
, allowed_methods
15 from mygpo
.utils
import daterange
21 @allowed_methods(['GET', 'POST'])
22 def show(request
, pid
):
23 podcast
= get_object_or_404(Podcast
, pk
=pid
)
24 episodes
= episode_list(podcast
, request
.user
)
25 max_listeners
= max([x
.listeners
for x
in episodes
]) if len(episodes
) else 0
26 related_podcasts
= [x
for x
in podcast
.group
.podcasts() if x
!= podcast
] if podcast
.group
else []
28 tags
= get_tags(podcast
, request
.user
)
30 if request
.user
.is_authenticated():
31 devices
= Device
.objects
.filter(user
=request
.user
)
32 history
= SubscriptionAction
.objects
.filter(podcast
=podcast
,device__in
=devices
).order_by('-timestamp')
33 subscribed_devices
= [s
.device
for s
in Subscription
.objects
.filter(podcast
=podcast
,user
=request
.user
)]
34 subscribe_targets
= podcast
.subscribe_targets(request
.user
)
38 qs
= Subscription
.objects
.filter(podcast
=podcast
, user
=request
.user
)
39 if qs
.count()>0 and request
.user
.get_profile().public_profile
:
40 # subscription meta is valid for all subscriptions, so we get one - doesn't matter which
42 subscriptionmeta
= subscription
.get_meta()
43 if request
.method
== 'POST':
44 privacy_form
= PrivacyForm(request
.POST
)
45 if privacy_form
.is_valid():
46 subscriptionmeta
.settings
['public_subscription'] = privacy_form
.cleaned_data
['public']
48 subscriptionmeta
.save()
50 except IntegrityError
, ie
:
51 error_message
= _('You can\'t use the same Device ID for two devices.')
53 privacy_form
= PrivacyForm({
54 'public': subscriptionmeta
.public
60 subscribe_form
= SyncForm()
61 subscribe_form
.set_targets(subscribe_targets
, '')
63 timeline_data
= listener_data(podcast
)
64 return render_to_response('podcast.html', {
67 'timeline_data': timeline_data
,
69 'privacy_form': privacy_form
,
70 'devices': subscribed_devices
,
71 'related_podcasts': related_podcasts
,
72 'can_subscribe': len(subscribe_targets
) > 0,
73 'subscribe_form': subscribe_form
,
75 'max_listeners': max_listeners
,
77 }, context_instance
=RequestContext(request
))
79 current_site
= Site
.objects
.get_current()
80 return render_to_response('podcast.html', {
82 'related_podcasts': related_podcasts
,
86 'max_listeners': max_listeners
,
87 }, context_instance
=RequestContext(request
))
90 def get_tags(podcast
, user
):
92 for t
in PodcastTag
.objects
.filter(podcast
=podcast
).values('tag').distinct():
93 tag_str
= t
['tag'].lower()
96 if not user
.is_anonymous():
97 for t
in PodcastTag
.objects
.filter(podcast
=podcast
, user
=user
).values('tag').distinct():
98 tag_str
= t
['tag'].lower()
101 tag_list
= [{'tag': key
, 'is_own': value
} for key
, value
in tags
.iteritems()]
102 tag_list
.sort(key
=lambda x
: x
['tag'])
104 if len(tag_list
) > MAX_TAGS_ON_PAGE
:
105 tag_list
= filter(lambda x
: x
['is_own'], tag_list
)
106 tag_list
.append({'tag': '...', 'is_own': False})
111 def listener_data(podcast
):
114 episodes
= EpisodeAction
.objects
.filter(episode__podcast
=podcast
, timestamp__gte
=d
).order_by('timestamp').values('timestamp')
115 if len(episodes
) == 0:
118 start
= episodes
[0]['timestamp']
121 for d
in daterange(start
):
122 next
= d
+ timedelta(days
=1)
123 listeners
= EpisodeAction
.objects
.filter(episode__podcast
=podcast
, timestamp__gte
=d
, timestamp__lt
=next
).values('user_id').distinct().count()
124 e
= Episode
.objects
.filter(podcast
=podcast
, timestamp__gte
=d
, timestamp__lt
=next
)
125 episode
= e
[0] if e
.count() > 0 else None
128 'listeners': listeners
,
134 def episode_list(podcast
, user
):
136 Returns a list of episodes, with their action-attribute set to the latest
137 action. The attribute is unsert if there is no episode-action for
140 episodes
= Episode
.objects
.filter(podcast
=podcast
).order_by('-timestamp')
142 listeners
= Listener
.objects
.filter(episode
=e
).values('user').distinct()
143 e
.listeners
= listeners
.count()
145 if user
.is_authenticated():
146 actions
= EpisodeAction
.objects
.filter(episode
=e
, user
=user
).order_by('-timestamp')
147 if actions
.count() > 0:
148 e
.action
= actions
[0]
154 def add_tag(request
, pid
):
155 podcast
= get_object_or_404(Podcast
, id=pid
)
156 tag_str
= request
.GET
.get('tag', '')
158 return HttpResponseBadRequest()
160 tags
= tag_str
.split(',')
163 tag
= PodcastTag
.objects
.get_or_create(podcast
=podcast
, tag
=t
, source
='user', user
=request
.user
)
165 if request
.GET
.get('next', '') == 'mytags':
166 return HttpResponseRedirect('/tags/')
168 return HttpResponseRedirect('/podcast/%s' % pid
)
172 def remove_tag(request
, pid
):
173 podcast
= get_object_or_404(Podcast
, id=pid
)
174 tag_str
= request
.GET
.get('tag', '')
176 return HttpResponseBadRequest()
178 PodcastTag
.objects
.filter(podcast
=podcast
, tag
=tag_str
, source
='user', user
=request
.user
).delete()
180 if request
.GET
.get('next', '') == 'mytags':
181 return HttpResponseRedirect('/tags/')
183 return HttpResponseRedirect('/podcast/%s' % pid
)
188 @allowed_methods(['GET', 'POST'])
189 def subscribe(request
, pid
):
190 podcast
= get_object_or_404(Podcast
, pk
=pid
)
193 if request
.method
== 'POST':
194 form
= SyncForm(request
.POST
)
197 target
= form
.get_target()
199 if isinstance(target
, SyncGroup
):
200 device
= target
.devices()[0]
205 SubscriptionAction
.objects
.create(podcast
=podcast
, device
=device
, action
=SUBSCRIBE_ACTION
)
206 except IntegrityError
, e
:
207 log('error while subscribing to podcast (device %s, podcast %s)' % (device
.id, podcast
.id))
209 return HttpResponseRedirect('/podcast/%s' % podcast
.id)
211 except ValueError, e
:
212 error_message
= _('Could not subscribe to the podcast: %s' % e
)
214 targets
= podcast
.subscribe_targets(request
.user
)
217 form
.set_targets(targets
, _('Choose a device:'))
219 return render_to_response('subscribe.html', {
220 'error_message': error_message
,
222 'can_subscribe': len(targets
) > 0,
224 }, context_instance
=RequestContext(request
))
229 def unsubscribe(request
, pid
, device_id
):
231 return_to
= request
.GET
.get('return_to', None)
234 raise Http404('Wrong URL')
236 podcast
= get_object_or_404(Podcast
, pk
=pid
)
237 device
= Device
.objects
.get(pk
=device_id
)
239 SubscriptionAction
.objects
.create(podcast
=podcast
, device
=device
, action
=UNSUBSCRIBE_ACTION
, timestamp
=datetime
.now())
240 except IntegrityError
, e
:
241 log('error while unsubscribing from podcast (device %s, podcast %s)' % (device
.id, podcast
.id))
243 return HttpResponseRedirect(return_to
)
248 def subscribe_url(request
):
249 url
= request
.GET
.get('url', None)
252 raise Http404('http://my.gpodder.org/subscribe?url=http://www.example.com/podcast.xml')
254 url
= sanitize_url(url
)
257 raise Http404('Please specify a valid url')
259 podcast
, created
= Podcast
.objects
.get_or_create(url
=url
)
261 return HttpResponseRedirect('/podcast/%d/subscribe' % podcast
.pk
)