Add extracted tools: CitrineOS, OpenOCPP, ShapeShifter

- CitrineOS core extracted (CSMS OCPP 2.0.1)
- OpenOCPP extracted (firmware OCPP 1.6J/2.0.1)
- ShapeShifter library installed (pip install -e)
- ShapeShifter specification extracted
- EVerest extracted

TODO updated with progress
This commit is contained in:
Eric F
2026-06-08 00:38:27 -04:00
parent 468cfeaa50
commit d398a6ced2
7326 changed files with 1177561 additions and 7 deletions

View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2019 Manuel Kaufmann
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1 @@
__version__ = "0.2.0"

View File

@@ -0,0 +1,329 @@
import docutils
import os
import sphinx
import warnings
from sphinx.environment.collectors import EnvironmentCollector
from sphinx.errors import ExtensionError
from . import __version__
from .utils import replace_uris
class BaseURIError(ExtensionError):
"""Exception for malformed base URI."""
pass
# https://www.sphinx-doc.org/en/stable/extdev/appapi.html#event-html-collect-pages
def html_collect_pages(app):
"""
Create for each ``<pagename>`` a html page.
Uses ``<template>`` as a template to be rendered with
``<context>`` for its context. The resulting file generated is
``<pagename>.html``.
If the user already defined a page with pagename title
``<pagename>``, we don't generate this page.
:param app: Sphinx Application
:type app: sphinx.application.Sphinx
"""
result = []
for page in app.config.staticpages_pages:
if page['pagename'] in app.env.titles:
# There is already a ``<pagename>.rst`` file rendered.
# Skip generating our default one.
continue
result.append((
page['pagename'],
page['context'],
page['template'],
))
return result
# https://www.sphinx-doc.org/en/stable/extdev/appapi.html#event-html-page-context
def finalize_media(app, pagename, templatename, context, doctree):
"""
Point media files at our media server.
Generate absolute URLs for resources (js, images, css, etc) to point to the
right URL. For example, if a URL in the page is ``_static/js/custom.js`` it will
be replaced by ``<urls_prefix>/_static/js/custom.js``.
Also, all the links from the sidebar (toctree) are replaced with their
absolute version. For example, ``../section/pagename.html`` will be replaced
by ``/section/pagename.html``.
It handles a special case for Read the Docs and URLs starting with ``/_/``.
These URLs have a special meaning under Read the Docs and don't have to be changed.
(e.g. ``/_/static/javascript/readthedocs-doc-embed.js``)
:param app: Sphinx Application
:type app: sphinx.application.Sphinx
:param pagename: name of the page being rendered
:type pagename: str
:param templatename: template used to render the page
:type templatename: str
:param context: context used to render the page
:type context: dict
:param doctree: doctree of the page being rendered
:type doctree: docutils.nodes.document
"""
# https://github.com/sphinx-doc/sphinx/blob/7138d03ba033e384f1e7740f639849ba5f2cc71d/sphinx/builders/html.py#L1054-L1065
def pathto(otheruri, resource=False, baseuri=None):
"""
Hack pathto to display absolute URL's.
Instead of calling ``relative_url`` function, we call
``app.builder.get_target_uri`` to get the absolute URL.
.. note::
If ``otheruri`` is a external ``resource`` it does not modify it.
If ``otheruri`` is a static file on Read the Docs it does not modify it.
"""
current_page = {}
for page in app.config.staticpages_pages:
if page['pagename'] == pagename:
current_page = page
break
READTHEDOCS = os.environ.get('READTHEDOCS', False) == 'True'
if resource and '://' in otheruri:
# allow non-local resources given by scheme
return otheruri
if READTHEDOCS and otheruri.startswith('/_/'):
# special case on Read the Docs
return otheruri
if not resource:
otheruri = app.builder.get_target_uri(otheruri)
if baseuri is None:
if current_page['urls_prefix'] is None:
baseuri = '/'
else:
baseuri = '{prefix}'.format(
prefix=current_page['urls_prefix'] or '/',
)
if not baseuri.startswith('/'):
raise BaseURIError('"baseuri" must be absolute')
if otheruri and not otheruri.startswith('/'):
otheruri = '/' + otheruri
if otheruri:
if baseuri.endswith('/'):
baseuri = baseuri[:-1]
otheruri = baseuri + otheruri
uri = otheruri or '#'
return uri
# https://github.com/sphinx-doc/sphinx/blob/2adeb68af1763be46359d5e808dae59d708661b1/sphinx/builders/html.py#L1081
def toctree(*args, **kwargs):
current_page = {}
for page in app.config.staticpages_pages:
if page['pagename'] == pagename:
current_page = page
break
try:
# Sphinx >= 1.6
from sphinx.environment.adapters.toctree import TocTree
get_toctree_for = TocTree(app.env).get_toctree_for
except ImportError:
# Sphinx < 1.6
get_toctree_for = app.env.get_toctree_for
toc = get_toctree_for(
current_page['pagename'],
app.builder,
collapse=kwargs.pop('collapse', False),
includehidden=kwargs.pop('includehidden', False),
**kwargs # not using trailing comma here makes this compatible with
# Python2 syntax
)
# If no TOC is found, just return ``None`` instead of failing here
if not toc:
return None
replace_uris(app, toc, docutils.nodes.reference, 'refuri')
return app.builder.render_partial(toc)['fragment']
# Borrowed from Sphinx<4.x to backward compatibility
# https://github.com/sphinx-doc/sphinx/blob/v3.5.4/sphinx/builders/html/__init__.py#L1003-L1010
def css_tag(css):
attrs = []
for key in sorted(css.attributes):
value = css.attributes[key]
if value is not None:
if sphinx.version_info < (2, 0):
# https://github.com/sphinx-doc/sphinx/blob/v1.8.5/sphinx/builders/html.py#L1144
from sphinx.util.pycompat import htmlescape
attrs.append('%s="%s"' % (key, htmlescape(value, True)))
else:
import html
attrs.append('%s="%s"' % (key, html.escape(value, True)))
attrs.append('href="%s"' % pathto(css.filename, resource=True))
return '<link %s />' % ' '.join(attrs)
# Apply our custom manipulation for each <pagename>.html page only
pagenames = []
pagenames.extend(page['pagename'] for page in app.config.staticpages_pages)
if pagename in pagenames:
# Override the ``pathto`` helper function from the context to use a custom one
# https://www.sphinx-doc.org/en/master/templating.html#pathto
context['pathto'] = pathto
# Override the ``toctree`` helper function from context to use a custom
# one and generate valid links on not found page.
# https://www.sphinx-doc.org/en/master/templating.html#toctree
# NOTE: not used on ``singlehtml`` builder for RTD Sphinx theme
context['toctree'] = toctree
if sphinx.version_info < (4, 0) or sphinx.version_info >= (7, 0):
context['css_tag'] = css_tag
# https://www.sphinx-doc.org/en/stable/extdev/appapi.html#event-doctree-resolved
def doctree_resolved(app, doctree, docname):
"""
Generate and override URLs for ``.. image::`` Sphinx directive.
When ``.. image::`` is used in the ``<pagename>.rst`` file, this function will
override the URLs to point to the right place.
:param app: Sphinx Application
:type app: sphinx.application.Sphinx
:param doctree: doctree representing the document
:type doctree: docutils.nodes.document
:param docname: name of the document
:type docname: str
"""
pagenames = []
pagenames.extend(item['pagename'] for item in app.config.staticpages_pages)
if docname in pagenames:
# Replace image ``uri`` to its absolute version
replace_uris(app, doctree, docutils.nodes.image, 'uri')
class OrphanMetadataCollector(EnvironmentCollector):
"""
Force the staicpages pages to be ``orphan``.
This way we remove the WARNING that Sphinx raises saying the page is not
included in any toctree.
This collector has the same effect than ``:orphan:`` at the top of the page.
"""
def clear_doc(self, app, env, docname):
return None
def process_doc(self, app, doctree):
for page in app.config.staticpages_pages:
metadata = app.env.metadata[page['pagename']]
metadata.update({'orphan': True})
if sphinx.version_info >= (3, 0, 0):
metadata.update({'nosearch': True})
def merge_other(self, app, env, docnames, other):
"""Merge in specified data regarding docnames from a different `BuildEnvironment`
object which coming from a subprocess in parallel builds."""
# TODO: find an example about why this is strictly required for parallel read
# https://github.com/readthedocs/sphinx-notfound-page/pull/112/files#r498219556
env.metadata.update(other.metadata)
def validate_configs(app, *args, **kwargs):
"""
Validate configs.
Shows a warning if one of the configs is not valid.
"""
for page in app.config.staticpages_pages:
if 'pagename' not in page:
message = 'pagename is required for each page'
warnings.warn(message, UserWarning, stacklevel=2)
if 'template' not in page:
page.update({'template': 'page.html'})
message = 'template is required for each page, using default'
warnings.warn(message, UserWarning, stacklevel=2)
if 'context' not in page:
page.update({'context': {
'title': 'Page Title',
'body': "<h1>Page Title</h1>\n\nThis is a placeholder page.",
}})
message = 'context is required for each page, using default'
warnings.warn(message, UserWarning, stacklevel=2)
if 'urls_prefix' not in page:
message = 'urls_prefix is required for each page'
warnings.warn(message, UserWarning, stacklevel=2)
def setup(app):
default_pages = [{
'template': 'page.html',
'context': {
'title': 'Versions Index',
'body': "<h1>Versions Index</h1>\n\nThis is a placeholder page for versions index.",
},
'pagename': 'versions_index',
'urls_prefix': '/en/latest/',
}]
app.add_config_value('staticpages_pages', default_pages, 'html')
# FIXME this config shouldn't exist, see _ext/staticpages/utils.py
app.add_config_value('staticpages_urls_prefix', None, 'html')
if sphinx.version_info > (1, 8, 0):
app.connect('config-inited', validate_configs)
else:
app.connect('builder-inited', validate_configs)
app.connect('html-collect-pages', html_collect_pages)
if sphinx.version_info >= (3, 0, 0):
# Use ``priority=400`` argument here because we want to execute our function
# *before* Sphinx's ``setup_resource_paths`` where the ``logo_url`` and
# ``favicon_url`` are resolved.
# See https://github.com/readthedocs/sphinx-notfound-page/issues/180#issuecomment-959506037
app.connect('html-page-context', finalize_media, priority=400)
else:
app.connect('html-page-context', finalize_media)
app.connect('doctree-resolved', doctree_resolved)
# Sphinx injects some javascript files using ``add_js_file``. The path for
# this file is rendered in the template using ``js_tag`` instead of
# ``pathto``. The ``js_tag`` uses ``pathto`` internally to resolve these
# paths, we call again the setup function for this tag *after* the context
# was overridden by our extension with the patched ``pathto`` function.
if sphinx.version_info < (7, 0):
if sphinx.version_info >= (1, 8):
from sphinx.builders.html import setup_js_tag_helper
app.connect('html-page-context', setup_js_tag_helper)
if sphinx.version_info >= (4, 0):
# CSS are now added via a ``css_tag``
# https://github.com/sphinx-doc/sphinx/pull/8643
from sphinx.builders.html import setup_css_tag_helper
app.connect('html-page-context', setup_css_tag_helper)
app.add_env_collector(OrphanMetadataCollector)
return {
'version': __version__,
'parallel_read_safe': True,
'parallel_write_safe': True,
}

View File

@@ -0,0 +1,79 @@
import docutils
import re
import sphinx
# Sphinx <2 Compatibility
if sphinx.version_info >= (2, 0):
from sphinx.builders.dirhtml import DirectoryHTMLBuilder
else:
from sphinx.builders.html import DirectoryHTMLBuilder
def replace_uris(app, doctree, nodetype, nodeattr):
"""
Replace ``nodetype`` URIs from ``doctree`` to the proper one.
If ``nodetype`` is an image (``docutils.nodes.image``), the URL is prefixed
with ``Builder.imagedir`` and the original image path is added to
``Builder.images`` so it's copied using Sphinx's internals before
finalizing the building.
:param app: Sphinx Application
:type app: sphinx.application.Sphinx
:param doctree: doctree representing the document
:type doctree: docutils.nodes.document
:param nodetype: type of node to replace URIs
:type nodetype: docutils.nodes.Node
:param nodeattr: node attribute to be replaced
:type nodeattr: str
"""
# https://github.com/sphinx-doc/sphinx/blob/2adeb68af1763be46359d5e808dae59d708661b1/sphinx/environment/adapters/toctree.py#L260-L266
for node in doctree.traverse(nodetype):
uri = olduri = node.attributes.get(nodeattr) # somepage.html (or ../sompage.html)
if isinstance(app.builder, DirectoryHTMLBuilder):
# When the builder is ``DirectoryHTMLBuilder``, refuri will be
# ``../somepage.html``. In that case, we want to remove the
# initial ``../`` to make valid links
if uri.startswith('../'):
uri = uri.replace('../', '')
if re.match('^https?://', uri):
# allow non-local URLs for resources
continue
imagedir = ''
if nodetype is docutils.nodes.image:
# Prefix the URL with ``Builder.imagedir`` to use the internal's
# Sphinx image handling if the node is an image
imagedir = '{imagedir}/'.format(
imagedir=app.builder.imagedir,
)
# The image is copied into ``app.builder.imagedir`` without keeping
# the directory structure, so we need only the filename for the
# correct link
uri = olduri.split('/')[-1]
uri = '{prefix}{imagedir}{filename}'.format(
prefix=app.config.staticpages_urls_prefix or '/',
imagedir=imagedir,
filename=uri,
)
node.replace_attr(nodeattr, uri)
# Force adding the image to the builder so it's copied at ``Builder.copy_image_files``
# https://github.com/sphinx-doc/sphinx/blob/5ce5c2c3156c53c1f1b758c38150e48080138b15/sphinx/builders/html.py#L721
# We need to do this at this point because ``Builder.post_process_images``
# does not add it automatically as the path does not match.
# https://github.com/sphinx-doc/sphinx/blob/5ce5c2c3156c53c1f1b758c38150e48080138b15/sphinx/builders/__init__.py#L189
if nodetype is docutils.nodes.image:
if all([
not olduri.startswith('data:'),
'://' not in olduri,
]):
app.builder.images[olduri] = olduri.split('/')[-1]