@allowed_methods to check for correct HTTP method
[mygpo.git] / mygpo / api / advanced / episode.py
blob9e03b3269e5f2e51bfc8ef008b06418563205cfa
2 # This file is part of my.gpodder.org.
4 # my.gpodder.org is free software: you can redistribute it and/or modify it
5 # under the terms of the GNU Affero General Public License as published by
6 # the Free Software Foundation, either version 3 of the License, or (at your
7 # option) any later version.
9 # my.gpodder.org is distributed in the hope that it will be useful, but
10 # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
12 # License for more details.
14 # You should have received a copy of the GNU Affero General Public License
15 # along with my.gpodder.org. If not, see <http://www.gnu.org/licenses/>.
18 from mygpo.api.basic_auth import require_valid_user, check_username
19 from django.http import HttpResponse, HttpResponseBadRequest, HttpResponseForbidden, Http404
20 from mygpo.api.httpresponse import JsonResponse
21 from mygpo.exceptions import ParameterMissing
22 from django.shortcuts import get_object_or_404
23 from mygpo.api.sanitizing import sanitize_url
24 from mygpo.api.models import Device, Podcast, Episode
25 from mygpo.api.models.episodes import Chapter
26 from django.utils.translation import ugettext as _
27 from datetime import datetime, timedelta
28 from mygpo.log import log
29 from mygpo.utils import parse_time
30 from mygpo.decorators import allowed_methods
31 import dateutil.parser
32 from django.views.decorators.csrf import csrf_exempt
34 try:
35 #try to import the JSON module (if we are on Python 2.6)
36 import json
38 # Python 2.5 seems to have a different json module
39 if not 'dumps' in dir(json):
40 raise ImportError
42 except ImportError:
43 # No JSON module available - fallback to simplejson (Python < 2.6)
44 print "No JSON module available - fallback to simplejson (Python < 2.6)"
45 import simplejson as json
48 @csrf_exempt
49 @require_valid_user
50 @check_username
51 @allowed_methods(['POST', 'GET'])
52 def chapters(request, username):
54 now = datetime.now()
55 now_ = int(mktime(now.timetuple()))
57 if request.method == 'POST':
58 req = json.loads(request.raw_post_data)
60 if not 'podcast' in req:
61 return HttpResponseBadRequest('Podcast URL missing')
63 if not 'episode' in req:
64 return HttpResponseBadRequest('Episode URL missing')
66 podcast_url = req.get('podcast', '')
67 episode_url = req.get('episode', '')
68 update_urls = []
70 # podcast sanitizing
71 s_podcast_url = sanitize_url(podcast_url)
72 if s_podcast_url != podcast_url:
73 req['podcast'] = s_podcast_url
74 update_urls.append((podcast_url, s_podcast_url))
76 # episode sanitizing
77 s_episode_url = sanitize_url(episode_url, podcast=False, episode=True)
78 if s_episode_url != episode_url:
79 req['episode'] = s_episode_url
80 update_urls.append((episode_url, s_episode_url))
82 if (s_podcast_url != '') and (s_episode_url != ''):
83 try:
84 update_chapters(req, request.user)
85 except ParameterMissing, e:
86 return HttpResponseBadRequest(e)
88 return JsonResponse({
89 'update_url': update_url,
90 'timestamp': now_
93 elif request.method == 'GET':
94 if not 'podcast' in request.GET:
95 return HttpResponseBadRequest('podcast URL missing')
97 if not 'episode' in request.GET:
98 return HttpResponseBadRequest('Episode URL missing')
100 podcast_url = request.GET['podcast']
101 episode_url = request.GET['episode']
103 since_ = request.GET.get('since', None)
104 since = datetime.fromtimestamp(float(since_)) if since_ else None
106 podcast = Podcast.objects.get(url=sanitize_url(podcast_url))
107 episode = Episode.objects.get(url=sanitize_url(episode_url, podcast=False, episode=True), podcast=podcast)
108 chapter_q = Chapter.objects.filter(user=request.user, episode=episode).order_by('start')
110 if since:
111 chapter_q = chapter_q.filter(timestamp__gt=since)
113 chapters = []
114 for c in chapter_q:
115 chapters.append({
116 'start': c.start,
117 'end': c.end,
118 'label': c.label,
119 'advertisement': c.advertisement,
120 'timestamp': c.created,
121 'device': c.device.uid
124 return JsonResponse({
125 'chapters': chapters,
126 'timestamp': now_
130 def update_chapters(req, user):
131 podcast, c = Podcast.objects.get_or_create(url=req['podcast'])
132 episode, c = Episode.objects.get_or_create(url=req['episode'], podcast=podcast)
134 device = None
135 if 'device' in req:
136 device, c = Device.objects.get_or_create(user=user, uid=req['device'], defaults = {'type': 'other', 'name': _('New Device')})
138 timestamp = dateutil.parser.parse(req['timestamp']) if 'timestamp' in req else datetime.now()
140 for c in req.get('chapters_add', []):
141 if not 'start' in c:
142 raise ParameterMissing('start parameter missing')
143 start = parse_time(c['start'])
145 if not 'end' in c:
146 raise ParameterMissing('end parameter missing')
147 end = parse_time(c['end'])
149 label = c.get('label', '')
150 adv = c.get('advertisement', False)
153 Chapter.objects.create(
154 user=user,
155 episode=episode,
156 device=device,
157 created=timestamp,
158 start=start,
159 end=end,
160 label=label,
161 advertisement=adv)
164 for c in req.get('chapters_remove', []):
165 if not 'start' in c:
166 raise ParameterMissing('start parameter missing')
167 start = parse_time(c['start'])
169 if not 'end' in c:
170 raise ParameterMissing('end parameter missing')
171 end = parse_time(c['end'])
173 Chapter.objects.filter(
174 user=user,
175 episode=episode,
176 start=start,
177 end=end).delete()