Skip to content

Commit 3fceb45

Browse files
authored
Refacto: modernize config date from meta (#285)
2 parents 3b8337e + a5db57f commit 3fceb45

File tree

7 files changed

+107
-78
lines changed

7 files changed

+107
-78
lines changed

mkdocs.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ markdown_extensions:
3939
pygments_lang_class: true
4040
- pymdownx.inlinehilite
4141
- pymdownx.snippets:
42-
base_path: "."
42+
base_path:
43+
- "."
4344
check_paths: true
4445
- pymdownx.superfences
4546
- pymdownx.tabbed:
@@ -105,7 +106,6 @@ plugins:
105106
abstract_delimiter: <!-- more -->
106107
date_from_meta:
107108
as_creation: "date"
108-
as_update: false
109109
datetime_format: "%Y-%m-%d %H:%M"
110110
default_timezone: "Europe/Paris"
111111
default_time: "22:00"

mkdocs_rss_plugin/config.py

+14-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
# ########## Libraries #############
55
# ##################################
66

7+
# standard
8+
from datetime import datetime
9+
from typing import Union
710

811
# 3rd party
912
from mkdocs.config import config_options
@@ -14,6 +17,16 @@
1417
# ##################################
1518

1619

20+
class _DateFromMeta(Config):
21+
# TODO: remove deprecated code in future version. Only str values will be accepted
22+
# for as_creation and as_update
23+
as_creation = config_options.Type(Union[bool, str], default="git")
24+
as_update = config_options.Type(Union[bool, str], default="git")
25+
datetime_format = config_options.Type(str, default="%Y-%m-%d %H:%M")
26+
default_time = config_options.Type(str, default=datetime.min.strftime("%H:%M"))
27+
default_timezone = config_options.Type(str, default="UTC")
28+
29+
1730
class _FeedsFilenamesConfig(Config):
1831
json_created = config_options.Type(str, default="feed_json_created.json")
1932
json_updated = config_options.Type(str, default="feed_json_updated.json")
@@ -30,7 +43,7 @@ class RssPluginConfig(Config):
3043
config_options.ListOfItems(config_options.Type(str))
3144
)
3245
comments_path = config_options.Optional(config_options.Type(str))
33-
date_from_meta = config_options.Optional(config_options.Type(dict))
46+
date_from_meta = config_options.SubConfig(_DateFromMeta)
3447
enabled = config_options.Type(bool, default=True)
3548
feed_ttl = config_options.Type(int, default=1440)
3649
feeds_filenames = config_options.SubConfig(_FeedsFilenamesConfig)

mkdocs_rss_plugin/plugin.py

+76-70
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,15 @@
1010
from datetime import datetime
1111
from email.utils import formatdate
1212
from pathlib import Path
13-
from re import compile
13+
from re import compile as re_compile
1414

1515
# 3rd party
1616
from jinja2 import Environment, FileSystemLoader, select_autoescape
1717
from mkdocs.config import config_options
18+
from mkdocs.config.defaults import MkDocsConfig
1819
from mkdocs.exceptions import PluginError
1920
from mkdocs.plugins import BasePlugin, event_priority, get_plugin_logger
21+
from mkdocs.structure.files import Files
2022
from mkdocs.structure.pages import Page
2123
from mkdocs.utils import get_build_timestamp
2224

@@ -55,30 +57,28 @@ class GitRssPlugin(BasePlugin[RssPluginConfig]):
5557

5658
def __init__(self):
5759
"""Instanciation."""
58-
# dates source
59-
self.src_date_created = self.src_date_updated = "git"
60-
self.meta_datetime_format: str | None = None
61-
self.meta_default_timezone: str = "UTC"
62-
self.meta_default_time: datetime.time | None = None
6360
# pages storage
6461
self.pages_to_filter: list = []
6562
# prepare output feeds
6663
self.feed_created: dict = {}
6764
self.feed_updated: dict = {}
6865

69-
def on_config(self, config: config_options.Config) -> dict:
66+
def on_config(self, config: MkDocsConfig) -> MkDocsConfig:
7067
"""The config event is the first event called on build and
7168
is run immediately after the user configuration is loaded and validated.
7269
Any alterations to the config should be made here.
73-
https://www.mkdocs.org/user-guide/plugins/#on_config
7470
75-
:param config: global configuration object
76-
:type config: config_options.Config
71+
See: https://www.mkdocs.org/user-guide/plugins/#on_config
7772
78-
:raises FileExistsError: if the template for the RSS feed is not found
73+
Args:
74+
config (config_options.Config): global configuration object
7975
80-
:return: plugin configuration object
81-
:rtype: dict
76+
Raises:
77+
FileExistsError: if the template for the RSS feed is not found
78+
PluginError: if the 'date_from_meta.default_time' format does not comply
79+
80+
Returns:
81+
MkDocsConfig: global configuration object
8282
"""
8383
# Skip if disabled
8484
if not self.config.enabled:
@@ -131,48 +131,56 @@ def on_config(self, config: config_options.Config) -> dict:
131131
base_feed["logo_url"] = self.config.image
132132

133133
# pattern to match pages included in output
134-
self.match_path_pattern = compile(self.config.match_path)
134+
self.match_path_pattern = re_compile(self.config.match_path)
135135

136136
# date handling
137-
if self.config.date_from_meta is not None:
138-
self.src_date_created = self.config.date_from_meta.get("as_creation", False)
139-
self.src_date_updated = self.config.date_from_meta.get("as_update", False)
140-
self.meta_datetime_format = self.config.date_from_meta.get(
141-
"datetime_format", "%Y-%m-%d %H:%M"
137+
if (
138+
self.config.date_from_meta.as_creation == "git"
139+
and self.config.date_from_meta.as_update == "git"
140+
):
141+
logger.debug("Dates will be retrieved from git log.")
142+
elif any(
143+
[
144+
isinstance(self.config.date_from_meta.as_creation, bool),
145+
isinstance(self.config.date_from_meta.as_update, bool),
146+
]
147+
):
148+
deprecation_msg = (
149+
"Since version 1.13, using a boolean for "
150+
"'date_from_meta.as_creation' and 'date_from_meta.as_update' is "
151+
"deprecated. Please update your "
152+
"`rss` plugin settings in your Mkdocs configuration "
153+
f"({config.config_file_path}) by using a str or removing the value if "
154+
"you were using `False`., "
142155
)
143-
self.meta_default_timezone = self.config.date_from_meta.get(
144-
"default_timezone", "UTC"
156+
logger.warning(DeprecationWarning(deprecation_msg))
157+
self.config.date_from_meta.as_creation = (
158+
self.config.date_from_meta.as_update
159+
) = "git"
160+
161+
# check if default time complies with expected format
162+
try:
163+
self.config.date_from_meta.default_time = datetime.strptime(
164+
self.config.date_from_meta.default_time, "%H:%M"
145165
)
146-
self.meta_default_time = self.config.date_from_meta.get(
147-
"default_time", None
166+
except ValueError as err:
167+
raise PluginError(
168+
"Config error: `date_from_meta.default_time` value "
169+
f"'{self.config.date_from_meta.default_time}' format doesn't match the "
170+
f"expected format %H:%M. Trace: {err}"
148171
)
149-
if self.meta_default_time:
150-
try:
151-
self.meta_default_time = datetime.strptime(
152-
self.meta_default_time, "%H:%M"
153-
)
154-
except ValueError as err:
155-
raise PluginError(
156-
"Config error: `date_from_meta.default_time` value "
157-
f"'{self.meta_default_time}' format doesn't match the expected "
158-
f"format %H:%M. Trace: {err}"
159-
)
160-
else:
161-
self.meta_default_time = datetime.min
162172

163-
if self.config.use_git:
164-
logger.debug(
165-
"Dates will be retrieved FIRSTLY from page meta (yaml "
166-
"frontmatter). The git log will be used as fallback."
167-
)
168-
else:
169-
logger.debug(
170-
"Dates will be retrieved ONLY from page meta (yaml "
171-
"frontmatter). The build date will be used as fallback, without any "
172-
"call to Git."
173-
)
173+
if self.config.use_git:
174+
logger.debug(
175+
"Dates will be retrieved FIRSTLY from page meta (yaml "
176+
"frontmatter). The git log will be used as fallback."
177+
)
174178
else:
175-
logger.debug("Dates will be retrieved from git log.")
179+
logger.debug(
180+
"Dates will be retrieved ONLY from page meta (yaml "
181+
"frontmatter). The build date will be used as fallback, without any "
182+
"call to Git."
183+
)
176184

177185
# create 2 final dicts
178186
self.feed_created = deepcopy(base_feed)
@@ -199,34 +207,32 @@ def on_config(self, config: config_options.Config) -> dict:
199207
"configuration file whereas a URL is mandatory to publish. "
200208
"See: https://validator.w3.org/feed/docs/rss2.html#requiredChannelElements"
201209
)
202-
self.feed_created["rss_url"] = self.feed_updated["rss_url"] = None
210+
self.feed_created["rss_url"] = self.feed_updated["json_url"] = (
211+
self.feed_updated["rss_url"]
212+
) = self.feed_updated["json_url"] = None
203213

204214
# ending event
205215
return config
206216

207217
@event_priority(priority=-75)
208218
def on_page_content(
209-
self, html: str, page: Page, config: config_options.Config, files
219+
self, html: str, page: Page, config: MkDocsConfig, files: Files
210220
) -> str | None:
211-
"""The page_content event is called after the Markdown text is rendered
212-
to HTML (but before being passed to a template) and can be used to alter
213-
the HTML body of the page.
221+
"""The page_content event is called after the Markdown text is rendered to HTML
222+
(but before being passed to a template) and can be used to alter the HTML
223+
body of the page.
214224
215-
https://www.mkdocs.org/user-guide/plugins/#on_page_content
225+
See: https://www.mkdocs.org/user-guide/plugins/#on_page_content
216226
217-
:param html: HTML rendered from Markdown source as string
218-
:type html: str
219-
:param page: mkdocs.nav.Page instance
220-
:type page: Page
221-
:param config: global configuration object
222-
:type config: config_options.Config
223-
:param files: global navigation object
224-
:type files: [type]
227+
Args:
228+
html (str): HTML rendered from Markdown source as string
229+
page (Page): `mkdocs.structure.pages.Page` instance
230+
config (MkDocsConfig): global configuration object
231+
files (Files): global files collection
225232
226-
:return: HTML rendered from Markdown source as string
227-
:rtype: str
233+
Returns:
234+
Optional[str]: HTML rendered from Markdown source as string
228235
"""
229-
230236
# Skip if disabled
231237
if not self.config.enabled:
232238
return
@@ -243,11 +249,11 @@ def on_page_content(
243249
# retrieve dates from git log
244250
page_dates = self.util.get_file_dates(
245251
in_page=page,
246-
source_date_creation=self.src_date_created,
247-
source_date_update=self.src_date_updated,
248-
meta_datetime_format=self.meta_datetime_format,
249-
meta_default_timezone=self.meta_default_timezone,
250-
meta_default_time=self.meta_default_time,
252+
source_date_creation=self.config.date_from_meta.as_creation,
253+
source_date_update=self.config.date_from_meta.as_update,
254+
meta_datetime_format=self.config.date_from_meta.datetime_format,
255+
meta_default_timezone=self.config.date_from_meta.default_timezone,
256+
meta_default_time=self.config.date_from_meta.default_time,
251257
)
252258

253259
# handle custom URL parameters

tests/fixtures/mkdocs_complete.yml

-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ plugins:
1919
comments_path: "#__comments"
2020
date_from_meta:
2121
as_creation: "date"
22-
as_update: false
2322
datetime_format: "%Y-%m-%d %H:%M"
2423
default_timezone: Europe/Paris
2524
default_time: "09:30"

tests/fixtures/mkdocs_complete_no_git.yml

-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ plugins:
1919
comments_path: "#__comments"
2020
date_from_meta:
2121
as_creation: "date"
22-
as_update: false
2322
datetime_format: "%Y-%m-%d %H:%M"
2423
default_timezone: Europe/Paris
2524
default_time: "09:30"

tests/fixtures/mkdocs_simple.yml

-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ plugins:
1717
- rss:
1818
date_from_meta:
1919
as_creation: "date"
20-
as_update: false
2120
datetime_format: "%Y-%m-%d %H:%M"
2221
default_timezone: "Europe/Paris"
2322
default_time: "22:00"

tests/test_config.py

+15-2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
# Standard library
1717
import unittest
18+
from datetime import datetime
1819
from pathlib import Path
1920

2021
# 3rd party
@@ -62,7 +63,13 @@ def test_plugin_config_defaults(self):
6263
"abstract_delimiter": "<!-- more -->",
6364
"categories": None,
6465
"comments_path": None,
65-
"date_from_meta": None,
66+
"date_from_meta": {
67+
"as_creation": "git",
68+
"as_update": "git",
69+
"datetime_format": "%Y-%m-%d %H:%M",
70+
"default_time": datetime.min.strftime("%H:%M"),
71+
"default_timezone": "UTC",
72+
},
6673
"enabled": True,
6774
"feed_ttl": 1440,
6875
"image": None,
@@ -98,7 +105,13 @@ def test_plugin_config_image(self):
98105
"abstract_delimiter": "<!-- more -->",
99106
"categories": None,
100107
"comments_path": None,
101-
"date_from_meta": None,
108+
"date_from_meta": {
109+
"as_creation": "git",
110+
"as_update": "git",
111+
"datetime_format": "%Y-%m-%d %H:%M",
112+
"default_time": datetime.min.strftime("%H:%M"),
113+
"default_timezone": "UTC",
114+
},
102115
"enabled": True,
103116
"feed_ttl": 1440,
104117
"image": self.feed_image,

0 commit comments

Comments
 (0)