sphinxfeed-lsaffre 0.3.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
sphinxfeed.py ADDED
@@ -0,0 +1,178 @@
1
+ # This application is derived from Dan Mackinlay's sphinxcontrib.feed package.
2
+ # The original can be found at http://bitbucket.org/birkenfeld/sphinx-contrib/src/tip/feed/
3
+ """
4
+ See https://github.com/lsaffre/sphinxfeed
5
+ """
6
+
7
+ __version__ = '0.3.2'
8
+
9
+ import os.path
10
+ import time
11
+ from datetime import datetime
12
+ from dateutil.tz import tzlocal
13
+ from sphinx.util.logging import getLogger
14
+
15
+ from feedgen.feed import FeedGenerator
16
+ from feedgen.feed import FeedEntry
17
+
18
+ doc_trees = [] # for atelier
19
+ logger = getLogger(__name__)
20
+
21
+
22
+ def parse_pubdate(pubdate):
23
+ # tz = "+0002"
24
+ # chunks = pubdate.split()
25
+ # if len(chunks) == 1:
26
+ # chunks.append("23:59")
27
+ # if len(chunks) == 2:
28
+ # chunks.append(tz)
29
+ # fmt = '%Y-%m-%d %H:%M %Z'
30
+ # return time.strptime(' '.join(chunks), fmt)
31
+ fmt = '%Y-%m-%d %H:%M'
32
+ try:
33
+ date = time.strptime(pubdate, fmt)
34
+ except ValueError:
35
+ date = time.strptime(pubdate + " 23:59", fmt)
36
+ return date
37
+
38
+
39
+ def setup(app):
40
+ """ see: http://sphinx.pocoo.org/ext/appapi.html
41
+ this is the primary extension point for Sphinx
42
+ """
43
+ from sphinx.application import Sphinx
44
+ if not isinstance(app, Sphinx): return
45
+ app.add_config_value('feed_base_url', '', 'html')
46
+ app.add_config_value('feed_description', '', 'html')
47
+ app.add_config_value('feed_author', '', 'html')
48
+ app.add_config_value('feed_field_name', 'Publish Date', 'env')
49
+ app.add_config_value('feed_filename', 'rss.xml', 'html')
50
+ app.add_config_value('feed_use_atom', False, 'html')
51
+ app.add_config_value('use_dirhtml', False, 'html')
52
+
53
+ app.connect('html-page-context', create_feed_item)
54
+ app.connect('build-finished', emit_feed)
55
+ app.connect('builder-inited', create_feed_container)
56
+
57
+ #env.process_metadata deletes most of the docinfo, and dates
58
+ #in particular.
59
+
60
+
61
+ def create_feed_container(app):
62
+ #from feedformatter import Feed
63
+ feed = FeedGenerator()
64
+ feed.title(app.config.project)
65
+ feed.link(href=app.config.feed_base_url)
66
+ if app.config.feed_use_atom:
67
+ feed.id(app.config.feed_base_url)
68
+ feed.author({'name': app.config.feed_author})
69
+ feed.description(app.config.feed_description)
70
+
71
+ if app.config.language:
72
+ feed.language(app.config.language)
73
+ if app.config.copyright:
74
+ feed.copyright(app.config.copyright)
75
+ app.builder.env.feed_feed = feed
76
+ if not hasattr(app.builder.env, 'feed_items'):
77
+ app.builder.env.feed_items = {}
78
+
79
+
80
+ def create_feed_item(app, pagename, templatename, ctx, doctree):
81
+ """ Here we have access to nice HTML fragments to use in, say, an RSS feed.
82
+ """
83
+
84
+ env = app.builder.env
85
+ metadata = app.builder.env.metadata.get(pagename, {})
86
+
87
+ pubDate = metadata.get(app.config.feed_field_name, None)
88
+ if not pubDate:
89
+ return
90
+
91
+ pubDate = parse_pubdate(pubDate)
92
+
93
+ if pubDate > time.localtime():
94
+ logger.info("Skipping %s, publish date is in the future: %s", pagename, pubDate)
95
+ return
96
+
97
+ if not ctx.get('body') or not ctx.get('title'):
98
+ return
99
+
100
+ pubDate = datetime.fromtimestamp(time.mktime(pubDate))
101
+ pubDate = pubDate.replace(tzinfo=tzlocal())
102
+
103
+ item = FeedEntry()
104
+ item.title(ctx.get('title'))
105
+ href = app.config.feed_base_url + '/' + ctx['current_page_name']
106
+ if not app.config.use_dirhtml:
107
+ href += ctx['file_suffix']
108
+ item.link(href=href)
109
+ if app.config.feed_use_atom:
110
+ item.id(href)
111
+ item.description(ctx.get('body'))
112
+ item.published(pubDate)
113
+
114
+ if author := metadata.get('author'):
115
+ # author may be a str (in field list/frontmatter) or a dict (expected by feedgen)
116
+ if isinstance (author, str):
117
+ author = {'name': author}
118
+ item.author(author)
119
+ if cat := metadata.get("category", None):
120
+ item.category(term=cat)
121
+ if tags := metadata.get("tags", None):
122
+ # tags may be a str (in field list/frontmatter), or a list (from sphinx-tags extension)
123
+ if isinstance(tags, str):
124
+ tags = tags.split()
125
+ for tag in tags:
126
+ item.category(term=tag)
127
+
128
+ env.feed_items[pagename] = item
129
+
130
+ #Additionally, we might like to provide our templates with a way to link to the rss output file
131
+ ctx['rss_link'] = app.config.feed_base_url + '/' + app.config.feed_filename
132
+
133
+
134
+ def emit_feed(app, exc):
135
+ ordered_items = list(app.builder.env.feed_items.values())
136
+ feed = app.builder.env.feed_feed
137
+ # ordered_items.sort(key=lambda x: x['pubDate'], reverse=True)
138
+ ordered_items.sort(key=lambda x: x.published())
139
+ for item in ordered_items:
140
+ feed.add_entry(item) # prepends the item
141
+ # for k, v in item.items():
142
+ # getattr(e, k)(v)
143
+
144
+ path = os.path.join(app.builder.outdir, app.config.feed_filename)
145
+
146
+ # print(20190315, path)
147
+ if app.config.feed_use_atom:
148
+ feed.atom_file(path)
149
+ else:
150
+ feed.rss_file(path)
151
+
152
+ return
153
+ # LS 20180204 The following code (pickle the environment and check
154
+ # consistency at this point) caused an error when also bibtex was
155
+ # installed. I deactivated it since I don't know why it's needed.
156
+
157
+ from os import path
158
+ from sphinx.application import ENV_PICKLE_FILENAME
159
+ from sphinx.util.console import bold
160
+ # save the environment
161
+ builder = app.builder
162
+ builder.info(bold('pickling environment... '), nonl=True)
163
+ builder.env.topickle(path.join(builder.doctreedir, ENV_PICKLE_FILENAME))
164
+ builder.info('done')
165
+
166
+ # global actions
167
+ builder.info(bold('checking consistency... '), nonl=True)
168
+ builder.env.check_consistency()
169
+ builder.info('done')
170
+
171
+
172
+ ## Tests
173
+
174
+ # ... TODO
175
+
176
+ if __name__ == '__main__':
177
+ import unittest
178
+ unittest.main()
@@ -0,0 +1,137 @@
1
+ Metadata-Version: 2.3
2
+ Name: sphinxfeed-lsaffre
3
+ Version: 0.3.2
4
+ Summary: Sphinx extension for generating RSS feeds
5
+ Project-URL: homepage, https://github.com/lsaffre/sphinxfeed
6
+ Project-URL: issues, https://github.com/lsaffre/sphinxfeed/issues
7
+ Author-email: Fergus Doyle <fergus.doyle@largeblue.com>, Luc Saffre <luc@saffre-rumma.net>, Jordan Cook <jordan.cook.git@proton.me>
8
+ Maintainer-email: Luc Saffre <luc@saffre-rumma.net>
9
+ License: Copyright 2011 Fergus Doyle <fergus.doyle@largeblue.com>
10
+ Copyright 2016-2024 Rumma & Ko Ltd <info@saffre-rumma.net>
11
+
12
+ Redistribution and use in source and binary forms, with or without modification,
13
+ are permitted provided that the following conditions are met:
14
+
15
+ 1. Redistributions of source code must retain the above copyright notice, this
16
+ list of conditions and the following disclaimer.
17
+
18
+ 2. Redistributions in binary form must reproduce the above copyright notice,
19
+ this list of conditions and the following disclaimer in the documentation
20
+ and/or other materials provided with the distribution.
21
+
22
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND
23
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
26
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
29
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
+ License-File: LICENSE
33
+ Classifier: Development Status :: 4 - Beta
34
+ Classifier: Environment :: Console
35
+ Classifier: Environment :: Web Environment
36
+ Classifier: Intended Audience :: Developers
37
+ Classifier: License :: OSI Approved :: BSD License
38
+ Classifier: Operating System :: OS Independent
39
+ Classifier: Programming Language :: Python
40
+ Classifier: Topic :: Documentation
41
+ Classifier: Topic :: Utilities
42
+ Requires-Python: >=3.8
43
+ Requires-Dist: feedgen
44
+ Requires-Dist: python-dateutil
45
+ Requires-Dist: sphinx
46
+ Provides-Extra: dev
47
+ Requires-Dist: atelier; extra == 'dev'
48
+ Requires-Dist: hatch; extra == 'dev'
49
+ Requires-Dist: pytest; extra == 'dev'
50
+ Description-Content-Type: text/x-rst
51
+
52
+ ==========================
53
+ The ``sphinxfeed`` package
54
+ ==========================
55
+
56
+ This Sphinx extension is a fork of Fergus Doyle's `sphinxfeed package
57
+ <https://github.com/junkafarian/sphinxfeed>`__ which itself is derived from Dan
58
+ Mackinlay's `sphinxcontrib.feed
59
+ <http://bitbucket.org/birkenfeld/sphinx-contrib/src/tip/feed/>`_ package. It
60
+ relies on Lars Kiesow's `python-feedgen <https://feedgen.kiesow.be>`__ package
61
+ instead of the defunct `feedformatter
62
+ <https://code.google.com/archive/p/feedformatter/>`_ package or of Django utils to
63
+ generate the feed.
64
+
65
+
66
+ Installation
67
+ ============
68
+
69
+ Soon you can install it using pip::
70
+
71
+ pip install sphinxfeed-lsaffre
72
+
73
+ How to test whether the right version of sphinxfeed is installed:
74
+
75
+ >>> import sphinxfeed
76
+ >>> sphinxfeed.__version__
77
+ '0.3.1'
78
+
79
+
80
+ Usage
81
+ =====
82
+
83
+ #. Add ``sphinxfeed`` to the list of extensions in your ``conf.py``::
84
+
85
+ extensions = [..., 'sphinxfeed']
86
+
87
+ #. Customise the necessary configuration options to correctly generate
88
+ the feed::
89
+
90
+ feed_base_url = 'https://YOUR_HOST_URL'
91
+ feed_author = 'YOUR NAME'
92
+ feed_description = "A longer description"
93
+
94
+ # optional options
95
+ feed_field_name = 'date' # default value is "Publish Date"
96
+ feed_use_atom = False
97
+ use_dirhtml = False
98
+
99
+ #. Optionally use the following metadata fields:
100
+
101
+ - date (or any other name configured using feed_field_name)
102
+ - author
103
+ - tags
104
+ - category
105
+
106
+ #. Sphinxfeed will include only `.rst` files that have a ``:date:`` field with a
107
+ date that does not lie in the future.
108
+
109
+
110
+ Maintenance
111
+ ===========
112
+
113
+ See also the files `LICENSE` and `CHANGELOG.rst`.
114
+
115
+ Install a developer version::
116
+
117
+ git clone https://github.com/lsaffre/sphinxfeed.git
118
+ pip install -e ".[dev]"
119
+
120
+ Run the test suite::
121
+
122
+ $ pytest
123
+
124
+ Release a new version to PyPI::
125
+
126
+ $ git tag v$(hatch version)
127
+ $ git push --tags
128
+
129
+ Manuael release to PyPI without GitHub::
130
+
131
+ $ hatch build
132
+ $ twine check --strict dist/*
133
+ $ twine upload dist/*
134
+
135
+ The ``twine upload`` step requires authentication credentials in your
136
+ `~/.pypirc` file.
137
+
@@ -0,0 +1,5 @@
1
+ sphinxfeed.py,sha256=yHzg28aQpYhG05-c58lJXVwlob7HZ-apmQaKmqWQScY,5672
2
+ sphinxfeed_lsaffre-0.3.2.dist-info/METADATA,sha256=VYEk7nbX0boJzkQL4vbEHi77xhDi7gzgAdxXfGe40RQ,4702
3
+ sphinxfeed_lsaffre-0.3.2.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
4
+ sphinxfeed_lsaffre-0.3.2.dist-info/licenses/LICENSE,sha256=L-9u0fPRQMuovEbw4skNexDN7iY0PMFQz35W_ffLqZY,1366
5
+ sphinxfeed_lsaffre-0.3.2.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.25.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,23 @@
1
+ Copyright 2011 Fergus Doyle <fergus.doyle@largeblue.com>
2
+ Copyright 2016-2024 Rumma & Ko Ltd <info@saffre-rumma.net>
3
+
4
+ Redistribution and use in source and binary forms, with or without modification,
5
+ are permitted provided that the following conditions are met:
6
+
7
+ 1. Redistributions of source code must retain the above copyright notice, this
8
+ list of conditions and the following disclaimer.
9
+
10
+ 2. Redistributions in binary form must reproduce the above copyright notice,
11
+ this list of conditions and the following disclaimer in the documentation
12
+ and/or other materials provided with the distribution.
13
+
14
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND
15
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
18
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
21
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.