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 HttpResponseBadRequest
20 from mygpo
.api
.httpresponse
import JsonResponse
21 from mygpo
.exceptions
import ParameterMissing
22 from mygpo
.api
.sanitizing
import sanitize_url
23 from mygpo
.api
.models
import Device
, Podcast
, Episode
24 from mygpo
.api
.models
.episodes
import Chapter
25 from django
.utils
.translation
import ugettext
as _
26 from datetime
import datetime
27 from mygpo
.utils
import parse_time
28 from mygpo
.decorators
import allowed_methods
29 import dateutil
.parser
30 from django
.views
.decorators
.csrf
import csrf_exempt
33 #try to import the JSON module (if we are on Python 2.6)
36 # Python 2.5 seems to have a different json module
37 if not 'dumps' in dir(json
):
41 # No JSON module available - fallback to simplejson (Python < 2.6)
42 print "No JSON module available - fallback to simplejson (Python < 2.6)"
43 import simplejson
as json
49 @allowed_methods(['POST', 'GET'])
50 def chapters(request
, username
):
53 now_
= int(mktime(now
.timetuple()))
55 if request
.method
== 'POST':
56 req
= json
.loads(request
.raw_post_data
)
58 if not 'podcast' in req
:
59 return HttpResponseBadRequest('Podcast URL missing')
61 if not 'episode' in req
:
62 return HttpResponseBadRequest('Episode URL missing')
64 podcast_url
= req
.get('podcast', '')
65 episode_url
= req
.get('episode', '')
69 s_podcast_url
= sanitize_url(podcast_url
)
70 if s_podcast_url
!= podcast_url
:
71 req
['podcast'] = s_podcast_url
72 update_urls
.append((podcast_url
, s_podcast_url
))
75 s_episode_url
= sanitize_url(episode_url
, podcast
=False, episode
=True)
76 if s_episode_url
!= episode_url
:
77 req
['episode'] = s_episode_url
78 update_urls
.append((episode_url
, s_episode_url
))
80 if (s_podcast_url
!= '') and (s_episode_url
!= ''):
82 update_chapters(req
, request
.user
)
83 except ParameterMissing
, e
:
84 return HttpResponseBadRequest(e
)
87 'update_url': update_url
,
91 elif request
.method
== 'GET':
92 if not 'podcast' in request
.GET
:
93 return HttpResponseBadRequest('podcast URL missing')
95 if not 'episode' in request
.GET
:
96 return HttpResponseBadRequest('Episode URL missing')
98 podcast_url
= request
.GET
['podcast']
99 episode_url
= request
.GET
['episode']
101 since_
= request
.GET
.get('since', None)
102 since
= datetime
.fromtimestamp(float(since_
)) if since_
else None
104 podcast
= Podcast
.objects
.get(url
=sanitize_url(podcast_url
))
105 episode
= Episode
.objects
.get(url
=sanitize_url(episode_url
, podcast
=False, episode
=True), podcast
=podcast
)
106 chapter_q
= Chapter
.objects
.filter(user
=request
.user
, episode
=episode
).order_by('start')
109 chapter_q
= chapter_q
.filter(timestamp__gt
=since
)
117 'advertisement': c
.advertisement
,
118 'timestamp': c
.created
,
119 'device': c
.device
.uid
122 return JsonResponse({
123 'chapters': chapters
,
128 def update_chapters(req
, user
):
129 podcast
, c
= Podcast
.objects
.get_or_create(url
=req
['podcast'])
130 episode
, c
= Episode
.objects
.get_or_create(url
=req
['episode'], podcast
=podcast
)
134 device
, c
= Device
.objects
.get_or_create(user
=user
, uid
=req
['device'], defaults
= {'type': 'other', 'name': _('New Device')})
136 timestamp
= dateutil
.parser
.parse(req
['timestamp']) if 'timestamp' in req
else datetime
.now()
138 for c
in req
.get('chapters_add', []):
140 raise ParameterMissing('start parameter missing')
141 start
= parse_time(c
['start'])
144 raise ParameterMissing('end parameter missing')
145 end
= parse_time(c
['end'])
147 label
= c
.get('label', '')
148 adv
= c
.get('advertisement', False)
151 Chapter
.objects
.create(
162 for c
in req
.get('chapters_remove', []):
164 raise ParameterMissing('start parameter missing')
165 start
= parse_time(c
['start'])
168 raise ParameterMissing('end parameter missing')
169 end
= parse_time(c
['end'])
171 Chapter
.objects
.filter(