rewrite the project as a static site generator

this removes Flask, reworks a number of library methods accordingly, and
adds generators and build commands to process the instance directory
(largely unchanged, except config.py is now config.json) and spit out
files suitable to be served by a web server such as Nginx.

there are probably some rough edges here, but overall this works.

also note, as this is no longer server software on a network, the
license has changed from AGPLv3 to GPLv3, and the "or any later version"
allowance has been removed

Signed-off-by: Brian S. Stephan <bss@incorporeal.org>
This commit is contained in:
2025-03-12 10:28:38 -05:00
parent ed12272d4d
commit 7eb485c6ae
45 changed files with 1389 additions and 1587 deletions

View File

@@ -1,67 +1,65 @@
"""Test graphviz functionality.
SPDX-FileCopyrightText: © 2021 Brian S. Stephan <bss@incorporeal.org>
SPDX-License-Identifier: AGPL-3.0-or-later
SPDX-License-Identifier: GPL-3.0-only
"""
import os
import tempfile
from incorporealcms import create_app
import pytest
from incorporealcms import init_instance
from incorporealcms.ssg import StaticSiteGenerator
HERE = os.path.dirname(os.path.abspath(__file__))
def app_with_pydot():
"""Create the test app, including the pydot extension."""
return create_app(instance_path=os.path.join(HERE, 'instance'),
test_config={'MARKDOWN_EXTENSIONS': ['incorporealcms.mdx.pydot']})
def test_functional_initialization():
"""Test initialization with the graphviz config."""
app = app_with_pydot()
assert app is not None
init_instance(instance_path=os.path.join(HERE, 'instance'),
extra_config={'MARKDOWN_EXTENSIONS': ['incorporealcms.mdx.pydot', 'incorporealcms.mdx.figures',
'attr_list']})
def test_graphviz_is_rendered():
"""Initialize the app with the graphviz extension and ensure it does something."""
app = app_with_pydot()
client = app.test_client()
with tempfile.TemporaryDirectory() as tmpdir:
src_dir = os.path.join(HERE, 'instance')
ssg = StaticSiteGenerator(src_dir, tmpdir)
os.chdir(os.path.join(src_dir, 'pages'))
response = client.get('/test-graphviz')
assert response.status_code == 200
assert b'~~~pydot' not in response.data
assert b'data:image/png;base64' in response.data
def test_two_graphviz_are_rendered():
"""Test two images are rendered."""
app = app_with_pydot()
client = app.test_client()
response = client.get('/test-two-graphviz')
assert response.status_code == 200
assert b'~~~pydot' not in response.data
assert b'data:image/png;base64' in response.data
ssg.build_file_in_destination(os.path.join(HERE, 'instance', 'pages'), '', 'test-graphviz.md', tmpdir, True)
with open(os.path.join(tmpdir, 'test-graphviz.html'), 'r') as graphviz_output:
data = graphviz_output.read()
assert 'data:image/png;base64' in data
os.chdir(HERE)
def test_invalid_graphviz_is_not_rendered():
"""Check that invalid graphviz doesn't blow things up."""
app = app_with_pydot()
client = app.test_client()
with tempfile.TemporaryDirectory() as tmpdir:
src_dir = os.path.join(HERE, 'instance')
ssg = StaticSiteGenerator(src_dir, tmpdir)
os.chdir(os.path.join(src_dir, 'broken'))
response = client.get('/test-invalid-graphviz')
assert response.status_code == 500
assert b'INTERNAL SERVER ERROR' in response.data
with pytest.raises(ValueError):
ssg.build_file_in_destination(os.path.join(HERE, 'instance', 'broken'), '', 'test-invalid-graphviz.md',
tmpdir, True)
os.chdir(HERE)
def test_figures_are_rendered(client):
def test_figures_are_rendered():
"""Test that a page with my figure syntax renders as expected."""
response = client.get('/figures')
assert response.status_code == 200
assert (b'<figure class="right"><img alt="fancy captioned logo" src="bss-square-no-bg.png" />'
b'<figcaption>this is my cool logo!</figcaption></figure>') in response.data
assert (b'<figure><img alt="vanilla captioned logo" src="bss-square-no-bg.png" />'
b'<figcaption>this is my cool logo without an attr!</figcaption>\n</figure>') in response.data
assert (b'<figure class="left"><img alt="fancy logo" src="bss-square-no-bg.png" />'
b'<span></span></figure>') in response.data
assert b'<figure><img alt="just a logo" src="bss-square-no-bg.png" /></figure>' in response.data
with tempfile.TemporaryDirectory() as tmpdir:
src_dir = os.path.join(HERE, 'instance')
ssg = StaticSiteGenerator(src_dir, tmpdir)
os.chdir(os.path.join(src_dir, 'pages'))
ssg.build_file_in_destination(os.path.join(HERE, 'instance', 'pages'), '', 'figures.md', tmpdir, True)
with open(os.path.join(tmpdir, 'figures.html'), 'r') as graphviz_output:
data = graphviz_output.read()
assert ('<figure class="right"><img alt="fancy captioned logo" src="bss-square-no-bg.png" />'
'<figcaption>this is my cool logo!</figcaption></figure>') in data
assert ('<figure><img alt="vanilla captioned logo" src="bss-square-no-bg.png" />'
'<figcaption>this is my cool logo without an attr!</figcaption>\n</figure>') in data
assert ('<figure class="left"><img alt="fancy logo" src="bss-square-no-bg.png" />'
'<span></span></figure>') in data
assert '<figure><img alt="just a logo" src="bss-square-no-bg.png" /></figure>' in data
os.chdir(HERE)