blurry-cli 0.10.0__tar.gz → 0.12.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. {blurry_cli-0.10.0 → blurry_cli-0.12.0}/PKG-INFO +2 -2
  2. {blurry_cli-0.10.0 → blurry_cli-0.12.0}/blurry/__init__.py +61 -10
  3. {blurry_cli-0.10.0 → blurry_cli-0.12.0}/blurry/templates.py +6 -5
  4. {blurry_cli-0.10.0 → blurry_cli-0.12.0}/pyproject.toml +2 -2
  5. {blurry_cli-0.10.0 → blurry_cli-0.12.0}/LICENSE +0 -0
  6. {blurry_cli-0.10.0 → blurry_cli-0.12.0}/README.md +0 -0
  7. {blurry_cli-0.10.0 → blurry_cli-0.12.0}/blurry/__main__.py +0 -0
  8. {blurry_cli-0.10.0 → blurry_cli-0.12.0}/blurry/async_typer.py +0 -0
  9. {blurry_cli-0.10.0 → blurry_cli-0.12.0}/blurry/cli.py +0 -0
  10. {blurry_cli-0.10.0 → blurry_cli-0.12.0}/blurry/constants.py +0 -0
  11. {blurry_cli-0.10.0 → blurry_cli-0.12.0}/blurry/images.py +0 -0
  12. {blurry_cli-0.10.0 → blurry_cli-0.12.0}/blurry/markdown/__init__.py +0 -0
  13. {blurry_cli-0.10.0 → blurry_cli-0.12.0}/blurry/markdown/front_matter.py +0 -0
  14. {blurry_cli-0.10.0 → blurry_cli-0.12.0}/blurry/markdown/renderer_functions/__init__.py +0 -0
  15. {blurry_cli-0.10.0 → blurry_cli-0.12.0}/blurry/markdown/renderer_functions/render_video.py +0 -0
  16. {blurry_cli-0.10.0 → blurry_cli-0.12.0}/blurry/open_graph.py +0 -0
  17. {blurry_cli-0.10.0 → blurry_cli-0.12.0}/blurry/plugins/__init__.py +0 -0
  18. {blurry_cli-0.10.0 → blurry_cli-0.12.0}/blurry/plugins/html_plugins/__init__.py +0 -0
  19. {blurry_cli-0.10.0 → blurry_cli-0.12.0}/blurry/plugins/html_plugins/minify_html_plugin.py +0 -0
  20. {blurry_cli-0.10.0 → blurry_cli-0.12.0}/blurry/plugins/jinja_plugins/__init__.py +0 -0
  21. {blurry_cli-0.10.0 → blurry_cli-0.12.0}/blurry/plugins/jinja_plugins/blurry_image_extension.py +0 -0
  22. {blurry_cli-0.10.0 → blurry_cli-0.12.0}/blurry/plugins/markdown_plugins/__init__.py +0 -0
  23. {blurry_cli-0.10.0 → blurry_cli-0.12.0}/blurry/plugins/markdown_plugins/container_plugin.py +0 -0
  24. {blurry_cli-0.10.0 → blurry_cli-0.12.0}/blurry/plugins/markdown_plugins/punctuation_plugin.py +0 -0
  25. {blurry_cli-0.10.0 → blurry_cli-0.12.0}/blurry/plugins/markdown_plugins/python_code_plugin.py +0 -0
  26. {blurry_cli-0.10.0 → blurry_cli-0.12.0}/blurry/py.typed +0 -0
  27. {blurry_cli-0.10.0 → blurry_cli-0.12.0}/blurry/schema_validation.py +0 -0
  28. {blurry_cli-0.10.0 → blurry_cli-0.12.0}/blurry/settings.py +0 -0
  29. {blurry_cli-0.10.0 → blurry_cli-0.12.0}/blurry/sitemap.py +0 -0
  30. {blurry_cli-0.10.0 → blurry_cli-0.12.0}/blurry/types.py +0 -0
  31. {blurry_cli-0.10.0 → blurry_cli-0.12.0}/blurry/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: blurry-cli
3
- Version: 0.10.0
3
+ Version: 0.12.0
4
4
  Summary: A Mistune-based static site generator for Python
5
5
  Home-page: https://github.com/blurry-dev/blurry
6
6
  License: MIT
@@ -33,7 +33,7 @@ Requires-Dist: livereload (>=2.7.0,<3.0.0)
33
33
  Requires-Dist: mistune (>=3.0.2,<4.0.0)
34
34
  Requires-Dist: pydantic2-schemaorg (>=0.2.0,<0.3.0)
35
35
  Requires-Dist: rich (>=13.3.3,<14.0.0)
36
- Requires-Dist: selectolax (>=0.3.6,<0.4.0)
36
+ Requires-Dist: selectolax (>=0.3.27,<0.4.0)
37
37
  Requires-Dist: toml (>=0.10.2,<0.11.0)
38
38
  Requires-Dist: typer (>=0.6.1,<0.7.0)
39
39
  Project-URL: Repository, https://github.com/blurry-dev/blurry
@@ -1,9 +1,12 @@
1
1
  import asyncio
2
2
  import dataclasses
3
+ import importlib
3
4
  import json
4
5
  import mimetypes
5
6
  import os
7
+ import pkgutil
6
8
  import shutil
9
+ import sys
7
10
  from collections.abc import Coroutine
8
11
  from copy import deepcopy
9
12
  from datetime import datetime
@@ -51,7 +54,7 @@ warning_console = Console(stderr=True, style="bold yellow")
51
54
  app = AsyncTyper()
52
55
 
53
56
 
54
- async def process_non_markdown_file(filepath: Path):
57
+ async def process_non_markdown_file(filepath: Path, file_data_by_directory):
55
58
  CONTENT_DIR = get_content_directory()
56
59
  mimetype, _ = mimetypes.guess_type(filepath, strict=False)
57
60
  relative_filepath = filepath.relative_to(CONTENT_DIR)
@@ -59,6 +62,13 @@ async def process_non_markdown_file(filepath: Path):
59
62
  output_file = Path(build_filepath)
60
63
  output_file.parent.mkdir(exist_ok=True, parents=True)
61
64
 
65
+ # Process Jinja files
66
+ if ".jinja" in filepath.suffixes:
67
+ # Process file
68
+ jinja_env = get_jinja_env()
69
+ process_jinja_file(filepath, jinja_env, file_data_by_directory)
70
+ return
71
+
62
72
  # Copy file to build directory
63
73
  shutil.copyfile(filepath, build_filepath)
64
74
 
@@ -70,6 +80,27 @@ async def process_non_markdown_file(filepath: Path):
70
80
  await generate_images_for_srcset(filepath)
71
81
 
72
82
 
83
+ def process_jinja_file(filepath: Path, jinja_env: Environment, file_data_by_directory):
84
+ build_directory = get_build_directory()
85
+ content_directory = get_content_directory()
86
+ template = jinja_env.get_template(str(filepath.relative_to(content_directory)))
87
+ context = {
88
+ "file_data_by_directory": {
89
+ str(path): data for path, data in deepcopy(file_data_by_directory).items()
90
+ },
91
+ "settings": deepcopy(SETTINGS),
92
+ "datetime": datetime,
93
+ }
94
+ filepath_with_new_extension = filepath.with_suffix(
95
+ filepath.suffix.replace(".jinja", "")
96
+ )
97
+ filepath_in_build = build_directory / filepath_with_new_extension.relative_to(
98
+ content_directory
99
+ )
100
+ html = template.render(dataclasses=dataclasses, **context)
101
+ filepath_in_build.write_text(html)
102
+
103
+
73
104
  async def write_html_file(
74
105
  file_data: MarkdownFileData,
75
106
  file_data_list: list[MarkdownFileData],
@@ -172,14 +203,8 @@ async def build(release=True):
172
203
  markdown_tasks: list[Coroutine] = []
173
204
  non_markdown_tasks: list[Coroutine] = []
174
205
 
175
- for filepath in path.glob("**/*.*"):
176
- # Handle images and other files
177
- if filepath.suffix != ".md":
178
- non_markdown_tasks.append(process_non_markdown_file(filepath))
179
- continue
180
-
181
- # Handle Markdown files
182
-
206
+ # Gather metadata from Markdown files
207
+ for filepath in path.glob("**/*.md"):
183
208
  # Extract filepath for storing context data and writing out
184
209
  relative_filepath = filepath.relative_to(CONTENT_DIR)
185
210
  directory = relative_filepath.parent
@@ -195,11 +220,19 @@ async def build(release=True):
195
220
  )
196
221
  file_data_by_directory[directory].append(file_data)
197
222
 
198
- non_markdown_tasks.append(write_sitemap_file(file_data_by_directory))
223
+ # Handle images and other files
224
+ for filepath in path.glob("**/*"):
225
+ if filepath.suffix == ".md" or filepath.is_dir():
226
+ continue
227
+ non_markdown_tasks.append(
228
+ process_non_markdown_file(filepath, file_data_by_directory)
229
+ )
199
230
 
200
231
  # Sort file data by publishedDate/createdDate, descending, if present
201
232
  file_data_by_directory = sort_directory_file_data_by_date(file_data_by_directory)
202
233
 
234
+ non_markdown_tasks.append(write_sitemap_file(file_data_by_directory))
235
+
203
236
  for file_data_list in file_data_by_directory.values():
204
237
  for file_data in file_data_list:
205
238
  markdown_tasks.append(
@@ -231,6 +264,20 @@ async def build_development():
231
264
  await build(release=False)
232
265
 
233
266
 
267
+ async def reload_local_plugins_and_build():
268
+ """Reloads a project's local modules and performs a dev build"""
269
+ cwd = str(Path.cwd())
270
+
271
+ for _, package_name, _ in pkgutil.iter_modules([cwd]):
272
+ try:
273
+ module = sys.modules[package_name]
274
+ except KeyError:
275
+ continue
276
+ importlib.reload(module)
277
+
278
+ await build_development()
279
+
280
+
234
281
  @app.command()
235
282
  def runserver():
236
283
  """Starts HTTP server with live reloading."""
@@ -251,6 +298,10 @@ def runserver():
251
298
  f"{SETTINGS['TEMPLATES_DIRECTORY_NAME']}/**/*",
252
299
  lambda: event_loop.create_task(build_development()),
253
300
  )
301
+ livereload_server.watch(
302
+ "./**/*.py",
303
+ lambda: event_loop.create_task(reload_local_plugins_and_build()),
304
+ )
254
305
  livereload_server.watch(
255
306
  "blurry.toml", lambda: event_loop.create_task(build_development())
256
307
  )
@@ -5,6 +5,7 @@ from jinja2 import select_autoescape
5
5
 
6
6
  from blurry.plugins import discovered_jinja_extensions
7
7
  from blurry.plugins import discovered_jinja_filter_plugins
8
+ from blurry.settings import get_content_directory
8
9
  from blurry.settings import get_templates_directory
9
10
  from blurry.settings import SETTINGS
10
11
 
@@ -14,16 +15,16 @@ def get_jinja_env() -> Environment:
14
15
  Returns a Jinja environment complete with JinjaX and any installed Jinja extensions and filters.
15
16
  """
16
17
  templates_directory = get_templates_directory()
18
+ content_directory = get_content_directory()
17
19
  jinja_env = Environment(
18
- loader=FileSystemLoader(templates_directory),
20
+ loader=FileSystemLoader([content_directory, templates_directory]),
19
21
  autoescape=select_autoescape(
20
- list(
22
+ enabled_extensions=list(
21
23
  {
22
24
  SETTINGS["MARKDOWN_FILE_JINJA_TEMPLATE_EXTENSION"].lstrip("."),
23
- "html",
24
- "xml",
25
+ "jinja",
25
26
  }
26
- )
27
+ ),
27
28
  ),
28
29
  extensions=[
29
30
  jinja_extension.load() for jinja_extension in discovered_jinja_extensions
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "blurry-cli"
3
- version = "0.10.0"
3
+ version = "0.12.0"
4
4
  description = "A Mistune-based static site generator for Python"
5
5
  authors = ["John Franey <franey@duck.com>"]
6
6
  license = "MIT"
@@ -32,7 +32,7 @@ livereload = "^2.7.0"
32
32
  mistune = "^3.0.2"
33
33
  python = "^3.10"
34
34
  rich = "^13.3.3"
35
- selectolax = "^0.3.6"
35
+ selectolax = "^0.3.27"
36
36
  toml = "^0.10.2"
37
37
  typer = "^0.6.1"
38
38
  htmlmin2 = "^0.1.13"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes