0
# Extensions System
1
2
Extensible plugin architecture supporting specialized feed formats including podcasts (iTunes), Dublin Core metadata, GeoRSS, media RSS, syndication, and BitTorrent feeds.
3
4
## Capabilities
5
6
### Extension Loading
7
8
Methods for loading and registering extensions on feeds and entries.
9
10
```python { .api }
11
def load_extension(self, name, atom=True, rss=True):
12
"""
13
Load built-in extension by name.
14
15
Args:
16
name (str): Extension name ('podcast', 'dc', 'geo', etc.)
17
atom (bool): Enable extension for ATOM feeds
18
rss (bool): Enable extension for RSS feeds
19
"""
20
21
def register_extension(self, namespace, extension_class_feed=None,
22
extension_class_entry=None, atom=True, rss=True):
23
"""
24
Register custom extension classes.
25
26
Args:
27
namespace (str): XML namespace for extension
28
extension_class_feed (class, optional): Feed extension class
29
extension_class_entry (class, optional): Entry extension class
30
atom (bool): Enable extension for ATOM feeds
31
rss (bool): Enable extension for RSS feeds
32
"""
33
```
34
35
### Podcast Extension
36
37
iTunes podcast support with specialized metadata for podcast feeds and episodes.
38
39
```python { .api }
40
# Load podcast extension
41
fg.load_extension('podcast')
42
43
# Podcast feed methods (accessible via fg.podcast.*)
44
def itunes_author(self, author=None): ...
45
def itunes_block(self, block=None): ... # 'yes' or 'no'
46
def itunes_category(self, category=None, subcategory=None, replace=False): ...
47
def itunes_explicit(self, explicit=None): ... # 'yes', 'no', 'clean'
48
def itunes_complete(self, complete=None): ... # 'yes' or 'no'
49
def itunes_image(self, image=None): ...
50
def itunes_new_feed_url(self, new_feed_url=None): ...
51
def itunes_owner(self, name=None, email=None): ...
52
def itunes_subtitle(self, subtitle=None): ...
53
def itunes_summary(self, summary=None): ...
54
def itunes_type(self, type=None): ... # 'episodic' or 'serial'
55
56
# Podcast entry methods (accessible via fe.podcast.*)
57
def itunes_author(self, author=None): ...
58
def itunes_season(self, season=None): ...
59
def itunes_episode(self, episode=None): ...
60
def itunes_title(self, title=None): ...
61
def itunes_episode_type(self, episode_type=None): ... # 'full', 'trailer', 'bonus'
62
def itunes_duration(self, duration=None): ...
63
def itunes_explicit(self, explicit=None): ...
64
def itunes_subtitle(self, subtitle=None): ...
65
```
66
67
### Dublin Core Extension
68
69
Dublin Core metadata elements for enhanced bibliographic information.
70
71
```python { .api }
72
# Load Dublin Core extension
73
fg.load_extension('dc')
74
75
# Dublin Core methods (accessible via fg.dc.* and fe.dc.*)
76
def dc_contributor(self, contributor=None, replace=False, **kwargs): ...
77
def dc_coverage(self, coverage=None, replace=False, **kwargs): ...
78
def dc_creator(self, creator=None, replace=False, **kwargs): ...
79
def dc_date(self, date=None, replace=False, **kwargs): ...
80
def dc_description(self, description=None, replace=False, **kwargs): ...
81
def dc_format(self, format=None, replace=False, **kwargs): ...
82
def dc_identifier(self, identifier=None, replace=False, **kwargs): ...
83
def dc_language(self, language=None, replace=False, **kwargs): ...
84
def dc_publisher(self, publisher=None, replace=False, **kwargs): ...
85
def dc_relation(self, relation=None, replace=False, **kwargs): ...
86
def dc_rights(self, rights=None, replace=False, **kwargs): ...
87
def dc_source(self, source=None, replace=False, **kwargs): ...
88
def dc_subject(self, subject=None, replace=False, **kwargs): ...
89
def dc_title(self, title=None, replace=False, **kwargs): ...
90
def dc_type(self, type=None, replace=False, **kwargs): ...
91
```
92
93
### Syndication Extension
94
95
RSS syndication module for update scheduling and frequency information.
96
97
```python { .api }
98
# Load syndication extension
99
fg.load_extension('syndication')
100
101
# Syndication methods (accessible via fg.syndication.*)
102
def update_period(self, period=None):
103
"""
104
Set update period: 'hourly', 'daily', 'weekly', 'monthly', 'yearly'
105
"""
106
107
def update_frequency(self, frequency=None):
108
"""
109
Set update frequency (number of times per period).
110
"""
111
112
def update_base(self, base=None):
113
"""
114
Set base timestamp for update calculations.
115
"""
116
```
117
118
### GeoRSS Extension
119
120
Geographic information support for location-aware feeds and entries.
121
122
```python { .api }
123
# Load geo extension
124
fg.load_extension('geo')
125
126
# GeoRSS entry methods (accessible via fe.geo.*)
127
def point(self, point=None, replace=False): ...
128
def line(self, line=None, replace=False): ...
129
def polygon(self, polygon=None, replace=False): ...
130
def featuretypetag(self, featuretypetag=None, replace=False): ...
131
def relationshiptag(self, relationshiptag=None, replace=False): ...
132
def featurename(self, featurename=None, replace=False): ...
133
def elev(self, elev=None, replace=False): ...
134
def floor(self, floor=None, replace=False): ...
135
def radius(self, radius=None, replace=False): ...
136
```
137
138
### Media RSS Extension
139
140
Yahoo Media RSS support for rich media content metadata.
141
142
```python { .api }
143
# Load media extension
144
fg.load_extension('media')
145
146
# Media entry methods (accessible via fe.media.*)
147
def content(self, content=None, replace=False, group=None): ...
148
def group(self, group=None, replace=False): ...
149
def rating(self, rating=None, replace=False, group=None): ...
150
def title(self, title=None, replace=False, group=None): ...
151
def description(self, description=None, replace=False, group=None): ...
152
def thumbnail(self, thumbnail=None, replace=False, group=None): ...
153
def category(self, category=None, replace=False, group=None): ...
154
def hash(self, hash=None, replace=False, group=None): ...
155
def player(self, player=None, replace=False, group=None): ...
156
def credit(self, credit=None, replace=False, group=None): ...
157
def copyright(self, copyright=None, replace=False, group=None): ...
158
def text(self, text=None, replace=False, group=None): ...
159
def restriction(self, restriction=None, replace=False, group=None): ...
160
def community(self, community=None, replace=False, group=None): ...
161
def comments(self, comments=None, replace=False, group=None): ...
162
def embed(self, embed=None, replace=False, group=None): ...
163
def responses(self, responses=None, replace=False, group=None): ...
164
def backLinks(self, backLinks=None, replace=False, group=None): ...
165
def status(self, status=None, replace=False, group=None): ...
166
def price(self, price=None, replace=False, group=None): ...
167
def license(self, license=None, replace=False, group=None): ...
168
def peerLink(self, peerLink=None, replace=False, group=None): ...
169
def rights(self, rights=None, replace=False, group=None): ...
170
def scenes(self, scenes=None, replace=False, group=None): ...
171
```
172
173
### Torrent Extension
174
175
BitTorrent RSS support for torrent feed distribution.
176
177
```python { .api }
178
# Load torrent extension
179
fg.load_extension('torrent')
180
181
# Torrent entry methods (accessible via fe.torrent.*)
182
def filename(self, filename=None): ...
183
def infohash(self, infohash=None): ...
184
def contentlength(self, contentlength=None): ...
185
def seeds(self, seeds=None): ...
186
def peers(self, peers=None): ...
187
def verified(self, verified=None): ...
188
```
189
190
### Base Extension Classes
191
192
Base classes for creating custom extensions.
193
194
```python { .api }
195
class BaseExtension:
196
def extend_ns(self):
197
"""Return namespace dictionary for XML."""
198
return {}
199
200
def extend_rss(self, feed):
201
"""Extend RSS feed XML element."""
202
return feed
203
204
def extend_atom(self, feed):
205
"""Extend ATOM feed XML element."""
206
return feed
207
208
class BaseEntryExtension(BaseExtension):
209
"""Base class for entry-level extensions."""
210
```
211
212
## Usage Examples
213
214
### Podcast Feed
215
216
```python
217
from feedgen.feed import FeedGenerator
218
219
fg = FeedGenerator()
220
# ... basic feed setup ...
221
222
# Load podcast extension
223
fg.load_extension('podcast')
224
225
# Set podcast-specific metadata
226
fg.podcast.itunes_author('Podcast Host Name')
227
fg.podcast.itunes_category('Technology', 'Podcasting')
228
fg.podcast.itunes_explicit('no')
229
fg.podcast.itunes_complete('no')
230
fg.podcast.itunes_owner('Host Name', 'host@example.com')
231
fg.podcast.itunes_summary('A great podcast about technology topics')
232
fg.podcast.itunes_type('episodic')
233
234
# Add podcast episode
235
fe = fg.add_entry()
236
fe.id('http://example.com/episodes/001')
237
fe.title('Episode 1: Introduction')
238
fe.description('Our first episode introducing the podcast')
239
240
# Episode-specific podcast metadata
241
fe.podcast.itunes_author('Episode Author')
242
fe.podcast.itunes_season(1)
243
fe.podcast.itunes_episode(1)
244
fe.podcast.itunes_title('Introduction Episode')
245
fe.podcast.itunes_episode_type('full')
246
fe.podcast.itunes_duration('00:45:30')
247
248
# Add audio enclosure
249
fe.enclosure(
250
url='http://example.com/episodes/001.mp3',
251
length='43200000',
252
type='audio/mpeg'
253
)
254
255
# Generate RSS with podcast extension
256
rss_feed = fg.rss_str(pretty=True)
257
```
258
259
### Geographic Feed with GeoRSS
260
261
```python
262
# Load GeoRSS extension
263
fg.load_extension('geo')
264
265
fe = fg.add_entry()
266
fe.title('Local Event in San Francisco')
267
fe.description('A cool event happening in downtown SF')
268
269
# Add geographic location
270
fe.geo.point('37.7749 -122.4194') # San Francisco coordinates
271
fe.geo.featurename('San Francisco, CA')
272
fe.geo.elev('52') # Elevation in meters
273
274
# Generate feed with geographic metadata
275
atom_feed = fg.atom_str(pretty=True)
276
```
277
278
### Dublin Core Metadata
279
280
```python
281
# Load Dublin Core extension
282
fg.load_extension('dc')
283
284
# Add Dublin Core metadata to feed
285
fg.dc.dc_creator('Content Creator Name')
286
fg.dc.dc_publisher('Publishing Organization')
287
fg.dc.dc_rights('Creative Commons Attribution 4.0')
288
fg.dc.dc_type('Text')
289
290
# Add entry with Dublin Core metadata
291
fe = fg.add_entry()
292
fe.title('Research Article')
293
fe.description('Academic research on web feeds')
294
295
fe.dc.dc_subject(['web feeds', 'RSS', 'ATOM', 'syndication'])
296
fe.dc.dc_creator('Dr. Research Author')
297
fe.dc.dc_date('2023-12-01')
298
fe.dc.dc_type('Text.Article.Research')
299
300
# Generate with Dublin Core extensions
301
atom_with_dc = fg.atom_str(pretty=True)
302
```
303
304
### Media RSS for Rich Content
305
306
```python
307
# Load media extension
308
fg.load_extension('media')
309
310
fe = fg.add_entry()
311
fe.title('Video Tutorial: Python Basics')
312
fe.description('Learn Python programming fundamentals')
313
314
# Add media content
315
fe.media.content({
316
'url': 'http://example.com/videos/python-basics.mp4',
317
'type': 'video/mp4',
318
'fileSize': '104857600',
319
'duration': '1800',
320
'width': '1920',
321
'height': '1080'
322
})
323
324
# Add media thumbnail
325
fe.media.thumbnail({
326
'url': 'http://example.com/thumbnails/python-basics.jpg',
327
'width': '320',
328
'height': '180'
329
})
330
331
# Media metadata
332
fe.media.title('Python Basics Tutorial')
333
fe.media.description('Complete beginner guide to Python programming')
334
fe.media.category('Education/Technology')
335
fe.media.credit({'name': 'Tutorial Creator', 'role': 'author'})
336
337
# Generate RSS with media extensions
338
rss_with_media = fg.rss_str(pretty=True)
339
```
340
341
### Custom Extension Development
342
343
```python
344
from feedgen.ext.base import BaseExtension, BaseEntryExtension
345
346
class CustomExtension(BaseExtension):
347
def extend_ns(self):
348
return {'custom': 'http://example.com/custom-namespace'}
349
350
def extend_rss(self, feed):
351
# Add custom elements to RSS feed
352
return feed
353
354
def extend_atom(self, feed):
355
# Add custom elements to ATOM feed
356
return feed
357
358
class CustomEntryExtension(BaseEntryExtension):
359
def custom_field(self, value=None):
360
if value is not None:
361
self.__custom_field = value
362
return getattr(self, '_CustomEntryExtension__custom_field', None)
363
364
# Register custom extension
365
fg.register_extension(
366
'http://example.com/custom-namespace',
367
extension_class_feed=CustomExtension,
368
extension_class_entry=CustomEntryExtension
369
)
370
```