import feedgenerator
from urllib import quote_plus
import os.path
+import directives
#global
feed_entries = None
#constant unlikely to occur in a docname and legal as a filename
MAGIC_SEPARATOR = '---###---'
+def parse_date(datestring):
+ try:
+ parser = parse_date.parser
+ except AttributeError:
+ import dateutil.parser
+ parser = dateutil.parser.parser()
+ parse_date.parser = parser
+ return parser.parse(datestring)
+
def setup(app):
"""
see: http://sphinx.pocoo.org/ext/appapi.html
"""
from sphinx.application import Sphinx
if not isinstance(app, Sphinx): return
+ app.add_config_value('feed_title', '', 'html')
app.add_config_value('feed_base_url', '', 'html')
app.add_config_value('feed_description', '', 'html')
app.add_config_value('feed_filename', 'rss.xml', 'html')
app.connect('html-page-context', create_feed_item)
- app.connect('html-page-context', inject_feed_url)
app.connect('build-finished', emit_feed)
app.connect('builder-inited', create_feed_container)
app.connect('env-purge-doc', remove_dead_feed_item)
def create_feed_container(app):
"""
- create lazy filesystem stash for keeping RSS entry fragments, since we don't
- want to store the entire site in the environment (in fact, even if we did,
- it wasn't persisting for some reason.)
+ create lazy filesystem stash for keeping RSS entry fragments, since we
+ don't want to store the entire site in the environment (in fact, even if
+ we did, it wasn't persisting for some reason.)
"""
global feed_entries
rss_fragment_path = os.path.realpath(os.path.join(app.outdir, '..', 'rss_entry_fragments'))
feed_entries = FSDict(work_dir=rss_fragment_path)
app.builder.env.feed_url = app.config.feed_base_url + '/' + \
app.config.feed_filename
-
-def inject_feed_url(app, pagename, templatename, ctx, doctree):
- #We like to provide our templates with a way to link to the rss output file
- ctx['rss_link'] = app.builder.env.feed_url #app.config.feed_base_url + '/' + app.config.feed_filename
-
+
def create_feed_item(app, pagename, templatename, ctx, doctree):
"""
Here we have access to nice HTML fragments to use in, say, an RSS feed.
We serialize them to disk so that we get them preserved across builds.
+
+ We also inject useful metadata into the context here.
"""
global feed_entries
- import dateutil.parser
from absolutify_urls import absolutify
- date_parser = dateutil.parser.parser()
metadata = app.builder.env.metadata.get(pagename, {})
if 'date' not in metadata:
return #don't index dateless articles
try:
- pub_date = date_parser.parse(metadata['date'])
+ pub_date = parse_date(metadata['date'])
+ app.builder.env.metadata.get(pagename, {})
except ValueError, exc:
#probably a nonsensical date
app.builder.warn('date parse error: ' + str(exc) + ' in ' + pagename)
return
-
- # title, link, description, author_email=None,
+
+ # RSS item attributes, w/defaults:
+ # title, link, description, author_email=None,
# author_name=None, author_link=None, pubdate=None, comments=None,
# unique_id=None, enclosure=None, categories=(), item_copyright=None,
# ttl=None,
}
if 'author' in metadata:
item['author'] = metadata['author']
- feed_entries[nice_name(pagename, pub_date)] = item
+ feed_entries[nice_name(pagename, pub_date)] = item
+
+ #Now, useful variables to keep in context
+ ctx['rss_link'] = app.builder.env.feed_url
+ ctx['pub_date'] = pub_date
def remove_dead_feed_item(app, env, docname):
"""
global feed_entries
import os.path
+ title = app.config.feed_title
+ if not title:
+ title = app.config.project
+
feed_dict = {
- 'title': app.config.project,
+ 'title': title,
'link': app.config.feed_base_url,
'feed_url': app.config.feed_base_url,
'description': app.config.feed_description