Skip to content

Commit

Permalink
fix: Type error with YAML dates in frontmatter
Browse files Browse the repository at this point in the history
When valid YAML dates or times are added to the page frontmatter, the
YAML parser will already convert them to datetime.date or
datetime.datetime objects.

Example:

    ---
    date: 2023-04-12
    ---

This resulted in #strptime raising a TypeError because datetime.date
isn't a string. This commit changes the plugin code to always accept a
native datetime.date or datetime.datetime, even if meta_time_format is
not set, and handle them without string parsing.

Close #48
  • Loading branch information
jgraichen committed Apr 12, 2023
1 parent 9021298 commit e07b738
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 16 deletions.
32 changes: 20 additions & 12 deletions mkdocs_blogging_plugin/plugin.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
import os
import logging
import os
import re
from datetime import date, datetime
from pathlib import Path
from typing import Dict

from jinja2 import Environment, FileSystemLoader, Template, select_autoescape
from mkdocs.config import config_options
from mkdocs.plugins import BasePlugin
from mkdocs.exceptions import PluginError
from jinja2 import Environment, FileSystemLoader, Template, select_autoescape
from mkdocs.plugins import BasePlugin

from mkdocs_blogging_plugin.config import BloggingConfig

from .util import Util
from pathlib import Path
from datetime import datetime

DIR_PATH = Path(os.path.dirname(os.path.realpath(__file__)))
BLOG_PAGE_PATTERN = re.compile(
Expand Down Expand Up @@ -332,13 +335,10 @@ def generate_html(self, category) -> str:

def with_timestamp(self, page, by_revision):
timestamp = None
if self.meta_time_format:
if "time" in page.meta:
timestamp = datetime.strptime(
page.meta["time"], self.meta_time_format).timestamp()
elif "date" in page.meta:
timestamp = datetime.strptime(
page.meta["date"], self.meta_time_format).timestamp()
if "time" in page.meta:
timestamp = self._parse_time(page.meta["time"])
if "date" in page.meta and timestamp is None:
timestamp = self._parse_time(page.meta["date"])
if not timestamp:
timestamp = self.util.get_git_commit_timestamp(
page.file.abs_src_path, is_first_commit=(not by_revision))
Expand All @@ -347,3 +347,11 @@ def with_timestamp(self, page, by_revision):
timestamp, False, format=self.time_format, _locale=self.locale)

return page

def _parse_time(self, value):
if isinstance(value, datetime):
return value.timestamp()
if isinstance(value, date):
return datetime.combine(value, datetime.min.time()).timestamp()
if self.meta_time_format:
return datetime.strptime(value, self.meta_time_format).timestamp()
20 changes: 16 additions & 4 deletions tests/test_format.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from datetime import datetime
import datetime
import os
import unittest
from pathlib import Path
from types import SimpleNamespace
import unittest

from mkdocs_blogging_plugin.plugin import BloggingPlugin

Expand All @@ -29,12 +29,24 @@ def test_date(self):
meta_date_str = "2022-05-03 11:09:00"
page = SimpleNamespace(meta={"time": meta_date_str})

date = datetime.strptime(
date = datetime.datetime.strptime(
meta_date_str, self.config["meta_time_format"])

page = self.plugin.with_timestamp(page, False)

expected_output = datetime.strftime(
expected_output = datetime.datetime.strftime(
date, self.config["time_format"])

assert page.meta["localized-time"] == expected_output

def test_date_object(self):
page = SimpleNamespace(meta={"date": datetime.date(2023, 4, 12)})
page = self.plugin.with_timestamp(page, False)

assert page.meta["localized-time"] == "2023/04/12 00:00:00"

def test_datetime_object(self):
page = SimpleNamespace(meta={"date": datetime.datetime(2023, 4, 12, 9, 15, 30)})
page = self.plugin.with_timestamp(page, False)

assert page.meta["localized-time"] == "2023/04/12 09:15:30"

0 comments on commit e07b738

Please sign in to comment.