Compare commits

..

No commits in common. "201cd808045f0a10c0261215235dc8bf8c390f97" and "b69bdb424a8e44737bba3b3e461062e4beb80749" have entirely different histories.

30 changed files with 61 additions and 88 deletions

24
.reuse/dep5 Normal file
View File

@ -0,0 +1,24 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: incorporeal-cms
Upstream-Contact: Brian S. Stephan <bss@incorporeal.org>
Source: https://git.incorporeal.org/bss/incorporeal-cms
# Trivial files
Files: .gitignore .gitattributes
Copyright: © 2020 Brian S. Stephan <bss@incorporeal.org>
License: GPL-3.0-only
# High level repo docs
Files: *.md
Copyright: © 2020 Brian S. Stephan <bss@incorporeal.org>
License: GPL-3.0-only
# Test data
Files: tests/instance/*
Copyright: © 2020 Brian S. Stephan <bss@incorporeal.org>
License: GPL-3.0-only
# Python packaging, scaffolding, and errata
Files: MANIFEST.in pyproject.toml tox.ini requirements/*
Copyright: © 2020 Brian S. Stephan <bss@incorporeal.org>
License: GPL-3.0-only

View File

@ -54,16 +54,17 @@ out and discuss issues and features and whatnot.
Written by and copyright (C) 2025 Brian S. Stephan (bss@incorporeal.org). Written by and copyright (C) 2025 Brian S. Stephan (bss@incorporeal.org).
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General This program is free software: you can redistribute it and/or modify
Public License as published by the Free Software Foundation, either version 3 of the License, or (at your it under the terms of the GNU General Public License as published by
option) any later version. the Free Software Foundation, version 3 of the License.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the This program is distributed in the hope that it will be useful,
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for but WITHOUT ANY WARRANTY; without even the implied warranty of
more details. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see You should have received a copy of the GNU General Public License
<https://www.gnu.org/licenses/>. along with this program. If not, see <https://www.gnu.org/licenses/>.
### Content Output ### Content Output

View File

@ -1,28 +0,0 @@
version = 1
SPDX-PackageName = "incorporeal-cms"
SPDX-PackageSupplier = "Brian S. Stephan <bss@incorporeal.org>"
SPDX-PackageDownloadLocation = "https://git.incorporeal.org/bss/incorporeal-cms"
[[annotations]]
path = [".gitignore", ".gitattributes"]
precedence = "aggregate"
SPDX-FileCopyrightText = "© 2020 Brian S. Stephan <bss@incorporeal.org>"
SPDX-License-Identifier = "GPL-3.0-or-later"
[[annotations]]
path = "**.md"
precedence = "aggregate"
SPDX-FileCopyrightText = "© 2020 Brian S. Stephan <bss@incorporeal.org>"
SPDX-License-Identifier = "GPL-3.0-or-later"
[[annotations]]
path = "tests/instance/**"
precedence = "aggregate"
SPDX-FileCopyrightText = "© 2020 Brian S. Stephan <bss@incorporeal.org>"
SPDX-License-Identifier = "GPL-3.0-or-later"
[[annotations]]
path = ["MANIFEST.in", "pyproject.toml", "tox.ini", "requirements/**"]
precedence = "aggregate"
SPDX-FileCopyrightText = "© 2020 Brian S. Stephan <bss@incorporeal.org>"
SPDX-License-Identifier = "GPL-3.0-or-later"

View File

@ -1,7 +1,7 @@
"""An application for running my Markdown-based sites. """An application for running my Markdown-based sites.
SPDX-FileCopyrightText: © 2025 Brian S. Stephan <bss@incorporeal.org> SPDX-FileCopyrightText: © 2025 Brian S. Stephan <bss@incorporeal.org>
SPDX-License-Identifier: GPL-3.0-or-later SPDX-License-Identifier: GPL-3.0-only
""" """
import json import json
import logging import logging

View File

@ -1,7 +1,7 @@
"""Default configuration. """Default configuration.
SPDX-FileCopyrightText: © 2020 Brian S. Stephan <bss@incorporeal.org> SPDX-FileCopyrightText: © 2020 Brian S. Stephan <bss@incorporeal.org>
SPDX-License-Identifier: GPL-3.0-or-later SPDX-License-Identifier: GPL-3.0-only
""" """

View File

@ -1,7 +1,7 @@
"""Process the error page templates. """Process the error page templates.
SPDX-FileCopyrightText: © 2025 Brian S. Stephan <bss@incorporeal.org> SPDX-FileCopyrightText: © 2025 Brian S. Stephan <bss@incorporeal.org>
SPDX-License-Identifier: GPL-3.0-or-later SPDX-License-Identifier: GPL-3.0-only
""" """
import os import os

View File

@ -7,7 +7,7 @@ under pages/ (which may make sense for a blog) if they want, but could just
as well be pages/foo content. as well be pages/foo content.
SPDX-FileCopyrightText: © 2023 Brian S. Stephan <bss@incorporeal.org> SPDX-FileCopyrightText: © 2023 Brian S. Stephan <bss@incorporeal.org>
SPDX-License-Identifier: GPL-3.0-or-later SPDX-License-Identifier: GPL-3.0-only
""" """
import logging import logging
import os import os

View File

@ -5,7 +5,7 @@ as is, but .md files need to be processed with a Markdown parser, so a lot of th
is our tweaks and customizations for pages my way. is our tweaks and customizations for pages my way.
SPDX-FileCopyrightText: © 2025 Brian S. Stephan <bss@incorporeal.org> SPDX-FileCopyrightText: © 2025 Brian S. Stephan <bss@incorporeal.org>
SPDX-License-Identifier: GPL-3.0-or-later SPDX-License-Identifier: GPL-3.0-only
""" """
import datetime import datetime
import logging import logging

View File

@ -1,5 +1,5 @@
"""Markdown extensions. """Markdown extensions.
SPDX-FileCopyrightText: © 2021 Brian S. Stephan <bss@incorporeal.org> SPDX-FileCopyrightText: © 2021 Brian S. Stephan <bss@incorporeal.org>
SPDX-License-Identifier: GPL-3.0-or-later SPDX-License-Identifier: GPL-3.0-only
""" """

View File

@ -1,7 +1,7 @@
"""Create generic figures with captions. """Create generic figures with captions.
SPDX-FileCopyrightText: © 2022 Brian S. Stephan <bss@incorporeal.org> SPDX-FileCopyrightText: © 2022 Brian S. Stephan <bss@incorporeal.org>
SPDX-License-Identifier: GPL-3.0-or-later SPDX-License-Identifier: GPL-3.0-only
""" """
import re import re
from xml.etree.ElementTree import SubElement # nosec B405 from xml.etree.ElementTree import SubElement # nosec B405

View File

@ -1,7 +1,7 @@
"""Serve dot diagrams inline. """Serve dot diagrams inline.
SPDX-FileCopyrightText: © 2021 Brian S. Stephan <bss@incorporeal.org> SPDX-FileCopyrightText: © 2021 Brian S. Stephan <bss@incorporeal.org>
SPDX-License-Identifier: GPL-3.0-or-later SPDX-License-Identifier: GPL-3.0-only
""" """
import base64 import base64
import logging import logging

View File

@ -1,7 +1,7 @@
"""Build an instance as a static site suitable for serving via e.g. Nginx. """Build an instance as a static site suitable for serving via e.g. Nginx.
SPDX-FileCopyrightText: © 2025 Brian S. Stephan <bss@incorporeal.org> SPDX-FileCopyrightText: © 2025 Brian S. Stephan <bss@incorporeal.org>
SPDX-License-Identifier: GPL-3.0-or-later SPDX-License-Identifier: GPL-3.0-only
""" """
import argparse import argparse
import logging import logging
@ -142,14 +142,6 @@ class StaticSiteGenerator(object):
src = self.symlink_to_relative_dest(source_dir, os.path.join(base_dir, file_)) src = self.symlink_to_relative_dest(source_dir, os.path.join(base_dir, file_))
print(f"creating symlink '{dst}' -> '{src}'") print(f"creating symlink '{dst}' -> '{src}'")
os.symlink(src, dst, target_is_directory=False) os.symlink(src, dst, target_is_directory=False)
if src.endswith('.md') and convert_markdown:
# we also need to make a .html symlink so that web server configs
# pick up the "redirect"
second_src = src.removesuffix('.md') + '.html'
second_dst = dst.removesuffix('.md') + '.html'
print(f"creating symlink '{second_dst}' -> '{second_src}'")
os.symlink(second_src, second_dst, target_is_directory=False)
else: else:
src = os.path.join(base_dir, file_) src = os.path.join(base_dir, file_)
print(f"copying file '{src}' -> '{dst}'") print(f"copying file '{src}' -> '{dst}'")

View File

@ -1,6 +1,6 @@
/* /*
* SPDX-FileCopyrightText: © 2020 Brian S. Stephan <bss@incorporeal.org> * SPDX-FileCopyrightText: © 2020 Brian S. Stephan <bss@incorporeal.org>
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-only
*/ */
html { html {

View File

@ -1,6 +1,6 @@
/* /*
* SPDX-FileCopyrightText: © 2020 Brian S. Stephan <bss@incorporeal.org> * SPDX-FileCopyrightText: © 2020 Brian S. Stephan <bss@incorporeal.org>
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-only
*/ */
/* common styling via the base.css, used in light and dark */ /* common styling via the base.css, used in light and dark */

View File

@ -1,6 +1,6 @@
/* /*
* SPDX-FileCopyrightText: © 2020 Brian S. Stephan <bss@incorporeal.org> * SPDX-FileCopyrightText: © 2020 Brian S. Stephan <bss@incorporeal.org>
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-only
*/ */
/* common styling via the base.css, used in light and dark */ /* common styling via the base.css, used in light and dark */

View File

@ -1,6 +1,6 @@
/* /*
* SPDX-FileCopyrightText: © 2020 Brian S. Stephan <bss@incorporeal.org> * SPDX-FileCopyrightText: © 2020 Brian S. Stephan <bss@incorporeal.org>
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-only
*/ */
/* specify almost no styling, just fix some image and nav rendering */ /* specify almost no styling, just fix some image and nav rendering */

View File

@ -5,7 +5,7 @@
* of my CMS, so I want to keep it around even in the static site. * of my CMS, so I want to keep it around even in the static site.
* *
* SPDX-FileCopyrightText: © 2025 Brian S. Stephan <bss@incorporeal.org> * SPDX-FileCopyrightText: © 2025 Brian S. Stephan <bss@incorporeal.org>
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-only
*/ */
/** /**

View File

@ -1,6 +1,6 @@
{# {#
SPDX-FileCopyrightText: © 2020 Brian S. Stephan <bss@incorporeal.org> SPDX-FileCopyrightText: © 2020 Brian S. Stephan <bss@incorporeal.org>
SPDX-License-Identifier: GPL-3.0-or-later SPDX-License-Identifier: GPL-3.0-only
#} #}
{% extends "base.html" %} {% extends "base.html" %}

View File

@ -1,6 +1,6 @@
{# {#
SPDX-FileCopyrightText: © 2020 Brian S. Stephan <bss@incorporeal.org> SPDX-FileCopyrightText: © 2020 Brian S. Stephan <bss@incorporeal.org>
SPDX-License-Identifier: GPL-3.0-or-later SPDX-License-Identifier: GPL-3.0-only
#} #}
{% extends "base.html" %} {% extends "base.html" %}

View File

@ -1,6 +1,6 @@
{# {#
SPDX-FileCopyrightText: © 2020 Brian S. Stephan <bss@incorporeal.org> SPDX-FileCopyrightText: © 2020 Brian S. Stephan <bss@incorporeal.org>
SPDX-License-Identifier: GPL-3.0-or-later SPDX-License-Identifier: GPL-3.0-only
#} #}
{% extends "base.html" %} {% extends "base.html" %}

View File

@ -1,6 +1,6 @@
{# {#
SPDX-FileCopyrightText: © 2020 Brian S. Stephan <bss@incorporeal.org> SPDX-FileCopyrightText: © 2020 Brian S. Stephan <bss@incorporeal.org>
SPDX-License-Identifier: GPL-3.0-or-later SPDX-License-Identifier: GPL-3.0-only
#} #}
{% extends "base.html" %} {% extends "base.html" %}
{% block site_class %}class="site-wrap site-wrap-double-width"{% endblock %} {% block site_class %}class="site-wrap site-wrap-double-width"{% endblock %}

View File

@ -1,6 +1,6 @@
<!doctype html>{# <!doctype html>{#
SPDX-FileCopyrightText: © 2020 Brian S. Stephan <bss@incorporeal.org> SPDX-FileCopyrightText: © 2020 Brian S. Stephan <bss@incorporeal.org>
SPDX-License-Identifier: GPL-3.0-or-later SPDX-License-Identifier: GPL-3.0-only
#} #}
<html lang="en"> <html lang="en">
<title>{{ title }}</title> <title>{{ title }}</title>

View File

@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta"
name = "incorporeal-cms" name = "incorporeal-cms"
description = "A lightweight static site generator for Markdown-based sites." description = "A lightweight static site generator for Markdown-based sites."
readme = "README.md" readme = "README.md"
license = {text = "GPL-3.0-or-later"} license = {text = "GPL-3.0-only"}
authors = [ authors = [
{name = "Brian S. Stephan", email = "bss@incorporeal.org"}, {name = "Brian S. Stephan", email = "bss@incorporeal.org"},
] ]
@ -14,8 +14,9 @@ requires-python = ">=3.9"
dependencies = ["feedgen", "jinja2", "Markdown", "termcolor"] dependencies = ["feedgen", "jinja2", "Markdown", "termcolor"]
dynamic = ["version"] dynamic = ["version"]
classifiers = [ classifiers = [
"Framework :: Flask",
"Programming Language :: Python :: 3", "Programming Language :: Python :: 3",
"License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)", "License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
"Operating System :: OS Independent", "Operating System :: OS Independent",
"Topic :: Text Processing :: Markup :: Markdown", "Topic :: Text Processing :: Markup :: Markdown",
] ]

View File

@ -1,7 +1,7 @@
"""Test graphviz functionality. """Test graphviz functionality.
SPDX-FileCopyrightText: © 2021 Brian S. Stephan <bss@incorporeal.org> SPDX-FileCopyrightText: © 2021 Brian S. Stephan <bss@incorporeal.org>
SPDX-License-Identifier: GPL-3.0-or-later SPDX-License-Identifier: GPL-3.0-only
""" """
import os import os
import tempfile import tempfile

View File

@ -1,7 +1,7 @@
"""Test command line invocations. """Test command line invocations.
SPDX-FileCopyrightText: © 2025 Brian S. Stephan <bss@incorporeal.org> SPDX-FileCopyrightText: © 2025 Brian S. Stephan <bss@incorporeal.org>
SPDX-License-Identifier: GPL-3.0-or-later SPDX-License-Identifier: GPL-3.0-only
""" """
import os import os
import tempfile import tempfile

View File

@ -1,7 +1,7 @@
"""Test basic configuration stuff. """Test basic configuration stuff.
SPDX-FileCopyrightText: © 2020 Brian S. Stephan <bss@incorporeal.org> SPDX-FileCopyrightText: © 2020 Brian S. Stephan <bss@incorporeal.org>
SPDX-License-Identifier: GPL-3.0-or-later SPDX-License-Identifier: GPL-3.0-only
""" """
import os import os

View File

@ -1,7 +1,7 @@
"""Test the feed methods. """Test the feed methods.
SPDX-FileCopyrightText: © 2023 Brian S. Stephan <bss@incorporeal.org> SPDX-FileCopyrightText: © 2023 Brian S. Stephan <bss@incorporeal.org>
SPDX-License-Identifier: GPL-3.0-or-later SPDX-License-Identifier: GPL-3.0-only
""" """
import os import os
import tempfile import tempfile

View File

@ -1,7 +1,7 @@
"""Test the conversion of Markdown pages. """Test the conversion of Markdown pages.
SPDX-FileCopyrightText: © 2025 Brian S. Stephan <bss@incorporeal.org> SPDX-FileCopyrightText: © 2025 Brian S. Stephan <bss@incorporeal.org>
SPDX-License-Identifier: GPL-3.0-or-later SPDX-License-Identifier: GPL-3.0-only
""" """
import os import os
from unittest.mock import patch from unittest.mock import patch

View File

@ -1,7 +1,7 @@
"""Test the high level SSG operations. """Test the high level SSG operations.
SPDX-FileCopyrightText: © 2025 Brian S. Stephan <bss@incorporeal.org> SPDX-FileCopyrightText: © 2025 Brian S. Stephan <bss@incorporeal.org>
SPDX-License-Identifier: GPL-3.0-or-later SPDX-License-Identifier: GPL-3.0-only
""" """
import os import os
import tempfile import tempfile
@ -52,23 +52,6 @@ def test_file_copy_symlink():
assert os.path.islink(os.path.join(tmpdir, 'symlink-to-foo.txt')) assert os.path.islink(os.path.join(tmpdir, 'symlink-to-foo.txt'))
def test_file_copy_symlink_of_markdown_also_has_html_symlink():
"""Test the ability to sync source and generated symlinks to the output dir."""
with tempfile.TemporaryDirectory() as tmpdir:
src_dir = os.path.join(HERE, 'instance')
generator = ssg.StaticSiteGenerator(src_dir, tmpdir)
os.chdir(os.path.join(instance_dir, 'pages'))
generator.build_file_in_destination(os.path.join(instance_dir, 'pages'), '', 'symlink-to-no-title.md', tmpdir,
True)
# need to copy the destination for os.path.exists to be happy with this
generator.build_file_in_destination(os.path.join(instance_dir, 'pages'), '', 'no-title.md', tmpdir, True)
assert os.path.exists(os.path.join(tmpdir, 'symlink-to-no-title.md'))
assert os.path.islink(os.path.join(tmpdir, 'symlink-to-no-title.md'))
# a .md symlink should also create the .html symlink (see issue #24)
assert os.path.exists(os.path.join(tmpdir, 'symlink-to-no-title.html'))
assert os.path.islink(os.path.join(tmpdir, 'symlink-to-no-title.html'))
def test_dir_copy(): def test_dir_copy():
"""Test the ability to sync a directory to the output dir.""" """Test the ability to sync a directory to the output dir."""
with tempfile.TemporaryDirectory() as tmpdir: with tempfile.TemporaryDirectory() as tmpdir: