From 8fe474561a4011fa5b63a9b472e726f39cb3ec1a Mon Sep 17 00:00:00 2001 From: sigmasternchen Date: Tue, 7 Jan 2025 09:45:05 +0100 Subject: [PATCH 1/7] docs: Fix wrong license in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8fc4fed..a564fb8 100644 --- a/README.md +++ b/README.md @@ -134,7 +134,7 @@ Contributions are welcome! If you have suggestions or improvements, feel free to ## License -This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details. +This project is licensed under the BSD-2-Clause License. See the [LICENSE](LICENSE) file for details. ## Acknowledgments From b2d8198d1daa167ccd4db83e1f13076827702d4d Mon Sep 17 00:00:00 2001 From: sigmasternchen Date: Tue, 7 Jan 2025 20:14:49 +0100 Subject: [PATCH 2/7] refactor: Extract individual features into toggleable modules --- grimoire-ssg/__main__.py | 131 ------------------------------ grimoiressg/__main__.py | 25 ++++++ grimoiressg/arguments.py | 31 +++++++ grimoiressg/config.py | 35 ++++++++ grimoiressg/content_files.py | 39 +++++++++ grimoiressg/modules/__init__.py | 9 ++ grimoiressg/modules/markdown.py | 8 ++ grimoiressg/modules/tags.py | 18 ++++ grimoiressg/modules/templating.py | 36 ++++++++ grimoiressg/utils/__init__.py | 1 + grimoiressg/utils/files.py | 18 ++++ pyproject.toml | 2 +- 12 files changed, 221 insertions(+), 132 deletions(-) delete mode 100644 grimoire-ssg/__main__.py create mode 100644 grimoiressg/__main__.py create mode 100644 grimoiressg/arguments.py create mode 100644 grimoiressg/config.py create mode 100644 grimoiressg/content_files.py create mode 100644 grimoiressg/modules/__init__.py create mode 100644 grimoiressg/modules/markdown.py create mode 100644 grimoiressg/modules/tags.py create mode 100644 grimoiressg/modules/templating.py create mode 100644 grimoiressg/utils/__init__.py create mode 100644 grimoiressg/utils/files.py diff --git a/grimoire-ssg/__main__.py b/grimoire-ssg/__main__.py deleted file mode 100644 index b89a532..0000000 --- a/grimoire-ssg/__main__.py +++ /dev/null @@ -1,131 +0,0 @@ -import argparse -import glob -import os - -import markdown -import yaml -from jinja2 import Environment, FileSystemLoader -from yaml import Loader - -jinja_env = Environment( - loader=FileSystemLoader("/") -) - - -def to_relative(path): - trimmed = path.removeprefix(os.getcwd()) - if trimmed != path: - trimmed = "." + trimmed - return trimmed - - -def compile_markdown(data): - for entry in data: - if "markdown" in entry: - print(f"Compiling markdown for {entry['relative_filename']}...") - entry["markdown_compiled"] = markdown.markdown(entry["markdown"]) - - -def render(data, tags, output_dir): - files_written = 0 - - for entry in data: - if "template" in entry: - template_path = os.path.realpath(os.path.dirname(entry["filename"]) + "/" + entry["template"]) - template_dir = os.path.dirname(template_path) - print(f"Rendering template for {entry['relative_filename']}...") - template = jinja_env.get_template(template_path) - entry["rendered"] = template.render(current=entry, all=data, tags=tags, template_dir=template_dir) - - if "rendered" in entry and "output" in entry: - files_written += 1 - filename = os.path.realpath(output_dir + "/" + entry["output"]) - print(f" ... writing to {to_relative(filename)}") - os.makedirs(os.path.dirname(filename), exist_ok=True) - with open(filename, "w") as file: - file.write(entry["rendered"]) - - return files_written - - -def extract_tags(data): - tags = {} - - for entry in data: - for tag in entry.get("tags", []): - entry_list = tags.get(tag, []) - entry_list.append(entry) - tags[tag] = entry_list - - print(f"Found tags: " + repr(list(tags.keys()))) - - return tags - - -def handle_file_or_glob(globname): - results = [] - - for filename in glob.glob(os.path.realpath(globname)): - results.extend(handle_file(filename)) - - return results - - -def handle_file(filename): - print(f"Reading {to_relative(filename)}...") - - with open(filename, "r") as file: - data = yaml.load(file, Loader) - - data["filename"] = filename - data["relative_filename"] = to_relative(filename) - results = [data] - - relative_dir = os.path.dirname(filename) - for filename in data.get("include", []): - filename = relative_dir + "/" + filename - sub_data = handle_file_or_glob(filename) - results.extend(sub_data) - - return results - - -def parse_arguments(): - parser = argparse.ArgumentParser() - parser.add_argument("-o", "--output", default="./output/") - - args, filenames = parser.parse_known_args() - - return args.output, filenames - - -def main(): - output_dir, filenames = parse_arguments() - - print(f"Output directory: {output_dir}") - print(f"Initial filenames: {filenames}") - print() - - if len(filenames) == 0: - print("error: at least one filename needed") - exit(1) - - data = [] - for filename in filenames: - data.extend(handle_file_or_glob(filename)) - - print(f"Total number of entries: {len(data)}") - print() - - compile_markdown(data) - tags = extract_tags(data) - files_written = render(data, tags, output_dir) - - print(f"Total files written: {files_written}") - - print() - print("Done.") - - -if __name__ == "__main__": - main() diff --git a/grimoiressg/__main__.py b/grimoiressg/__main__.py new file mode 100644 index 0000000..0b4004e --- /dev/null +++ b/grimoiressg/__main__.py @@ -0,0 +1,25 @@ +from grimoiressg.arguments import parse_arguments_to_initial_context +from grimoiressg.config import read_config +from grimoiressg.content_files import recursively_read_files +from grimoiressg.modules import available_modules + + +def apply_modules(data, config, context): + for module in config.get("enabled_modules", []): + print(f"Applying module {module}...") + available_modules[module](data, context) + print("") + + +def main(): + context = parse_arguments_to_initial_context() + config = read_config(context) + + data = recursively_read_files(context) + apply_modules(data, config, context) + + print("Done.") + + +if __name__ == "__main__": + main() diff --git a/grimoiressg/arguments.py b/grimoiressg/arguments.py new file mode 100644 index 0000000..22dd6b8 --- /dev/null +++ b/grimoiressg/arguments.py @@ -0,0 +1,31 @@ +import argparse + + +def parse_arguments_to_initial_context(): + parser = argparse.ArgumentParser( + description=''' + Grimoire is a minimalistic Static Site Generator. + In the simplest case the only argument needed is at least one content file. \ + The rest of the flags is used to customize the behavior. + ''' + ) + parser.add_argument("content_file", nargs='+', help="one or more content files") + parser.add_argument("-o", "--output", default="./output/", help="the output directory (default: ./output/)") + parser.add_argument("-c", "--config", help="the config file to use") + + args, _ = parser.parse_known_args() + + context = { + "output_dir": args.output, + "config_file": args.config, + "filenames": args.content_file + } + + print(f"Output directory: {context['output_dir']}") + print(f"Config file: {context['config_file']}") + print("Content files:") + for filename in context["filenames"]: + print(f" - {filename}") + print() + + return context diff --git a/grimoiressg/config.py b/grimoiressg/config.py new file mode 100644 index 0000000..ada4269 --- /dev/null +++ b/grimoiressg/config.py @@ -0,0 +1,35 @@ +import yaml +from yaml import Loader + +from grimoiressg.modules import available_modules + + +def default_config(): + return { + "enabled_modules": [ + "tags", + "markdown", + "templating" + ] + } + + +def read_config(context): + config_file = context.get("config_file", None) + + if not config_file: + print("No config file given; using default config") + config = default_config() + else: + with open(config_file, "r") as file: + config = yaml.load(file, Loader) or {} + + print("Enabled modules:") + for module in config.get("enabled_modules", []): + print(f" - {module}") + if module not in available_modules: + print(f" ERROR: Module does not exist") + exit(1) + print() + + return config diff --git a/grimoiressg/content_files.py b/grimoiressg/content_files.py new file mode 100644 index 0000000..0c3f299 --- /dev/null +++ b/grimoiressg/content_files.py @@ -0,0 +1,39 @@ +import os + +import yaml +from yaml import Loader + +from grimoiressg.utils.files import for_each_glob, to_relative + + +def handle_file(filename): + print(f" Reading {to_relative(filename)}...") + + with open(filename, "r") as file: + data = yaml.load(file, Loader) + + data["filename"] = filename + data["relative_filename"] = to_relative(filename) + results = [data] + + relative_dir = os.path.dirname(filename) + for filename in data.get("include", []): + filename = relative_dir + "/" + filename + sub_data = for_each_glob(filename, handle_file) + results.extend(sub_data) + + return results + + +def recursively_read_files(context): + data = [] + + print("Reading content files...") + + for filename in context["filenames"]: + data.extend(for_each_glob(filename, handle_file)) + + print(f"Read {len(data)} files in total.") + print() + + return data diff --git a/grimoiressg/modules/__init__.py b/grimoiressg/modules/__init__.py new file mode 100644 index 0000000..1240793 --- /dev/null +++ b/grimoiressg/modules/__init__.py @@ -0,0 +1,9 @@ +from grimoiressg.modules.markdown import compile_markdown +from grimoiressg.modules.tags import extract_tags +from grimoiressg.modules.templating import render_templates + +available_modules = { + "tags": extract_tags, + "markdown": compile_markdown, + "templating": render_templates +} diff --git a/grimoiressg/modules/markdown.py b/grimoiressg/modules/markdown.py new file mode 100644 index 0000000..8bbfca4 --- /dev/null +++ b/grimoiressg/modules/markdown.py @@ -0,0 +1,8 @@ +import markdown + + +def compile_markdown(data, context): + for entry in data: + if "markdown" in entry: + print(f"Compiling markdown for {entry['relative_filename']}...") + entry["markdown_compiled"] = markdown.markdown(entry["markdown"]) diff --git a/grimoiressg/modules/tags.py b/grimoiressg/modules/tags.py new file mode 100644 index 0000000..053f88c --- /dev/null +++ b/grimoiressg/modules/tags.py @@ -0,0 +1,18 @@ + +def extract_tags(data, context): + tags = {} + + for entry in data: + for tag in entry.get("tags", []): + entry_list = tags.get(tag, []) + entry_list.append(entry) + tags[tag] = entry_list + + if tags: + print("Found tags:") + for tag in tags.keys(): + print(f" - {tag} ({len(tags[tag])} files)") + else: + print("No tags found.") + + context["tags"] = tags \ No newline at end of file diff --git a/grimoiressg/modules/templating.py b/grimoiressg/modules/templating.py new file mode 100644 index 0000000..f7c875b --- /dev/null +++ b/grimoiressg/modules/templating.py @@ -0,0 +1,36 @@ +import os + +from grimoiressg.utils import to_relative + +from jinja2 import Environment, FileSystemLoader + +jinja_env = Environment( + loader=FileSystemLoader("/") +) + + +def render_templates(data, context): + files_written = 0 + + for entry in data: + if "template" in entry: + template_path = os.path.realpath(os.path.dirname(entry["filename"]) + "/" + entry["template"]) + template_dir = os.path.dirname(template_path) + print(f"Rendering template for {entry['relative_filename']}...") + template = jinja_env.get_template(template_path) + entry["rendered"] = template.render( + **context, + current=entry, + all=data, + template_dir=template_dir + ) + + if "rendered" in entry and "output" in entry: + files_written += 1 + filename = os.path.realpath(context["output_dir"] + "/" + entry["output"]) + print(f" writing to {to_relative(filename)}") + os.makedirs(os.path.dirname(filename), exist_ok=True) + with open(filename, "w") as file: + file.write(entry["rendered"]) + + print(f"{files_written} rendered") diff --git a/grimoiressg/utils/__init__.py b/grimoiressg/utils/__init__.py new file mode 100644 index 0000000..8205bd0 --- /dev/null +++ b/grimoiressg/utils/__init__.py @@ -0,0 +1 @@ +from .files import to_relative diff --git a/grimoiressg/utils/files.py b/grimoiressg/utils/files.py new file mode 100644 index 0000000..c3ccf31 --- /dev/null +++ b/grimoiressg/utils/files.py @@ -0,0 +1,18 @@ +import glob +import os + + +def to_relative(path): + trimmed = path.removeprefix(os.getcwd()) + if trimmed != path: + trimmed = "." + trimmed + return trimmed + + +def for_each_glob(glob_path, callback): + results = [] + + for filename in glob.glob(os.path.realpath(glob_path)): + results.extend(callback(filename)) + + return results diff --git a/pyproject.toml b/pyproject.toml index 85bfcfe..a5a875b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [tool.poetry] name = "grimoire-ssg" packages = [ - { include = "grimoire-ssg" } + { include = "grimoiressg" } ] version = "0.1.0" description = "A minimalistic Static Site Generator" From 7ad0d3eb409b54cbb52a3ae7fd7491d3c5afe651 Mon Sep 17 00:00:00 2001 From: sigmasternchen Date: Tue, 7 Jan 2025 20:30:09 +0100 Subject: [PATCH 3/7] feat: Allow loading of external modules --- example/config.yml | 8 ++++++++ external_module_test/__init__.py | 8 ++++++++ grimoiressg/config.py | 8 +++++++- grimoiressg/modules/__init__.py | 4 ++++ 4 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 example/config.yml create mode 100644 external_module_test/__init__.py diff --git a/example/config.yml b/example/config.yml new file mode 100644 index 0000000..9a65a5b --- /dev/null +++ b/example/config.yml @@ -0,0 +1,8 @@ +load_modules: + - external_module_test + +enabled_modules: + - tags + - markdown + - templating + - test \ No newline at end of file diff --git a/external_module_test/__init__.py b/external_module_test/__init__.py new file mode 100644 index 0000000..39d0ccc --- /dev/null +++ b/external_module_test/__init__.py @@ -0,0 +1,8 @@ +from grimoiressg.modules import available_modules + + +def test(data, context): + print("This is test module.") + + +available_modules["test"] = test diff --git a/grimoiressg/config.py b/grimoiressg/config.py index ada4269..512fade 100644 --- a/grimoiressg/config.py +++ b/grimoiressg/config.py @@ -1,7 +1,7 @@ import yaml from yaml import Loader -from grimoiressg.modules import available_modules +from grimoiressg.modules import available_modules, load_external_module def default_config(): @@ -21,9 +21,15 @@ def read_config(context): print("No config file given; using default config") config = default_config() else: + print("Loading config file...") with open(config_file, "r") as file: config = yaml.load(file, Loader) or {} + for module in config.get("load_modules", []): + print(f" Loading external module {module}") + load_external_module(module) + print() + print("Enabled modules:") for module in config.get("enabled_modules", []): print(f" - {module}") diff --git a/grimoiressg/modules/__init__.py b/grimoiressg/modules/__init__.py index 1240793..133e55f 100644 --- a/grimoiressg/modules/__init__.py +++ b/grimoiressg/modules/__init__.py @@ -7,3 +7,7 @@ available_modules = { "markdown": compile_markdown, "templating": render_templates } + + +def load_external_module(module): + __import__(module) From 49ad983da07d5ad0d20c0245f78b8ab7a4ee3212 Mon Sep 17 00:00:00 2001 From: sigmasternchen Date: Tue, 7 Jan 2025 20:38:14 +0100 Subject: [PATCH 4/7] docs: Update README to include information about the plugin system --- README.md | 48 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 44 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index a564fb8..d6e8c44 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ for programming knowledge — simply modify YAML files to generate your site. - **Markdown Support**: Write content in Markdown, which is automatically converted to HTML. - **Tagging System**: Organize your content with tags for easy referencing in templates. - **File Inclusion**: Include other YAML files to create a modular content structure. +- **Plugin System**: Extend the functionality with modules that can be added at runtime. ## Getting Started @@ -26,7 +27,7 @@ To generate your static site, run the Grimoire command with your input YAML file You can specify an output directory using the `-o` or `--output` flag. ```bash -python -m grimoire-ssg -o output_directory one_or_more_input_files.yml +python -m grimoiressg -o output_directory one_or_more_input_files.yml ``` ### Alternative Installation @@ -43,7 +44,7 @@ poetry install You can then run the program directly using Poetry: ```bash -poetry run python -m grimoire-ssg -o output_directory one_or_more_input_files.yml +poetry run python -m grimoiressg -o output_directory one_or_more_input_files.yml ``` ### Example YAML File @@ -101,7 +102,11 @@ extends a layout and includes dynamic content:

My latest blog articles:

{% endblock %} @@ -126,7 +131,42 @@ Additionally, the following fields are defined: ### Output Structure -The output files will be generated in the specified output directory, with paths defined in the `output` attribute of your YAML files. +The output files will be generated in the specified output directory, with paths defined in the `output` +attribute of your YAML files. + +## Advanced Features + +### Custom Plugins + +The program supports the addition of custom plugins at runtime. To utilize this, create a Python module +that modifies the list of available modules: + +```Python +from grimoiressg.modules import available_modules + + +def test(data, context): + print("This is test module.") + + +available_modules["test"] = test + +``` + +You then need a config file that loads, and enables this module. Please note that you need to specify +all `enabled_modules` to be used - not just the additional one. + +```yaml +load_modules: + - external_module_test + +enabled_modules: + - tags # built-in module for tagging + - markdown # built-in module for markdown support + - templating # built-in module for templating + - test # our custom module; the name is the + # key in the `available_modules` dict above +``` ## Contributing From d7ef7a122a9068d76316a773ae6c73182b9f7dba Mon Sep 17 00:00:00 2001 From: Sigma Date: Fri, 10 Jan 2025 18:28:01 +0100 Subject: [PATCH 5/7] fix: Change utils import to named import Co-authored-by: Ninaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa --- grimoiressg/utils/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grimoiressg/utils/__init__.py b/grimoiressg/utils/__init__.py index 8205bd0..96766ce 100644 --- a/grimoiressg/utils/__init__.py +++ b/grimoiressg/utils/__init__.py @@ -1 +1 @@ -from .files import to_relative +from .files import to_relative as to_relative From 201617312318966e3577c1a485383bd980a5d968 Mon Sep 17 00:00:00 2001 From: sigmasternchen Date: Fri, 10 Jan 2025 18:28:56 +0100 Subject: [PATCH 6/7] format: Change to consistent use of double-quotes --- grimoiressg/arguments.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grimoiressg/arguments.py b/grimoiressg/arguments.py index 22dd6b8..86d74b7 100644 --- a/grimoiressg/arguments.py +++ b/grimoiressg/arguments.py @@ -9,7 +9,7 @@ def parse_arguments_to_initial_context(): The rest of the flags is used to customize the behavior. ''' ) - parser.add_argument("content_file", nargs='+', help="one or more content files") + parser.add_argument("content_file", nargs="+", help="one or more content files") parser.add_argument("-o", "--output", default="./output/", help="the output directory (default: ./output/)") parser.add_argument("-c", "--config", help="the config file to use") From f3f2889e44179110c883af5967e8576f23600afd Mon Sep 17 00:00:00 2001 From: sigmasternchen Date: Fri, 10 Jan 2025 18:53:57 +0100 Subject: [PATCH 7/7] feat: Switch to Python logging --- README.md | 3 ++- external_module_test/__init__.py | 3 ++- grimoiressg/__main__.py | 9 ++++++--- grimoiressg/arguments.py | 11 ++++++----- grimoiressg/config.py | 18 ++++++++++-------- grimoiressg/content_files.py | 9 ++++----- grimoiressg/modules/markdown.py | 4 +++- grimoiressg/modules/tags.py | 8 +++++--- grimoiressg/modules/templating.py | 10 +++++----- grimoiressg/utils/__init__.py | 3 ++- grimoiressg/utils/logger.py | 5 +++++ 11 files changed, 50 insertions(+), 33 deletions(-) create mode 100644 grimoiressg/utils/logger.py diff --git a/README.md b/README.md index d6e8c44..ed9eb2e 100644 --- a/README.md +++ b/README.md @@ -143,10 +143,11 @@ that modifies the list of available modules: ```Python from grimoiressg.modules import available_modules +from grimoiressg.utils import logger def test(data, context): - print("This is test module.") + logger.info("This is test module.") available_modules["test"] = test diff --git a/external_module_test/__init__.py b/external_module_test/__init__.py index 39d0ccc..5a59c42 100644 --- a/external_module_test/__init__.py +++ b/external_module_test/__init__.py @@ -1,8 +1,9 @@ from grimoiressg.modules import available_modules +from grimoiressg.utils import logger def test(data, context): - print("This is test module.") + logger.info("This is test module.") available_modules["test"] = test diff --git a/grimoiressg/__main__.py b/grimoiressg/__main__.py index 0b4004e..b8b38cb 100644 --- a/grimoiressg/__main__.py +++ b/grimoiressg/__main__.py @@ -1,14 +1,16 @@ +import logging + from grimoiressg.arguments import parse_arguments_to_initial_context from grimoiressg.config import read_config from grimoiressg.content_files import recursively_read_files from grimoiressg.modules import available_modules +from grimoiressg.utils import logger def apply_modules(data, config, context): for module in config.get("enabled_modules", []): - print(f"Applying module {module}...") + logger.info("Applying module %s...", module) available_modules[module](data, context) - print("") def main(): @@ -18,7 +20,8 @@ def main(): data = recursively_read_files(context) apply_modules(data, config, context) - print("Done.") + logger.info("Done.") + logging.shutdown() if __name__ == "__main__": diff --git a/grimoiressg/arguments.py b/grimoiressg/arguments.py index 86d74b7..a062299 100644 --- a/grimoiressg/arguments.py +++ b/grimoiressg/arguments.py @@ -1,5 +1,7 @@ import argparse +from grimoiressg.utils import logger + def parse_arguments_to_initial_context(): parser = argparse.ArgumentParser( @@ -21,11 +23,10 @@ def parse_arguments_to_initial_context(): "filenames": args.content_file } - print(f"Output directory: {context['output_dir']}") - print(f"Config file: {context['config_file']}") - print("Content files:") + logger.debug("Output directory: %s", context['output_dir']) + logger.debug("Config file: %s", context['config_file']) + logger.debug("Content files:") for filename in context["filenames"]: - print(f" - {filename}") - print() + logger.debug(" - %s", filename) return context diff --git a/grimoiressg/config.py b/grimoiressg/config.py index 512fade..ce4ebe4 100644 --- a/grimoiressg/config.py +++ b/grimoiressg/config.py @@ -1,7 +1,10 @@ +import logging + import yaml from yaml import Loader from grimoiressg.modules import available_modules, load_external_module +from grimoiressg.utils import logger def default_config(): @@ -18,24 +21,23 @@ def read_config(context): config_file = context.get("config_file", None) if not config_file: - print("No config file given; using default config") + logger.info("No config file given; using default config") config = default_config() else: - print("Loading config file...") + logger.info("Loading config file...") with open(config_file, "r") as file: config = yaml.load(file, Loader) or {} for module in config.get("load_modules", []): - print(f" Loading external module {module}") + logger.debug(" Loading external module %s", module) load_external_module(module) - print() - print("Enabled modules:") + logger.debug("Enabled modules:") for module in config.get("enabled_modules", []): - print(f" - {module}") + logger.debug(" - %s", module) if module not in available_modules: - print(f" ERROR: Module does not exist") + logger.critical("Module does not exist: %s", module) + logging.shutdown() exit(1) - print() return config diff --git a/grimoiressg/content_files.py b/grimoiressg/content_files.py index 0c3f299..854d6af 100644 --- a/grimoiressg/content_files.py +++ b/grimoiressg/content_files.py @@ -3,11 +3,11 @@ import os import yaml from yaml import Loader -from grimoiressg.utils.files import for_each_glob, to_relative +from grimoiressg.utils import logger, for_each_glob, to_relative def handle_file(filename): - print(f" Reading {to_relative(filename)}...") + logger.debug(" Reading %s...", to_relative(filename)) with open(filename, "r") as file: data = yaml.load(file, Loader) @@ -28,12 +28,11 @@ def handle_file(filename): def recursively_read_files(context): data = [] - print("Reading content files...") + logger.info("Reading content files...") for filename in context["filenames"]: data.extend(for_each_glob(filename, handle_file)) - print(f"Read {len(data)} files in total.") - print() + logger.info(f"Read %d files in total.", len(data)) return data diff --git a/grimoiressg/modules/markdown.py b/grimoiressg/modules/markdown.py index 8bbfca4..2202277 100644 --- a/grimoiressg/modules/markdown.py +++ b/grimoiressg/modules/markdown.py @@ -1,8 +1,10 @@ import markdown +from grimoiressg.utils import logger + def compile_markdown(data, context): for entry in data: if "markdown" in entry: - print(f"Compiling markdown for {entry['relative_filename']}...") + logger.debug("Compiling markdown for %s...", entry['relative_filename']) entry["markdown_compiled"] = markdown.markdown(entry["markdown"]) diff --git a/grimoiressg/modules/tags.py b/grimoiressg/modules/tags.py index 053f88c..1d63cf7 100644 --- a/grimoiressg/modules/tags.py +++ b/grimoiressg/modules/tags.py @@ -1,3 +1,5 @@ +from grimoiressg.utils import logger + def extract_tags(data, context): tags = {} @@ -9,10 +11,10 @@ def extract_tags(data, context): tags[tag] = entry_list if tags: - print("Found tags:") + logger.debug("Found tags:") for tag in tags.keys(): - print(f" - {tag} ({len(tags[tag])} files)") + logger.debug(" - %s (%d files)", tag, len(tags[tag])) else: - print("No tags found.") + logger.debug("No tags found.") context["tags"] = tags \ No newline at end of file diff --git a/grimoiressg/modules/templating.py b/grimoiressg/modules/templating.py index f7c875b..ef2e307 100644 --- a/grimoiressg/modules/templating.py +++ b/grimoiressg/modules/templating.py @@ -1,9 +1,9 @@ import os -from grimoiressg.utils import to_relative - from jinja2 import Environment, FileSystemLoader +from grimoiressg.utils import to_relative, logger + jinja_env = Environment( loader=FileSystemLoader("/") ) @@ -16,7 +16,7 @@ def render_templates(data, context): if "template" in entry: template_path = os.path.realpath(os.path.dirname(entry["filename"]) + "/" + entry["template"]) template_dir = os.path.dirname(template_path) - print(f"Rendering template for {entry['relative_filename']}...") + logger.debug("Rendering template for %s...", entry['relative_filename']) template = jinja_env.get_template(template_path) entry["rendered"] = template.render( **context, @@ -28,9 +28,9 @@ def render_templates(data, context): if "rendered" in entry and "output" in entry: files_written += 1 filename = os.path.realpath(context["output_dir"] + "/" + entry["output"]) - print(f" writing to {to_relative(filename)}") + logger.debug(" writing to %s", to_relative(filename)) os.makedirs(os.path.dirname(filename), exist_ok=True) with open(filename, "w") as file: file.write(entry["rendered"]) - print(f"{files_written} rendered") + logger.debug("%d rendered", files_written) diff --git a/grimoiressg/utils/__init__.py b/grimoiressg/utils/__init__.py index 96766ce..c90e260 100644 --- a/grimoiressg/utils/__init__.py +++ b/grimoiressg/utils/__init__.py @@ -1 +1,2 @@ -from .files import to_relative as to_relative +from .files import to_relative as to_relative, for_each_glob as for_each_glob +from .logger import logger as logger diff --git a/grimoiressg/utils/logger.py b/grimoiressg/utils/logger.py new file mode 100644 index 0000000..cae4f43 --- /dev/null +++ b/grimoiressg/utils/logger.py @@ -0,0 +1,5 @@ +import logging +import sys + +logging.basicConfig(stream=sys.stdout, level=logging.INFO, format="%(asctime)s %(levelname)-9s: %(message)s") +logger = logging.getLogger("grimoire")