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
):
11 def post(self
, request
, username
):
12 """Add / remove Chapters to/from an episode"""
14 now_
= get_timestamp(datetime
.utcnow())
16 body
= self
.parsed_body(request
)
18 podcast_url
, episode_url
, update_urls
= self
.get_urls(body
)
19 body
["podcast"] = podcast_url
20 body
["episode"] = episode_url
22 if not podcast_url
or not episode_url
:
23 raise RequestException("Invalid Podcast or Episode URL")
25 self
.update_chapters(body
, user
)
26 return JsonResponse({"update_url": update_urls
, "timestamp": now_
})
28 def get(self
, request
, username
):
29 """Get chapters for an episode"""
31 now_
= get_timestamp(datetime
.utcnow())
33 podcast_url
, episode_url
, _update_urls
= self
.get_urls(request
)
35 episode
= Episode
.objects
.filter(
36 podcast__urls__url
=podcast_url
, urls__url
=episode_url
39 chapters
= Chapter
.objects
.filter(user
=user
, episode
=episode
)
41 since
= self
.get_since(request
)
43 chapters
= chapters
.filter(created__gte
=since
)
45 chapters_json
= map(self
.chapter_to_json
, chapters
)
47 return JsonResponse({"chapters": chapters_json
, "timestamp": now_
})
49 def update_chapters(self
, req
, user
):
50 """Add / remove chapters according to the client's request"""
51 podcast
= Podcast
.objects
.get_or_create_for_url(podcast_url
).object
52 episode
= Episode
.objects
.get_or_create_for_url(podcast
, episode_url
).object
55 for chapter_data
in req
.get("chapters_add", []):
56 chapter
= self
.parse_new(user
, chapter_data
)
60 for chapter_data
in req
.get("chapters_remove", []):
61 start
, end
= self
.parse_rem(chapter_data
)
62 Chapter
.objects
.filter(
63 user
=user
, episode
=episode
, start
=start
, end
=end
66 def parse_new(self
, user
, chapter_data
):
67 """Parse a chapter to be added"""
69 if not "start" in chapter_data
:
70 raise ParameterMissing("start parameter missing")
71 chapter
.start
= parse_time(chapter_data
["start"])
73 if not "end" in chapter_data
:
74 raise ParameterMissing("end parameter missing")
75 chapter
.end
= parse_time(chapter_data
["end"])
77 chapter
.label
= chapter_data
.get("label", "")
78 chapter
.advertisement
= chapter_data
.get("advertisement", False)
81 def parse_rem(self
, chapter_data
):
82 """Parse a chapter to be removed"""
83 if not "start" in chapter_data
:
84 raise ParameterMissing("start parameter missing")
85 start
= parse_time(chapter_data
["start"])
87 if not "end" in chapter_data
:
88 raise ParameterMissing("end parameter missing")
89 end
= parse_time(chapter_data
["end"])
93 def get_urls(self
, body
):
94 """Parse and normalize the URLs from the request"""
95 podcast_url
= body
.get("podcast", "")
96 episode_url
= body
.get("episode", "")
99 raise RequestException("Podcast URL missing")
102 raise RequestException("Episode URL missing")
107 s_podcast_url
= normalize_feed_url(podcast_url
)
108 if s_podcast_url
!= podcast_url
:
109 update_urls
.append((podcast_url
, s_podcast_url
or ""))
112 s_episode_url
= normalize_feed_url(episode_url
, "episode")
113 if s_episode_url
!= episode_url
:
114 update_urls
.append((episode_url
, s_episode_url
or ""))
116 return s_podcast_url
, s_episode_url
, update_urls
118 def chapter_to_json(self
, chapter
):
119 """JSON representation of Chapter for GET response"""
121 "start": chapter
.start
,
123 "label": chapter
.label
,
124 "advertisement": chapter
.advertisement
,
125 "timestamp": chapter
.created
,