Skip to content

Commit 048d1b1

Browse files
committed
Finish improving the documentation
The other modules have now had their documentation read through and improved. This concludes the work on improving the documentation for now.
1 parent f88b0af commit 048d1b1

File tree

5 files changed

+213
-86
lines changed

5 files changed

+213
-86
lines changed

podgen/category.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,13 +95,19 @@ def __init__(self, category, subcategory=None):
9595

9696
@property
9797
def category(self):
98-
"""The category represented by this object. Read-only."""
98+
"""The category represented by this object. Read-only.
99+
100+
:type: :obj:`str`
101+
"""
99102
return self.__category
100103
# Make this attribute read-only by not implementing setter
101104

102105
@property
103106
def subcategory(self):
104-
"""The subcategory this object represents. Read-only."""
107+
"""The subcategory this object represents. Read-only.
108+
109+
:type: :obj:`str`
110+
"""
105111
return self.__subcategory
106112
# Make this attribute read-only by not implementing setter
107113

podgen/episode.py

Lines changed: 119 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class Episode(object):
4040
ValueError if you set an attribute to an invalid value.
4141
4242
You must have filled in either :attr:`.title` or :attr:`.summary` before
43-
the RSS is generated.
43+
the RSS can be generated.
4444
4545
To add an episode to a podcast::
4646
@@ -51,12 +51,12 @@ class Episode(object):
5151
5252
You may also replace the last two lines with a shortcut::
5353
54-
>>> episode = p.add_episode(Episode())
54+
>>> episode = p.add_episode(podgen.Episode())
5555
5656
5757
.. seealso::
5858
59-
The :doc:`Basic Usage Guide </user/basic_usage_guide/part_2>`
59+
:doc:`/user/basic_usage_guide/part_2`
6060
A friendlier introduction to episodes.
6161
"""
6262

@@ -79,19 +79,24 @@ def __init__(self, **kwargs):
7979
up to 4000 characters in length.
8080
8181
See also :py:attr:`.Episode.subtitle` and
82-
:py:attr:`.Episode.long_summary`."""
82+
:py:attr:`.Episode.long_summary`.
83+
84+
:type: :obj:`str` which can be parsed as XHTML.
85+
:RSS: description"""
8386

8487
self.long_summary = None
8588
"""A long (read: full) summary, which supplements the shorter
86-
:attr:`~podgen.Episode.summary`.
89+
:attr:`~podgen.Episode.summary`. Like summary, this must be compatible
90+
with XHTML parsers; use :func:`podgen.htmlencode` if this isn't HTML.
8791
8892
This attribute should be seen as a full, longer variation of
8993
summary if summary exists. Even then, the long_summary should be
9094
independent from summary, in that you only need to read one of them.
9195
This means you may have to repeat the first sentences.
9296
93-
If summary does not exist but this does, this is used in place of
94-
summary."""
97+
:type: :obj:`str` which can be parsed as XHTML.
98+
:RSS: content:encoded or description
99+
"""
95100

96101
self.__media = None
97102

@@ -101,7 +106,7 @@ def __init__(self, **kwargs):
101106
If not present, the URL of the enclosed media is used. This is usually
102107
the best way to go, **as long as the media URL doesn't change**.
103108
104-
Set the id to boolean False if you don't want to associate any id to
109+
Set the id to boolean ``False`` if you don't want to associate any id to
105110
this episode.
106111
107112
It is important that an episode keeps the same ID until the end of time,
@@ -116,17 +121,28 @@ def __init__(self, **kwargs):
116121
domain which you own (for example, use something like
117122
http://example.org/podcast/episode1 if you own example.org).
118123
119-
This property corresponds to the RSS GUID element."""
124+
:type: :obj:`str`, :obj:`None` to use default or :obj:`False` to leave
125+
out.
126+
:RSS: guid
127+
"""
120128

121129
self.link = None
122-
"""The link to the full version of this episode description.
123-
Remember to start the link with the scheme, e.g. https://."""
130+
"""The link to the full version of this episode's :attr:`.summary`.
131+
Remember to start the link with the scheme, e.g. https://.
132+
133+
:type: :obj:`str`
134+
:RSS: link
135+
"""
124136

125137
self.__publication_date = None
126138

127139
self.title = None
128140
"""This episode's human-readable title.
129-
Title is mandatory and should not be blank."""
141+
Title is mandatory and should not be blank.
142+
143+
:type: :obj:`str`
144+
:RSS: title
145+
"""
130146

131147
# ITunes tags
132148
# http://www.apple.com/itunes/podcasts/specs.html#rss
@@ -138,20 +154,27 @@ def __init__(self, **kwargs):
138154

139155
self.__explicit = None
140156

141-
self.is_closed_captioned = None
142-
"""Whether this podcast includes a video episode with embedded closed
143-
captioning support.
157+
self.is_closed_captioned = False
158+
"""Whether this podcast includes a video episode with embedded `closed
159+
captioning`_ support. Defaults to ``False``.
144160
145-
The two values for this tag are ``True`` and
146-
``False``."""
161+
:type: :obj:`bool`
162+
:RSS: itunes:isClosedCaptioned
163+
164+
.. _closed captioning: https://en.wikipedia.org/wiki/Closed_captioning
165+
"""
147166

148167
self.__position = None
149168

150169
self.subtitle = None
151170
"""A short subtitle.
152171
153172
This is shown in the Description column in iTunes.
154-
The subtitle displays best if it is only a few words long."""
173+
The subtitle displays best if it is only a few words long.
174+
175+
:type: :obj:`str`
176+
:RSS: itunes:subtitle
177+
"""
155178

156179
# It is time to assign the keyword arguments
157180
for attribute, value in iteritems(kwargs):
@@ -162,7 +185,13 @@ def __init__(self, **kwargs):
162185
"recognized!" % (attribute, value))
163186

164187
def rss_entry(self):
165-
"""Create a RSS item and return it."""
188+
"""Create an RSS item using lxml's etree and return it.
189+
190+
This is primarily used by :class:`podgen.Podcast` when generating the
191+
podcast's RSS feed.
192+
193+
:returns: etree.Element('item')
194+
"""
166195

167196
ITUNES_NS = 'http://www.itunes.com/dtds/podcast-1.0.dtd'
168197
DUBLIN_NS = 'http://purl.org/dc/elements/1.1/'
@@ -279,8 +308,8 @@ def authors(self):
279308
"""List of :class:`~podgen.Person` that contributed to this
280309
episode.
281310
282-
The authors don't need to have both name and email set. The names are
283-
shown under the podcast's title on iTunes.
311+
The authors don't need to have both name and email set. They're usually
312+
not displayed anywhere.
284313
285314
.. note::
286315
@@ -308,6 +337,9 @@ def authors(self):
308337
>>> # Or assign a new list (discarding earlier authors)
309338
>>> ep.authors = [Person("John Doe", "[email protected]"),
310339
... Person("Mary Sue", "[email protected]")]
340+
341+
:type: :obj:`list` of :class:`podgen.Person`
342+
:RSS: author or dc:creator, and itunes:author
311343
"""
312344
return self.__authors
313345

@@ -322,11 +354,22 @@ def authors(self, authors):
322354

323355
@property
324356
def publication_date(self):
325-
"""Set or get the time that this episode first was made public.
357+
"""The time and date this episode was first published.
358+
359+
The value can be a :obj:`str`, which will be parsed and
360+
made into a :class:`datetime.datetime` object when assigned. You may
361+
also assign a :class:`datetime.datetime` object directly. In both cases,
362+
you must ensure that the value includes timezone information.
363+
364+
:type: :obj:`str` (will be converted to and stored as
365+
:class:`datetime.datetime`) or :class:`datetime.datetime`.
366+
:RSS: pubDate
367+
368+
.. note::
326369
327-
The value can either be a string which will automatically be parsed or a
328-
datetime.datetime object. In both cases you must ensure that the value
329-
includes timezone information.
370+
Don't use the media file's modification date as the publication
371+
date, unless they're the same. It looks very odd when an episode
372+
suddenly pops up in the feed, but it claims to be several hours old!
330373
"""
331374
return self.__publication_date
332375

@@ -348,13 +391,16 @@ def media(self):
348391
"""Get or set the :class:`~podgen.Media` object that is attached
349392
to this episode.
350393
351-
Note that if :py:attr:`.id` is not set, the enclosure's url is used as
352-
the globally unique identifier. If you rely on this, you should make
353-
sure the url never changes, since changing the id messes up with clients
354-
(they will think this episode is new again, even if the user already
355-
has listened to it). Therefore, you should only rely on this behaviour
356-
if you own the domain which the episodes reside on. If you don't, then
357-
you must set :py:attr:`.id` to an appropriate value manually.
394+
Note that if :py:attr:`.id` is not set, the media's URL is used as
395+
the id. If you rely on this, you should make sure the URL never changes,
396+
since changing the id messes up with clients (they will think this
397+
episode is new again, even if the user has listened to it already).
398+
Therefore, you should only rely on this behaviour if you own the domain
399+
which the episodes reside on. If you don't, then you must set
400+
:py:attr:`.id` to an appropriate value manually.
401+
402+
:type: :class:`podgen.Media`
403+
:RSS: enclosure and itunes:duration
358404
"""
359405
return self.__media
360406

@@ -374,17 +420,20 @@ def media(self, media):
374420

375421
@property
376422
def withhold_from_itunes(self):
377-
"""Get or set the iTunes block attribute. Use this to prevent episodes
378-
from appearing in the iTunes podcast directory. Note that the episode
379-
can still be found by inspecting the XML, so it is still public.
423+
"""Prevent this episode from appearing in the iTunes podcast directory.
424+
Note that the episode can still be found by inspecting the XML, so it is
425+
still public.
380426
381-
One use case is if you know that this episode will get you kicked
427+
One use case would be if you knew that this episode would get you kicked
382428
out from iTunes, should it make it there. In such cases, you can set
383429
withhold_from_itunes to ``True`` so this episode isn't published on
384430
iTunes, allowing you to publish it to everyone else while keeping your
385431
podcast on iTunes.
386432
387433
This attribute defaults to ``False``, of course.
434+
435+
:type: :obj:`bool`
436+
:RSS: itunes:block
388437
"""
389438
return self.__withhold_from_itunes
390439

@@ -401,29 +450,35 @@ def withhold_from_itunes(self, withhold_from_itunes):
401450

402451
@property
403452
def image(self):
404-
"""The podcast episode's image.
453+
"""The podcast episode's image, overriding the podcast's
454+
:attr:`~.Podcast.image`.
455+
456+
This attribute specifies the absolute URL to the artwork for your
457+
podcast. iTunes prefers square images that are at least ``1400x1400``
458+
pixels.
459+
460+
iTunes supports images in JPEG and PNG formats with an RGB color space
461+
(CMYK is not supported). The URL must end in ".jpg" or ".png".
462+
463+
:type: :obj:`str`
464+
:RSS: itunes:image
465+
466+
.. note::
467+
468+
If you change an episode’s image, you should also change the file’s
469+
name; iTunes doesn't check the actual file to see if it's changed.
470+
471+
Additionally, the server hosting your cover art image must allow HTTP
472+
HEAD requests.
405473
406474
.. warning::
407475
408476
Almost no podcatchers support this. iTunes supports it only if you
409477
embed the cover in the media file (the same way you would embed
410-
an album cover), and recommends you use Garageband's Enhanced
411-
Podcast feature. If you don't, the podcast's image is used instead.
478+
an album cover), and recommends that you use Garageband's Enhanced
479+
Podcast feature.
412480
413-
This tag specifies the artwork for your podcast.
414-
iTunes prefers square .jpg images that are at least 1400x1400 pixels,
415-
which is different from what is specified for the standard RSS image
416-
tag. In order for a podcast to be eligible for an iTunes Store feature,
417-
the accompanying image must be at least 1400x1400 pixels.
418-
419-
iTunes supports images in JPEG and PNG formats with an RGB color space
420-
(CMYK is not supported). The URL must end in ".jpg" or ".png".
421-
422-
If you change an episode’s image, you should also change the file’s
423-
name. iTunes may not change the image if it checks your feed and the
424-
image URL is the same. The server hosting your cover art image must
425-
allow HTTP head requests for iTunes to be able to automatically update
426-
your cover art.
481+
The podcast's image is used if this isn't supported.
427482
"""
428483
return self.__image
429484

@@ -444,13 +499,16 @@ def explicit(self):
444499
inappropriate for children.
445500
446501
The value of the podcast's explicit attribute is used by default, if
447-
this is ``None``.
502+
this is kept as ``None``.
448503
449504
If you set this to ``True``, an "explicit" parental advisory
450505
graphic will appear in the Name column in iTunes. If the value is
451506
``False``, the parental advisory type is considered Clean, meaning that
452507
no explicit language or adult content is included anywhere in this
453508
episode, and a "clean" graphic will appear.
509+
510+
:type: :obj:`bool`
511+
:RSS: itunes:explicit
454512
"""
455513
return self.__explicit
456514

@@ -471,9 +529,14 @@ def position(self):
471529
472530
If you would like this episode to appear first, set it to ``1``.
473531
If you want it second, set it to ``2``, and so on. If multiple episodes
474-
share the same position, they will be sorted by their publication date.
532+
share the same position, they will be sorted by their
533+
:attr:`publication date <.Episode.publication_date>`.
534+
535+
To remove the order from the episode, set the position back to
536+
:obj:`None`.
475537
476-
To remove the order from the episode, set the position back to ``None``.
538+
:type: :obj:`int`
539+
:RSS: itunes:order
477540
"""
478541
return self.__position
479542

0 commit comments

Comments
 (0)