|
| 1 | +#! python3 # noqa: E265 |
| 2 | + |
| 3 | +# ############################################################################ |
| 4 | +# ########## Libraries ############# |
| 5 | +# ################################## |
| 6 | + |
| 7 | +# standard library |
| 8 | +import logging |
| 9 | +from pathlib import Path |
| 10 | +from typing import Literal, Optional |
| 11 | + |
| 12 | +# 3rd party |
| 13 | +import mkdocs.plugins |
| 14 | +from material import __version__ as material_version |
| 15 | +from mkdocs.config.defaults import MkDocsConfig |
| 16 | +from mkdocs.structure.pages import Page |
| 17 | +from mkdocs.utils.meta import get_data |
| 18 | + |
| 19 | +# ########################################################################### |
| 20 | +# ########## Global ################ |
| 21 | +# ################################## |
| 22 | + |
| 23 | + |
| 24 | +logger = logging.getLogger("mkdocs") |
| 25 | +log_prefix = f"[{__name__}] " |
| 26 | + |
| 27 | +# ########################################################################### |
| 28 | +# ########## Functions ############# |
| 29 | +# ################################## |
| 30 | + |
| 31 | + |
| 32 | +def get_latest_content( |
| 33 | + content_type: Literal["articles", "rdp"], |
| 34 | + count: int = 10, |
| 35 | + social_card_image_base: str = "https://geotribu.fr/assets/images/social/", |
| 36 | +): |
| 37 | + output_contents_list: list[Page] = [] |
| 38 | + |
| 39 | + if content_type == "articles": |
| 40 | + glob_pattern = "202*/202*.md" |
| 41 | + elif content_type == "rdp": |
| 42 | + glob_pattern = "202*/rdp_202*.md" |
| 43 | + |
| 44 | + for content in sorted( |
| 45 | + Path(f"content/{content_type}/").glob(glob_pattern), reverse=True |
| 46 | + )[:count]: |
| 47 | + with content.open(encoding="utf-8-sig", errors="strict") as f: |
| 48 | + source = f.read() |
| 49 | + |
| 50 | + page_meta = get_data(source)[1] |
| 51 | + |
| 52 | + page_rel = str(content.relative_to("content/"))[:-3] |
| 53 | + |
| 54 | + if page_meta.get("image") is None or page_meta.get("image") == "": |
| 55 | + social_card_url = f"{social_card_image_base}{page_rel}.png" |
| 56 | + output_contents_list.append( |
| 57 | + get_data(source)[1] | {"url_rel": page_rel} | {"image": social_card_url} |
| 58 | + ) |
| 59 | + else: |
| 60 | + output_contents_list.append(get_data(source)[1] | {"url_rel": page_rel}) |
| 61 | + |
| 62 | + return output_contents_list |
| 63 | + |
| 64 | + |
| 65 | +def is_mkdocs_theme_material_insiders() -> Optional[bool]: |
| 66 | + """Check if the material theme is community or insiders edition. |
| 67 | +
|
| 68 | + Returns: |
| 69 | + bool: True if the theme is Insiders edition. False if community. |
| 70 | + """ |
| 71 | + if material_version is not None and "insiders" in material_version: |
| 72 | + logger.debug(log_prefix + "Material theme edition INSIDERS") |
| 73 | + return True |
| 74 | + else: |
| 75 | + logger.debug(log_prefix + "Material theme edition COMMUNITY") |
| 76 | + return False |
| 77 | + |
| 78 | + |
| 79 | +# ########################################################################### |
| 80 | +# ########## Hooks ################# |
| 81 | +# ################################## |
| 82 | + |
| 83 | + |
| 84 | +@mkdocs.plugins.event_priority(10) |
| 85 | +def on_config(config: MkDocsConfig) -> MkDocsConfig: |
| 86 | + """The config event is the first event called on build and |
| 87 | + is run immediately after the user configuration is loaded and validated. |
| 88 | + Any alterations to the config should be made here. |
| 89 | +
|
| 90 | + See: https://www.mkdocs.org/user-guide/plugins/#on_config |
| 91 | +
|
| 92 | + Args: |
| 93 | + config (config_options.Config): global configuration object |
| 94 | +
|
| 95 | + Returns: |
| 96 | + MkDocsConfig: global configuration object |
| 97 | + """ |
| 98 | + # determine the website flavor |
| 99 | + config_filename = Path(config.get("config_file_path")).name |
| 100 | + if config_filename == "mkdocs.yml": |
| 101 | + config["extra"]["website_flavor"] = "insiders" |
| 102 | + elif config_filename == "mkdocs-free.yml": |
| 103 | + config["extra"]["website_flavor"] = "community" |
| 104 | + else: |
| 105 | + config["extra"]["website_flavor"] = "minimal" |
| 106 | + |
| 107 | + # check if insiders version is installed |
| 108 | + if ( |
| 109 | + config["extra"]["website_flavor"] == "insiders" |
| 110 | + and not is_mkdocs_theme_material_insiders() |
| 111 | + ): |
| 112 | + logger.warning( |
| 113 | + log_prefix |
| 114 | + + f"Le fichier {config.get('config_file_path')} contient des paramètres ou " |
| 115 | + "plugins uniquement disponibles dans la version Insiders (payante) du thème " |
| 116 | + "Material. Or c'est la version community (gratuite) qui est installée " |
| 117 | + f"({material_version}). La génération va probablement échouer. Deux solutions :" |
| 118 | + "A. Installer la version Insiders (requiert un jeton GitHub). " |
| 119 | + "B. Utiliser la configuration basée sur la version communautaire (gratuite), " |
| 120 | + "par exemple : 'mkdocs build -f mkdocs-free.yml'" |
| 121 | + ) |
| 122 | + config["extra"]["website_flavor"] = "community" |
| 123 | + |
| 124 | + logger.info( |
| 125 | + log_prefix + f"Génération du site {config.get('site_name')} " |
| 126 | + f"en version {config.get('extra').get('website_flavor').upper()}" |
| 127 | + ) |
| 128 | + |
| 129 | + # latest contents |
| 130 | + latest_contents: dict = {"articles": [], "rdp": []} |
| 131 | + for k in latest_contents: |
| 132 | + latest_contents[k] = get_latest_content( |
| 133 | + content_type=k, |
| 134 | + social_card_image_base=f"{config.get('site_url')}assets/images/social/", |
| 135 | + ) |
| 136 | + |
| 137 | + config["extra"]["latest"] = latest_contents |
| 138 | + logger.info( |
| 139 | + log_prefix + "Contenus récents ajoutés à la configuration globale du site." |
| 140 | + ) |
0 commit comments