Skip to content

Commit

Permalink
Implement Episode.season
Browse files Browse the repository at this point in the history
Fixes #102
  • Loading branch information
tobinus committed Dec 9, 2019
1 parent 903a4bf commit 1584b5c
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 0 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added

- Support for the [new Apple Podcast categories][category-new-2019] that were [added August 9th 2019][category-published-2019].
- Support for `Episode.episode_type` for indicating whether an episode
constains a full episode, a trailer or bonus material.
- Support for `Episode.season` for indicating what season the episode belongs
to.
- Documentation of the Warning classes defined by PodGen.

[category-new-2019]: https://podnews.net/article/apple-changed-podcast-categories-2019
Expand Down
1 change: 1 addition & 0 deletions podgen/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ def main():
e1 = p.add_episode()
e1.id = 'http://lernfunk.de/_MEDIAID_123#1'
e1.title = 'First Element'
e1.season = 1
e1.summary = htmlencode('''Lorem ipsum dolor sit amet, consectetur adipiscing elit. Tamen
aberramus a proposito, et, ne longius, prorsus, inquam, Piso, si ista
mala sunt, placet. Aut etiam, ut vestitum, sic sententiam habeas aliam
Expand Down
35 changes: 35 additions & 0 deletions podgen/episode.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,8 @@ def __init__(self, **kwargs):

self.__position = None

self.__season = None

self.__episode_type = EPISODE_TYPE_FULL

self.subtitle = None
Expand Down Expand Up @@ -310,6 +312,13 @@ def rss_entry(self):
)
episode_type.text = self.__episode_type

if self.__season is not None:
season = etree.SubElement(
entry,
'{%s}season' % ITUNES_NS
)
season.text = str(self.__season)

if self.__position is not None and self.__position >= 0:
order = etree.SubElement(entry, '{%s}order' % ITUNES_NS)
order.text = str(self.__position)
Expand Down Expand Up @@ -569,6 +578,32 @@ def episode_type(self, episode_type):

self.__episode_type = as_str

@property
def season(self):
"""The number of the season this episode belongs to.
By default, the episode belongs to no season, indicated by this
attribute being set to :obj:`None`.
Some podcast applications may choose to show season numbers only when
there is more than one season.
:type: :obj:`None` or positive :obj:`int`
:RSS: itunes:season
"""
return self.__season

@season.setter
def season(self, season):
if season is None:
self.__season = None
else:
as_int = int(season)
if as_int <= 0:
raise ValueError('Season number must be a positive, non-zero '
'integer; not "%s"' % as_int)
self.__season = as_int

@property
def position(self):
"""A custom position for this episode on the iTunes store page.
Expand Down
56 changes: 56 additions & 0 deletions podgen/tests/test_episode.py
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,49 @@ def get_element():
assert get_element() is not None
self.assertEqual(get_element().text.lower(), "yes")

def test_season(self):
def get_element():
return self.fe.rss_entry()\
.find("{%s}season" % self.itunes_ns)

# Starts out as None
assert self.fe.season is None

# Not used when set to None
assert get_element() is None

# Can be set
self.fe.season = 3
self.assertEqual(self.fe.season, 3)

# Is used when set
assert get_element() is not None
self.assertEqual(get_element().text, "3")

# Can be set to something that can be converted to int
self.fe.season = "5"
self.assertEqual(self.fe.season, 5)
assert get_element() is not None
self.assertEqual(get_element().text, "5")

# Can be reset to None
self.fe.season = None
assert self.fe.season is None
assert get_element() is None

# Gives error when set to something that cannot be converted to int
with self.assertRaises(ValueError):
self.fe.season = "Best Season"

# Gives error when set to zero
with self.assertRaises(ValueError):
self.fe.season = 0

# Gives error when set to negative number
with self.assertRaises(ValueError):
self.fe.season = -1


def test_episodeType(self):
def get_element():
return self.fe.rss_entry()\
Expand All @@ -526,14 +569,27 @@ def get_element():

# Used when set to "trailer"
self.fe.episode_type = EPISODE_TYPE_TRAILER
self.assertEqual(self.fe.episode_type, EPISODE_TYPE_TRAILER)
assert get_element() is not None
self.assertEqual(get_element().text.lower(), "trailer")

# Used when set to "bonus"
self.fe.episode_type = EPISODE_TYPE_BONUS
self.assertEqual(self.fe.episode_type, EPISODE_TYPE_BONUS)
assert get_element() is not None
self.assertEqual(get_element().text.lower(), "bonus")

# Can be set to something that evaluates to "trailer" or "bonus" when
# converted to str()
class IsEpisodeTypeWhenStr:
def __str__(self):
return EPISODE_TYPE_TRAILER

self.fe.episode_type = IsEpisodeTypeWhenStr()
self.assertEqual(self.fe.episode_type, EPISODE_TYPE_TRAILER)
assert get_element() is not None
self.assertEqual(get_element().text.lower(), "trailer")

# Fails when set to anything else
with self.assertRaises(ValueError):
self.fe.episode_type = "banana"
Expand Down

0 comments on commit 1584b5c

Please sign in to comment.