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
, 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
.listener_count() 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
= podcast
.get_episodes().order_by('-timestamp')
142 if user
.is_authenticated():
143 actions
= EpisodeAction
.objects
.filter(episode
=e
, user
=user
).order_by('-timestamp')
144 if actions
.count() > 0:
145 e
.action
= actions
[0]
151 def add_tag(request
, pid
):
152 podcast
= get_object_or_404(Podcast
, id=pid
)
153 tag_str
= request
.GET
.get('tag', '')
155 return HttpResponseBadRequest()
157 tags
= tag_str
.split(',')
160 tag
= PodcastTag
.objects
.get_or_create(podcast
=podcast
, tag
=t
, source
='user', user
=request
.user
)
162 if request
.GET
.get('next', '') == 'mytags':
163 return HttpResponseRedirect('/tags/')
165 return HttpResponseRedirect('/podcast/%s' % pid
)
169 def remove_tag(request
, pid
):
170 podcast
= get_object_or_404(Podcast
, id=pid
)
171 tag_str
= request
.GET
.get('tag', '')
173 return HttpResponseBadRequest()
175 PodcastTag
.objects
.filter(podcast
=podcast
, tag
=tag_str
, source
='user', user
=request
.user
).delete()
177 if request
.GET
.get('next', '') == 'mytags':
178 return HttpResponseRedirect('/tags/')
180 return HttpResponseRedirect('/podcast/%s' % pid
)
185 @allowed_methods(['GET', 'POST'])
186 def subscribe(request
, pid
):
187 podcast
= get_object_or_404(Podcast
, pk
=pid
)
190 if request
.method
== 'POST':
191 form
= SyncForm(request
.POST
)
194 target
= form
.get_target()
196 if isinstance(target
, SyncGroup
):
197 device
= target
.devices()[0]
202 podcast
.subscribe(device
)
203 except IntegrityError
, e
:
204 log('error while subscribing to podcast (device %s, podcast %s)' % (device
.id, podcast
.id))
206 return HttpResponseRedirect('/podcast/%s' % podcast
.id)
208 except ValueError, e
:
209 error_message
= _('Could not subscribe to the podcast: %s' % e
)
211 targets
= podcast
.subscribe_targets(request
.user
)
214 form
.set_targets(targets
, _('Choose a device:'))
216 return render_to_response('subscribe.html', {
217 'error_message': error_message
,
219 'can_subscribe': len(targets
) > 0,
221 }, context_instance
=RequestContext(request
))
226 def unsubscribe(request
, pid
, device_id
):
228 return_to
= request
.GET
.get('return_to', None)
231 raise Http404('Wrong URL')
233 podcast
= get_object_or_404(Podcast
, pk
=pid
)
234 device
= Device
.objects
.get(pk
=device_id
)
236 podcast
.unsubscribe(device
)
237 except IntegrityError
, e
:
238 log('error while unsubscribing from podcast (device %s, podcast %s)' % (device
.id, podcast
.id))
240 return HttpResponseRedirect(return_to
)
245 def subscribe_url(request
):
246 url
= request
.GET
.get('url', None)
249 raise Http404('http://my.gpodder.org/subscribe?url=http://www.example.com/podcast.xml')
251 url
= sanitize_url(url
)
254 raise Http404('Please specify a valid url')
256 podcast
, created
= Podcast
.objects
.get_or_create(url
=url
)
258 return HttpResponseRedirect('/podcast/%d/subscribe' % podcast
.pk
)