From 63b043533728c341c58f1286b229c00786143644 Mon Sep 17 00:00:00 2001 From: GeoJulien Date: Fri, 7 Jun 2024 22:51:29 +0200 Subject: [PATCH 1/4] feature(option): allow customize output filenames --- mkdocs_rss_plugin/config.py | 11 +++- mkdocs_rss_plugin/constants.py | 4 -- mkdocs_rss_plugin/models.py | 24 ++++---- mkdocs_rss_plugin/plugin.py | 37 ++++++------ .../mkdocs_custom_output_basename.yml | 14 +++++ tests/test_build.py | 59 +++++++++++++++---- tests/test_config.py | 12 ++++ 7 files changed, 114 insertions(+), 47 deletions(-) create mode 100644 tests/fixtures/mkdocs_custom_output_basename.yml diff --git a/mkdocs_rss_plugin/config.py b/mkdocs_rss_plugin/config.py index 8010cc7f..98c47272 100644 --- a/mkdocs_rss_plugin/config.py +++ b/mkdocs_rss_plugin/config.py @@ -9,10 +9,18 @@ from mkdocs.config import config_options from mkdocs.config.base import Config - # ############################################################################ # ########## Classes ############### # ################################## + + +class _OutputBasenameConfig(Config): + json_created = config_options.Type(str, default="feed_json_created.json") + json_updated = config_options.Type(str, default="feed_json_updated.json") + rss_created = config_options.Type(str, default="feed_rss_created.xml") + rss_updated = config_options.Type(str, default="feed_rss_updated.xml") + + class RssPluginConfig(Config): """Configuration for RSS plugin for Mkdocs.""" @@ -29,6 +37,7 @@ class RssPluginConfig(Config): json_feed_enabled = config_options.Type(bool, default=True) length = config_options.Type(int, default=20) match_path = config_options.Type(str, default=".*") + output_basename = config_options.SubConfig(_OutputBasenameConfig) pretty_print = config_options.Type(bool, default=False) rss_feed_enabled = config_options.Type(bool, default=True) url_parameters = config_options.Optional(config_options.Type(dict)) diff --git a/mkdocs_rss_plugin/constants.py b/mkdocs_rss_plugin/constants.py index 0f142eb9..07a8ddba 100644 --- a/mkdocs_rss_plugin/constants.py +++ b/mkdocs_rss_plugin/constants.py @@ -17,10 +17,6 @@ DEFAULT_TEMPLATE_FOLDER = Path(__file__).parent / "templates" DEFAULT_TEMPLATE_FILENAME = DEFAULT_TEMPLATE_FOLDER / "rss.xml.jinja2" MKDOCS_LOGGER_NAME = "[RSS-plugin]" -OUTPUT_RSS_FEED_CREATED = "feed_rss_created.xml" -OUTPUT_RSS_FEED_UPDATED = "feed_rss_updated.xml" -OUTPUT_JSON_FEED_CREATED = "feed_json_created.json" -OUTPUT_JSON_FEED_UPDATED = "feed_json_updated.json" REMOTE_REQUEST_HEADERS = { "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "User-Agent": f"{__about__.__title__}/{__about__.__version__}", diff --git a/mkdocs_rss_plugin/models.py b/mkdocs_rss_plugin/models.py index 16c545bb..7e863bd8 100644 --- a/mkdocs_rss_plugin/models.py +++ b/mkdocs_rss_plugin/models.py @@ -7,7 +7,7 @@ # standard from datetime import datetime from pathlib import Path -from typing import NamedTuple +from typing import NamedTuple, Optional # ############################################################################ @@ -16,14 +16,14 @@ class PageInformation(NamedTuple): """Data type to set and get page information in order to produce the RSS feed.""" - abs_path: Path = None - categories: list = None - authors: tuple = None - created: datetime = None - description: str = None - guid: str = None - image: str = None - title: str = None - updated: datetime = None - url_comments: str = None - url_full: str = None + abs_path: Optional[Path] = None + categories: Optional[list] = None + authors: Optional[tuple] = None + created: Optional[datetime] = None + description: Optional[str] = None + guid: Optional[str] = None + image: Optional[str] = None + title: Optional[str] = None + updated: Optional[datetime] = None + url_comments: Optional[str] = None + url_full: Optional[str] = None diff --git a/mkdocs_rss_plugin/plugin.py b/mkdocs_rss_plugin/plugin.py index 78bbed58..fe942c8d 100644 --- a/mkdocs_rss_plugin/plugin.py +++ b/mkdocs_rss_plugin/plugin.py @@ -28,10 +28,6 @@ DEFAULT_TEMPLATE_FILENAME, DEFAULT_TEMPLATE_FOLDER, MKDOCS_LOGGER_NAME, - OUTPUT_JSON_FEED_CREATED, - OUTPUT_JSON_FEED_UPDATED, - OUTPUT_RSS_FEED_CREATED, - OUTPUT_RSS_FEED_UPDATED, ) from mkdocs_rss_plugin.integrations.theme_material_social_plugin import ( IntegrationMaterialSocialCards, @@ -82,7 +78,6 @@ def on_config(self, config: config_options.Config) -> dict: :return: plugin configuration object :rtype: dict """ - # Skip if disabled if not self.config.enabled: return config @@ -121,8 +116,8 @@ def on_config(self, config: config_options.Config) -> dict: "description": config.site_description, "entries": [], "generator": f"{__title__} - v{__version__}", - "html_url": self.util.get_site_url(config), - "language": self.util.guess_locale(config), + "html_url": self.util.get_site_url(mkdocs_config=config), + "language": self.util.guess_locale(mkdocs_config=config), "pubDate": formatdate(get_build_timestamp()), "repo_url": config.repo_url, "title": config.site_name, @@ -185,16 +180,16 @@ def on_config(self, config: config_options.Config) -> dict: if base_feed.get("html_url"): # concatenate both URLs self.feed_created["rss_url"] = ( - base_feed.get("html_url") + OUTPUT_RSS_FEED_CREATED + base_feed.get("html_url") + self.config.output_basename.rss_created ) self.feed_updated["rss_url"] = ( - base_feed.get("html_url") + OUTPUT_RSS_FEED_UPDATED + base_feed.get("html_url") + self.config.output_basename.rss_updated ) self.feed_created["json_url"] = ( - base_feed.get("html_url") + OUTPUT_JSON_FEED_CREATED + base_feed.get("html_url") + self.config.output_basename.json_created ) self.feed_updated["json_url"] = ( - base_feed.get("html_url") + OUTPUT_JSON_FEED_UPDATED + base_feed.get("html_url") + self.config.output_basename.json_updated ) else: logger.error( @@ -210,7 +205,7 @@ def on_config(self, config: config_options.Config) -> dict: @event_priority(priority=-75) def on_page_content( self, html: str, page: Page, config: config_options.Config, files - ) -> str: + ) -> Optional[str]: """The page_content event is called after the Markdown text is rendered to HTML (but before being passed to a template) and can be used to alter the HTML body of the page. @@ -299,7 +294,7 @@ def on_page_content( ) ) - def on_post_build(self, config: config_options.Config) -> dict: + def on_post_build(self, config: config_options.Config) -> Optional[dict]: """The post_build event does not alter any variables. \ Use this event to call post-build scripts. \ See: @@ -318,10 +313,18 @@ def on_post_build(self, config: config_options.Config) -> dict: pretty_print = self.config.pretty_print # output filepaths - out_feed_created = Path(config.site_dir).joinpath(OUTPUT_RSS_FEED_CREATED) - out_feed_updated = Path(config.site_dir).joinpath(OUTPUT_RSS_FEED_UPDATED) - out_json_created = Path(config.site_dir).joinpath(OUTPUT_JSON_FEED_CREATED) - out_json_updated = Path(config.site_dir).joinpath(OUTPUT_JSON_FEED_UPDATED) + out_feed_created = Path(config.site_dir).joinpath( + self.config.output_basename.rss_created + ) + out_feed_updated = Path(config.site_dir).joinpath( + self.config.output_basename.rss_updated + ) + out_json_created = Path(config.site_dir).joinpath( + self.config.output_basename.json_created + ) + out_json_updated = Path(config.site_dir).joinpath( + self.config.output_basename.json_updated + ) # created items self.feed_created.get("entries").extend( diff --git a/tests/fixtures/mkdocs_custom_output_basename.yml b/tests/fixtures/mkdocs_custom_output_basename.yml new file mode 100644 index 00000000..e5b621f2 --- /dev/null +++ b/tests/fixtures/mkdocs_custom_output_basename.yml @@ -0,0 +1,14 @@ +site_name: Test RSS Plugin with custom RSS and JSON feeds output +site_description: Test RSS Plugin with customized output_basename +site_url: https://guts.github.io/mkdocs-rss-plugin + +plugins: + - rss: + output_basename: + json_created: json + json_updated: json-updated + rss_created: rss + rss_updated: rss-updated + +theme: + name: mkdocs diff --git a/tests/test_build.py b/tests/test_build.py index efbb9705..b3277f42 100644 --- a/tests/test_build.py +++ b/tests/test_build.py @@ -15,11 +15,9 @@ # Standard library import json +import logging import tempfile import unittest - -# logging -from logging import DEBUG, getLogger from pathlib import Path from traceback import format_exception @@ -27,19 +25,17 @@ import feedparser import jsonfeed -# project -from mkdocs_rss_plugin.constants import ( - OUTPUT_JSON_FEED_CREATED, - OUTPUT_JSON_FEED_UPDATED, - OUTPUT_RSS_FEED_CREATED, - OUTPUT_RSS_FEED_UPDATED, -) - # test suite from tests.base import BaseTest -logger = getLogger(__name__) -logger.setLevel(DEBUG) +# -- Globals -- +logger = logging.getLogger(__name__) +logger.setLevel(logging.DEBUG) + +OUTPUT_RSS_FEED_CREATED = "feed_rss_created.xml" +OUTPUT_RSS_FEED_UPDATED = "feed_rss_updated.xml" +OUTPUT_JSON_FEED_CREATED = "feed_json_created.json" +OUTPUT_JSON_FEED_UPDATED = "feed_json_updated.json" # ############################################################################# # ########## Classes ############### @@ -531,6 +527,43 @@ def test_simple_build_language_specific_material(self): feed_parsed = feedparser.parse(Path(tmpdirname) / OUTPUT_RSS_FEED_UPDATED) self.assertEqual(feed_parsed.feed.get("language"), "fr") + def test_simple_build_custom_output_basename(self): + config = self.get_plugin_config_from_mkdocs( + mkdocs_yml_filepath=Path( + "tests/fixtures/mkdocs_custom_output_basename.yml" + ), + plugin_name="rss", + ) + + with tempfile.TemporaryDirectory() as tmpdirname: + cli_result = self.build_docs_setup( + testproject_path="docs", + mkdocs_yml_filepath=Path( + "tests/fixtures/mkdocs_custom_output_basename.yml" + ), + output_path=tmpdirname, + strict=True, + ) + + if cli_result.exception is not None: + e = cli_result.exception + logger.debug(format_exception(type(e), e, e.__traceback__)) + + self.assertEqual(cli_result.exit_code, 0) + self.assertIsNone(cli_result.exception) + + # created items + feed_parsed = feedparser.parse( + Path(tmpdirname) / config.output_basename.rss_created + ) + self.assertEqual(feed_parsed.bozo, 0) + + # updated items + feed_parsed = feedparser.parse( + Path(tmpdirname) / config.output_basename.rss_updated + ) + self.assertEqual(feed_parsed.bozo, 0) + def test_simple_build_pretty_print_enabled(self): with tempfile.TemporaryDirectory() as tmpdirname: cli_result = self.build_docs_setup( diff --git a/tests/test_config.py b/tests/test_config.py index c7a7cdca..478c54f1 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -69,6 +69,12 @@ def test_plugin_config_defaults(self): "json_feed_enabled": True, "length": 20, "match_path": ".*", + "output_basename": { + "json_created": "feed_json_created.json", + "json_updated": "feed_json_updated.json", + "rss_created": "feed_rss_created.xml", + "rss_updated": "feed_rss_updated.xml", + }, "pretty_print": False, "rss_feed_enabled": True, "url_parameters": None, @@ -99,6 +105,12 @@ def test_plugin_config_image(self): "json_feed_enabled": True, "length": 20, "match_path": ".*", + "output_basename": { + "json_created": "feed_json_created.json", + "json_updated": "feed_json_updated.json", + "rss_created": "feed_rss_created.xml", + "rss_updated": "feed_rss_updated.xml", + }, "pretty_print": False, "rss_feed_enabled": True, "url_parameters": None, From 7debda7b3765c01104242e6b15d40c471eb50cce Mon Sep 17 00:00:00 2001 From: GeoJulien Date: Sat, 8 Jun 2024 18:02:54 +0200 Subject: [PATCH 2/4] feature: rename output_basename into feeds_filenames --- mkdocs_rss_plugin/config.py | 4 ++-- mkdocs_rss_plugin/plugin.py | 16 ++++++++-------- ...ame.yml => mkdocs_custom_feeds_filenames.yml} | 2 +- tests/test_build.py | 2 +- 4 files changed, 12 insertions(+), 12 deletions(-) rename tests/fixtures/{mkdocs_custom_output_basename.yml => mkdocs_custom_feeds_filenames.yml} (93%) diff --git a/mkdocs_rss_plugin/config.py b/mkdocs_rss_plugin/config.py index 98c47272..b2129bdb 100644 --- a/mkdocs_rss_plugin/config.py +++ b/mkdocs_rss_plugin/config.py @@ -14,7 +14,7 @@ # ################################## -class _OutputBasenameConfig(Config): +class _FeedsFilenamesConfig(Config): json_created = config_options.Type(str, default="feed_json_created.json") json_updated = config_options.Type(str, default="feed_json_updated.json") rss_created = config_options.Type(str, default="feed_rss_created.xml") @@ -37,7 +37,7 @@ class RssPluginConfig(Config): json_feed_enabled = config_options.Type(bool, default=True) length = config_options.Type(int, default=20) match_path = config_options.Type(str, default=".*") - output_basename = config_options.SubConfig(_OutputBasenameConfig) + feeds_filenames = config_options.SubConfig(_FeedsFilenamesConfig) pretty_print = config_options.Type(bool, default=False) rss_feed_enabled = config_options.Type(bool, default=True) url_parameters = config_options.Optional(config_options.Type(dict)) diff --git a/mkdocs_rss_plugin/plugin.py b/mkdocs_rss_plugin/plugin.py index fe942c8d..715ba62d 100644 --- a/mkdocs_rss_plugin/plugin.py +++ b/mkdocs_rss_plugin/plugin.py @@ -180,16 +180,16 @@ def on_config(self, config: config_options.Config) -> dict: if base_feed.get("html_url"): # concatenate both URLs self.feed_created["rss_url"] = ( - base_feed.get("html_url") + self.config.output_basename.rss_created + base_feed.get("html_url") + self.config.feeds_filenames.rss_created ) self.feed_updated["rss_url"] = ( - base_feed.get("html_url") + self.config.output_basename.rss_updated + base_feed.get("html_url") + self.config.feeds_filenames.rss_updated ) self.feed_created["json_url"] = ( - base_feed.get("html_url") + self.config.output_basename.json_created + base_feed.get("html_url") + self.config.feeds_filenames.json_created ) self.feed_updated["json_url"] = ( - base_feed.get("html_url") + self.config.output_basename.json_updated + base_feed.get("html_url") + self.config.feeds_filenames.json_updated ) else: logger.error( @@ -314,16 +314,16 @@ def on_post_build(self, config: config_options.Config) -> Optional[dict]: # output filepaths out_feed_created = Path(config.site_dir).joinpath( - self.config.output_basename.rss_created + self.config.feeds_filenames.rss_created ) out_feed_updated = Path(config.site_dir).joinpath( - self.config.output_basename.rss_updated + self.config.feeds_filenames.rss_updated ) out_json_created = Path(config.site_dir).joinpath( - self.config.output_basename.json_created + self.config.feeds_filenames.json_created ) out_json_updated = Path(config.site_dir).joinpath( - self.config.output_basename.json_updated + self.config.feeds_filenames.json_updated ) # created items diff --git a/tests/fixtures/mkdocs_custom_output_basename.yml b/tests/fixtures/mkdocs_custom_feeds_filenames.yml similarity index 93% rename from tests/fixtures/mkdocs_custom_output_basename.yml rename to tests/fixtures/mkdocs_custom_feeds_filenames.yml index e5b621f2..4290154d 100644 --- a/tests/fixtures/mkdocs_custom_output_basename.yml +++ b/tests/fixtures/mkdocs_custom_feeds_filenames.yml @@ -4,7 +4,7 @@ site_url: https://guts.github.io/mkdocs-rss-plugin plugins: - rss: - output_basename: + feed_filenames: json_created: json json_updated: json-updated rss_created: rss diff --git a/tests/test_build.py b/tests/test_build.py index b3277f42..1f8bc2cf 100644 --- a/tests/test_build.py +++ b/tests/test_build.py @@ -539,7 +539,7 @@ def test_simple_build_custom_output_basename(self): cli_result = self.build_docs_setup( testproject_path="docs", mkdocs_yml_filepath=Path( - "tests/fixtures/mkdocs_custom_output_basename.yml" + "tests/fixtures/mkdocs_custom_feeds_filenames.yml" ), output_path=tmpdirname, strict=True, From 611208ec15a31fa55a15840daa55acbe92336264 Mon Sep 17 00:00:00 2001 From: GeoJulien Date: Sat, 8 Jun 2024 18:04:36 +0200 Subject: [PATCH 3/4] docs: add how to customize output feeds filenames --- docs/configuration.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/docs/configuration.md b/docs/configuration.md index 605b9a81..7de4e209 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -415,6 +415,33 @@ At the end, into the RSS you will get: - for Python >= 3.9, it uses the standard library and ships [tzdata](https://pypi.org/project/tzdata/) only on Windows which do not provide such data - for Python < 3.9, [pytz](https://pypi.org/project/pytz/) is shipped. +---- + +### `feeds_filenames`: customize the output feed URL { #feeds_filenames } + +> Since version 1.13.0. + +Customize every feed filenames generated by the plugin: + +```yaml title="mkdocs.yml with custom RSS and JSON feeds names." +plugins: + - rss: + feeds_filenames: + json_created: feed.json + json_updated: feed-updated.json + rss_created: rss.xml + rss_updated: rss-updated.xml +``` + +Default: + +- JSON feed for **created** items: `feed_json_created.json` +- JSON feed for **updated** items: `feed_json_updated.json` +- RSS feed for **created** items: `feed_rss_created.json` +- RSS feed for **updated** items: `feed_rss_updated.json` + +---- + ### `pretty_print`: prettified XML By default, the output file is minified, using Jinja2 strip options and manual work. It's possible to disable it and prettify the output using `pretty_print: true`. From 222d3f0519f0eec1b21bbafe4a4b8e32ee950002 Mon Sep 17 00:00:00 2001 From: GeoJulien Date: Sat, 8 Jun 2024 18:07:50 +0200 Subject: [PATCH 4/4] fix: tests after renaming output option --- tests/fixtures/mkdocs_custom_feeds_filenames.yml | 2 +- tests/test_build.py | 6 +++--- tests/test_config.py | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/fixtures/mkdocs_custom_feeds_filenames.yml b/tests/fixtures/mkdocs_custom_feeds_filenames.yml index 4290154d..dbd85ccf 100644 --- a/tests/fixtures/mkdocs_custom_feeds_filenames.yml +++ b/tests/fixtures/mkdocs_custom_feeds_filenames.yml @@ -4,7 +4,7 @@ site_url: https://guts.github.io/mkdocs-rss-plugin plugins: - rss: - feed_filenames: + feeds_filenames: json_created: json json_updated: json-updated rss_created: rss diff --git a/tests/test_build.py b/tests/test_build.py index 1f8bc2cf..75467e8d 100644 --- a/tests/test_build.py +++ b/tests/test_build.py @@ -530,7 +530,7 @@ def test_simple_build_language_specific_material(self): def test_simple_build_custom_output_basename(self): config = self.get_plugin_config_from_mkdocs( mkdocs_yml_filepath=Path( - "tests/fixtures/mkdocs_custom_output_basename.yml" + "tests/fixtures/mkdocs_custom_feeds_filenames.yml" ), plugin_name="rss", ) @@ -554,13 +554,13 @@ def test_simple_build_custom_output_basename(self): # created items feed_parsed = feedparser.parse( - Path(tmpdirname) / config.output_basename.rss_created + Path(tmpdirname) / config.feeds_filenames.rss_created ) self.assertEqual(feed_parsed.bozo, 0) # updated items feed_parsed = feedparser.parse( - Path(tmpdirname) / config.output_basename.rss_updated + Path(tmpdirname) / config.feeds_filenames.rss_updated ) self.assertEqual(feed_parsed.bozo, 0) diff --git a/tests/test_config.py b/tests/test_config.py index 478c54f1..89083028 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -69,7 +69,7 @@ def test_plugin_config_defaults(self): "json_feed_enabled": True, "length": 20, "match_path": ".*", - "output_basename": { + "feeds_filenames": { "json_created": "feed_json_created.json", "json_updated": "feed_json_updated.json", "rss_created": "feed_rss_created.xml", @@ -105,7 +105,7 @@ def test_plugin_config_image(self): "json_feed_enabled": True, "length": 20, "match_path": ".*", - "output_basename": { + "feeds_filenames": { "json_created": "feed_json_created.json", "json_updated": "feed_json_updated.json", "rss_created": "feed_rss_created.xml",