-
Notifications
You must be signed in to change notification settings - Fork 35
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Generate json artifacts #43
Changes from all commits
a0091db
9fb97cf
5413c6e
be06d24
c853064
dc33983
ffc0ffe
c5bbd70
ddfba51
a59aad8
6edf54a
c659280
ebc2832
4fc6363
ef2564f
cc7c7f8
fb33462
38f9999
b0643cb
dff342f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,26 +3,49 @@ | |
from __future__ import absolute_import | ||
|
||
import codecs | ||
import json | ||
import os | ||
import re | ||
import types | ||
from distutils.version import LooseVersion | ||
|
||
import sphinx | ||
from sphinx import package_dir | ||
from sphinx.builders.html import StandaloneHTMLBuilder, DirectoryHTMLBuilder, SingleFileHTMLBuilder | ||
from sphinx.builders.html import (DirectoryHTMLBuilder, SingleFileHTMLBuilder, | ||
StandaloneHTMLBuilder) | ||
from sphinx.util.console import bold | ||
|
||
from .embed import EmbedDirective | ||
from .mixins import BuilderMixin | ||
|
||
try: | ||
# Avaliable from Sphinx 1.6 | ||
from sphinx.util.logging import getLogger | ||
except ImportError: | ||
from logging import getLogger | ||
|
||
log = getLogger(__name__) | ||
|
||
MEDIA_MAPPING = { | ||
"_static/jquery.js": "%sjavascript/jquery/jquery-2.0.3.min.js", | ||
"_static/underscore.js": "%sjavascript/underscore.js", | ||
"_static/doctools.js": "%sjavascript/doctools.js", | ||
} | ||
|
||
|
||
# Whitelist keys that we want to output | ||
# to the json artifacts. | ||
KEYS = [ | ||
'body', | ||
'title', | ||
'sourcename', | ||
'current_page_name', | ||
'rellinks', | ||
'toc', | ||
'page_source_suffix', | ||
] | ||
|
||
|
||
def finalize_media(app): | ||
""" Point media files at our media server. """ | ||
|
||
|
@@ -126,6 +149,44 @@ def rtd_render(self, template, render_context): | |
app.builder.templates) | ||
|
||
|
||
def generate_json_artifacts(app, pagename, templatename, context, doctree): | ||
""" | ||
Generate JSON artifacts for each page. | ||
|
||
This way we can skip generating this in other build step. | ||
""" | ||
try: | ||
if not app.config.rtd_generate_json_artifacts: | ||
return | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I didn't find a way of using this configuration in the setup step, so I'm checking it here |
||
# We need to get the output directory where the docs are built | ||
# _build/json. | ||
build_json = os.path.abspath( | ||
os.path.join(app.outdir, '..', 'json') | ||
) | ||
outjson = os.path.join(build_json, pagename + '.fjson') | ||
outdir = os.path.dirname(outjson) | ||
if not os.path.exists(outdir): | ||
os.makedirs(outdir) | ||
with open(outjson, 'w+') as json_file: | ||
to_context = { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i think the field should be blank rather than non existence if the key is missing. to_context = { key: context.get(key, '') for key in KEYS} There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This makes sense, so that the JSON always has the same keys. |
||
key: context.get(key, '') | ||
for key in KEYS | ||
} | ||
json.dump(to_context, json_file, indent=4) | ||
except TypeError: | ||
log.exception( | ||
'Fail to encode JSON for page {page}'.format(page=outjson) | ||
) | ||
except IOError: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same for this |
||
log.exception( | ||
'Fail to save JSON output for page {page}'.format(page=outjson) | ||
) | ||
except Exception as e: | ||
log.exception( | ||
'Failure in JSON search dump for page {page}'.format(page=outjson) | ||
) | ||
|
||
|
||
class HtmlBuilderMixin(BuilderMixin): | ||
|
||
static_readthedocs_files = [ | ||
|
@@ -213,11 +274,13 @@ def setup(app): | |
app.add_builder(ReadtheDocsSingleFileHTMLBuilderLocalMedia) | ||
app.connect('builder-inited', finalize_media) | ||
app.connect('html-page-context', update_body) | ||
app.connect('html-page-context', generate_json_artifacts) | ||
|
||
# Embed | ||
app.add_directive('readthedocs-embed', EmbedDirective) | ||
app.add_config_value('readthedocs_embed_project', '', 'html') | ||
app.add_config_value('readthedocs_embed_version', '', 'html') | ||
app.add_config_value('readthedocs_embed_doc', '', 'html') | ||
app.add_config_value('rtd_generate_json_artifacts', False, 'html') | ||
|
||
return {} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
import os | ||
import sys | ||
|
||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..')) | ||
|
||
extensions = ['readthedocs_ext.readthedocs'] | ||
|
||
templates_path = ['_templates'] | ||
source_suffix = '.rst' | ||
master_doc = 'index' | ||
project = u'pyexample' | ||
copyright = u'2015, rtfd' | ||
author = u'rtfd' | ||
version = '0.1' | ||
release = '0.1' | ||
language = None | ||
exclude_patterns = ['_build'] | ||
pygments_style = 'sphinx' | ||
todo_include_todos = False | ||
html_theme = 'alabaster' | ||
html_static_path = ['_static'] | ||
htmlhelp_basename = 'pyexampledoc' | ||
rtd_generate_json_artifacts = True | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This value should be in the conf.py template of the rtd repo :) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
.. pyexample documentation master file, created by | ||
sphinx-quickstart on Fri May 29 13:34:37 2015. | ||
You can adapt this file completely to your liking, but it should at least | ||
contain the root `toctree` directive. | ||
|
||
Welcome to pyexample's documentation! | ||
===================================== | ||
|
||
Hey there friend! |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,7 +9,12 @@ class LanguageIntegrationTests(unittest.TestCase): | |
|
||
def _run_test(self, test_dir, test_file, test_string, builder='html'): | ||
with build_output(test_dir, test_file, builder) as data: | ||
self.assertIn(test_string, data) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I replate this to test more easily the output :) |
||
if not isinstance(test_string, list): | ||
test_strings = [test_string] | ||
else: | ||
test_strings = test_string | ||
for string in test_strings: | ||
self.assertIn(string, data) | ||
|
||
|
||
class IntegrationTests(LanguageIntegrationTests): | ||
|
@@ -56,3 +61,25 @@ def test_searchtools_is_patched(self): | |
HtmlBuilderMixin.REPLACEMENT_PATTERN | ||
) | ||
self.assertIn(HtmlBuilderMixin.REPLACEMENT_TEXT, data) | ||
|
||
def test_generate_json_artifacts(self): | ||
self._run_test( | ||
'pyexample-json', | ||
'_build/json/index.fjson', | ||
[ | ||
'current_page_name', 'title', 'body', | ||
'toc', 'sourcename', 'rellinks', 'page_source_suffix', | ||
], | ||
) | ||
|
||
def test_no_generate_json_artifacts(self): | ||
with self.assertRaises(IOError) as e: | ||
self._run_test( | ||
'pyexample', | ||
'_build/json/index.fjson', | ||
['current_page_name', 'title', 'body', 'toc'], | ||
) | ||
self.assertIn( | ||
"No such file or directory: '_build/json/index.fjson'", | ||
str(e.exception) | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sphinx 1.4 has the logging module, but not
getLogger