diff --git a/feedgen/__init__.py b/feedgen/__init__.py index 649c95e..e89a923 100644 --- a/feedgen/__init__.py +++ b/feedgen/__init__.py @@ -5,8 +5,8 @@ ======= This module can be used to generate web feeds in both ATOM and RSS format. - The included PodcastGenerator furthermore includes all of Apples RSS - extension for Podcasts. + It has support for extensions. Included is for example an extension to + produce Podcasts. :copyright: 2013 by Lars Kiesow :license: FreeBSD and LGPL, see license.* for more details. @@ -69,32 +69,61 @@ >>> fe.title('The First Episode') The FeedGenerators method add_entry(...) without argument provides will - automaticall generate a new FeedEntry object, append it to the feeds + automatically generate a new FeedEntry object, append it to the feeds internal list of entries and return it, so that additional data can be added. - ----------------- - Produce a Podcast - ----------------- + ---------- + Extensions + ---------- - A podcast is an RSS feed with some additional elements for ITunes. The - feedgen has a PodcastGenerator class as extension to the default - FeedGenerator which you can use to set these additional fields. + The FeedGenerator supports extension to include additional data into the XML + structure of the feeds. Extensions can be loaded like this:: - To produce a podcast simply do something like this:: + >>> fg.load_extension('someext', atom=True, rss=True) - >>> from feedgen.podcast import PodcastGenerator - >>> fg = PodcastGenerator() + This will try to load the extension “someext” from the file + `ext/someext.py`. It is required that `someext.py` contains a class named + “SomextExtension” which is required to have at least the two methods + `extend_rss(...)` and `extend_atom(...)`. Although not required, it is + strongly suggested to use BaseExtension from `ext/base.py` as superclass. + + `load_extension('someext', ...)` will also try to load a class named + “SomextEntryExtension” for every entry of the feed. This class can be + located either in the same file as SomextExtension or in + `ext/someext_entry.py` which is suggested especially for large extensions. + + The parameters `atom` and `rss` tell the FeedGenerator if the extensions + should only be used for either ATOM or RSS feeds. The default value for both + parameters is true which means that the extension would be used for both + kinds of feeds. + + **Example: Produceing a Podcast** + + One extension already provided is the podcast extension. A podcast is an RSS + feed with some additional elements for ITunes. + + To produce a podcast simply load the `podcast` extension:: + + >>> from feedgen.feed import FeedGenerator + >>> fg = FeedGenerator() + >>> fg.load_extension('podcast') ... - >>> fg.podcast_str(pretty=True) - >>> fg.podcast_file('podcast.xml') + >>> fg.podcast.itunes_category('Technology', 'Podcasting') + ... + >>> fg.rss_str(pretty=True) + >>> fg.rss_file('podcast.xml') - For the episodes of the podcast you should also use PodcastEntry instead of - FeedEntry. However, if you use the add_entry(...) method to generator the - entry objects, it will take care of that for you. + Of cause the extension has to be loaded for the FeedEntry objects as well + but this is done automatically by the FeedGenerator for every feed entry if + the extension is loaded for the whole feed. You can, however, load an + extension for a specific FeedEntry by calling `load_extension(...)` on that + entry. But this is a rather uncommon use. - Of cause you can still produce a normat ATOM or RSS feed, even if you use - the PodcastGenerator using the {atom,rss}_{str,file} methods. + Of cause you can still produce a normal ATOM or RSS feed, even if you have + loaded some plugins by temporary disabling them during the feed generation. + This can be done by calling the generating method with the keyword argument + `extensions` set to `False`. --------------------- Testing the Generator @@ -102,6 +131,6 @@ You can test the module by simply executing:: - %> pythom -m feedgen + $ pythom -m feedgen """ diff --git a/feedgen/ext/base.py b/feedgen/ext/base.py index 4c40f7b..be774db 100644 --- a/feedgen/ext/base.py +++ b/feedgen/ext/base.py @@ -3,7 +3,8 @@ feedgen.ext.base ~~~~~~~~~~~~~~~~ - Basic FeedGenerator which does nothing but provides all necessary methods. + Basic FeedGenerator extension which does nothing but provides all necessary + methods. :copyright: 2013, Lars Kiesow diff --git a/feedgen/ext/podcast.py b/feedgen/ext/podcast.py index 812616a..15a1a07 100644 --- a/feedgen/ext/podcast.py +++ b/feedgen/ext/podcast.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- ''' - feedgen.podcast - ~~~~~~~~~~~~~~~ + feedgen.ext.podcast + ~~~~~~~~~~~~~~~~~~~ Extends the FeedGenerator to produce podcasts. @@ -11,11 +11,7 @@ ''' from lxml import etree -from datetime import datetime -import dateutil.parser -import dateutil.tz from feedgen.ext.base import BaseExtension -from feedgen.util import ensure_format class PodcastExtension(BaseExtension): diff --git a/feedgen/ext/podcast_entry.py b/feedgen/ext/podcast_entry.py index cd20d69..06fada1 100644 --- a/feedgen/ext/podcast_entry.py +++ b/feedgen/ext/podcast_entry.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- ''' - feedgen.podcast_entry - ~~~~~~~~~~~~~~~~~~~~~ + feedgen.ext.podcast_entry + ~~~~~~~~~~~~~~~~~~~~~~~~~ Extends the feedgen to produce podcasts. @@ -11,14 +11,10 @@ ''' from lxml import etree -from datetime import datetime -import dateutil.parser -import dateutil.tz -from feedgen.ext.base import BaseExtension -from feedgen.util import ensure_format +from feedgen.ext.base import BaseEntryExtension -class PodcastEntryExtension(BaseExtension): +class PodcastEntryExtension(BaseEntryExtension): '''FeedEntry extension for podcasts. ''' diff --git a/feedgen/feed.py b/feedgen/feed.py index 7a9b62e..e5dd912 100644 --- a/feedgen/feed.py +++ b/feedgen/feed.py @@ -16,6 +16,7 @@ import dateutil.tz from feedgen.entry import FeedEntry from feedgen.util import ensure_format +_feedgen_version = 0.2 class FeedGenerator(object): '''FeedGenerator for generating ATOM and RSS feeds. diff --git a/readme.md b/readme.md index f043111..e97f568 100644 --- a/readme.md +++ b/readme.md @@ -2,9 +2,9 @@ Feedgenerator ============= -This module can be used to generate web feeds in both ATOM and RSS format. -The included PodcastGenerator can furthermore generate all of Apples RSS -extension for Podcasts. +This module can be used to generate web feeds in both ATOM and RSS format. It +has support for extensions. Included is for example an extension to produce +Podcasts. It is licensed under the terms of both, the FreeBSD license and the LGPLv3+. Choose the one which is more convenient for you. For more details have a look @@ -37,11 +37,12 @@ You can also use pip to install the feedgen module. Simply run:: $ pip install feedgen + ------------- Create a Feed ------------- -To create a feed simply instantiate the FeedGenerator class and insert some +To create a feed simply instanciate the FeedGenerator class and insert some data:: >>> from feedgen.feed import FeedGenerator @@ -55,8 +56,8 @@ data:: >>> fg.link( href='http://larskiesow.de/test.atom', rel='self' ) >>> fg.language('en') -Note that for the methods which set fields that can occur more than once in -a feed you can use all of the following ways to provide data: +Note that for the methods which set fields that can occur more than once in a +feed you can use all of the following ways to provide data: - Provide the data for that element as keyword arguments - Provide the data for that element as dictionary @@ -68,9 +69,9 @@ Example:: >>> fg.contributor({'name':'John Doe', 'email':'jdoe@example.com'}) >>> fg.contributor([{'name':'John Doe', 'email':'jdoe@example.com'}, ...]) ---------------- -Generate output ---------------- +----------------- +Generate the Feed +----------------- After that you can generate both RSS or ATOM by calling the respective method:: @@ -84,42 +85,71 @@ After that you can generate both RSS or ATOM by calling the respective method:: Add Feed Entries ---------------- -To add entries (items) to a feed you need to create new FeedEntry objects -and append them to the list of entries in the FeedGenerator. The most -convenient way to go is to use the FeedGenerator itself for the -instantiation of the FeedEntry object:: +To add entries (items) to a feed you need to create new FeedEntry objects and +append them to the list of entries in the FeedGenerator. The most convenient +way to go is to use the FeedGenerator itself for the instantiation of the +FeedEntry object:: >>> fe = fg.add_entry() >>> fe.id('http://lernfunk.de/media/654321/1') >>> fe.title('The First Episode') The FeedGenerators method add_entry(...) without argument provides will -automatically generate a new FeedEntry object, append it to the feeds -internal list of entries and return it, so that additional data can be -added. +automatically generate a new FeedEntry object, append it to the feeds internal +list of entries and return it, so that additional data can be added. ------------------ -Produce a Podcast ------------------ +---------- +Extensions +---------- -A podcast is an RSS feed with some additional elements for ITunes. The -feedgen has a PodcastGenerator class as extension to the default -FeedGenerator which you can use to set these additional fields. +The FeedGenerator supports extension to include additional data into the XML +structure of the feeds. Extensions can be loaded like this:: -To produce a podcast simply do something like this:: + >>> fg.load_extension('someext', atom=True, rss=True) - >>> from feedgen.podcast import PodcastGenerator - >>> fg = PodcastGenerator() +This will try to load the extension “someext” from the file `ext/someext.py`. +It is required that `someext.py` contains a class named “SomextExtension” which +is required to have at least the two methods `extend_rss(...)` and +`extend_atom(...)`. Although not required, it is strongly suggested to use +`BaseExtension` from `ext/base.py` as superclass. + +`load_extension('someext', ...)` will also try to load a class named +“SomextEntryExtension” for every entry of the feed. This class can be located +either in the same file as SomextExtension or in `ext/someext_entry.py` which +is suggested especially for large extensions. + +The parameters `atom` and `rss` tell the FeedGenerator if the extensions should +only be used for either ATOM or RSS feeds. The default value for both +parameters is true which means that the extension would be used for both kinds +of feeds. + +**Example: Produceing a Podcast** + +One extension already provided is the podcast extension. A podcast is an RSS +feed with some additional elements for ITunes. + +To produce a podcast simply load the `podcast` extension:: + + >>> from feedgen.feed import FeedGenerator + >>> fg = FeedGenerator() + >>> fg.load_extension('podcast') ... - >>> fg.podcast_str(pretty=True) - >>> fg.podcast_file('podcast.xml') + >>> fg.podcast.itunes_category('Technology', 'Podcasting') + ... + >>> fg.rss_str(pretty=True) + >>> fg.rss_file('podcast.xml') -For the episodes of the podcast you should also use PodcastEntry instead of -FeedEntry. However, if you use the add_entry(...) method to generator the -entry objects, it will take care of that for you. +Of cause the extension has to be loaded for the FeedEntry objects as well but +this is done automatically by the FeedGenerator for every feed entry if the +extension is loaded for the whole feed. You can, however, load an extension for +a specific FeedEntry by calling `load_extension(...)` on that entry. But this +is a rather uncommon use. + +Of cause you can still produce a normal ATOM or RSS feed, even if you have +loaded some plugins by temporary disabling them during the feed generation. +This can be done by calling the generating method with the keyword argument +`extensions` set to `False`. -Of cause you can still produce a normal ATOM or RSS feed, even if you use -the PodcastGenerator using the {atom,rss}_{str,file} methods. --------------------- Testing the Generator