1 from datetime
import datetime
3 from mygpo
.api
import APIView
, RequestException
4 from mygpo
.api
.httpresponse
import JsonResponse
5 from mygpo
.api
.exceptions
import ParameterMissing
6 from mygpo
.chapters
.models
import Chapter
7 from mygpo
.utils
import parse_time
, normalize_feed_url
, get_timestamp
10 class ChaptersAPI(APIView
):
12 def post(self
, request
, username
):
13 """ Add / remove Chapters to/from an episode """
15 now_
= get_timestamp(datetime
.utcnow())
17 body
= self
.parsed_body(request
)
19 podcast_url
, episode_url
, update_urls
= self
.get_urls(body
)
20 body
['podcast'] = podcast_url
21 body
['episode'] = episode_url
23 if not podcast_url
or not episode_url
:
24 raise RequestException('Invalid Podcast or Episode URL')
26 self
.update_chapters(body
, user
)
28 'update_url': update_urls
,
32 def get(self
, request
, username
):
33 """ Get chapters for an episode """
35 now_
= get_timestamp(datetime
.utcnow())
37 podcast_url
, episode_url
, _update_urls
= self
.get_urls(request
)
39 episode
= Episode
.objects
.filter(podcast__urls__url
=podcast_url
,
40 urls__url
=episode_url
).get()
42 chapters
= Chapter
.objects
.filter(user
=user
, episode
=episode
)
44 since
= self
.get_since(request
)
46 chapters
= chapters
.filter(created__gte
=since
)
48 chapters_json
= map(self
.chapter_to_json
, chapters
)
51 'chapters': chapters_json
,
55 def update_chapters(self
, req
, user
):
56 """ Add / remove chapters according to the client's request """
57 podcast
= Podcast
.objects
.get_or_create_for_url(podcast_url
)
58 episode
= Episode
.objects
.get_or_create_for_url(podcast
, episode_url
)
61 for chapter_data
in req
.get('chapters_add', []):
62 chapter
= self
.parse_new(user
, chapter_data
)
66 for chapter_data
in req
.get('chapters_remove', []):
67 start
, end
= self
.parse_rem(chapter_data
)
68 Chapter
.objects
.filter(user
=user
, episode
=episode
,
69 start
=start
, end
=end
)\
72 def parse_new(self
, user
, chapter_data
):
73 """ Parse a chapter to be added """
75 if not 'start' in chapter_data
:
76 raise ParameterMissing('start parameter missing')
77 chapter
.start
= parse_time(chapter_data
['start'])
79 if not 'end' in chapter_data
:
80 raise ParameterMissing('end parameter missing')
81 chapter
.end
= parse_time(chapter_data
['end'])
83 chapter
.label
= chapter_data
.get('label', '')
84 chapter
.advertisement
= chapter_data
.get('advertisement', False)
87 def parse_rem(self
, chapter_data
):
88 """ Parse a chapter to be removed """
89 if not 'start' in chapter_data
:
90 raise ParameterMissing('start parameter missing')
91 start
= parse_time(chapter_data
['start'])
93 if not 'end' in chapter_data
:
94 raise ParameterMissing('end parameter missing')
95 end
= parse_time(chapter_data
['end'])
99 def get_urls(self
, body
):
100 """ Parse and normalize the URLs from the request """
101 podcast_url
= body
.get('podcast', '')
102 episode_url
= body
.get('episode', '')
105 raise RequestException('Podcast URL missing')
108 raise RequestException('Episode URL missing')
113 s_podcast_url
= normalize_feed_url(podcast_url
)
114 if s_podcast_url
!= podcast_url
:
115 update_urls
.append((podcast_url
, s_podcast_url
or ''))
118 s_episode_url
= normalize_feed_url(episode_url
, 'episode')
119 if s_episode_url
!= episode_url
:
120 update_urls
.append((episode_url
, s_episode_url
or ''))
122 return s_podcast_url
, s_episode_url
, update_urls
124 def chapter_to_json(self
, chapter
):
125 """ JSON representation of Chapter for GET response """
127 'start': chapter
.start
,
129 'label': chapter
.label
,
130 'advertisement': chapter
.advertisement
,
131 'timestamp': chapter
.created
,