def _build_theme_template(template_name, env, files, config, nav): """ Build a template using the theme environment. """ log.debug("Building theme template: {}".format(template_name)) try: template = env.get_template(template_name) except TemplateNotFound: log.warning( "Template skipped: '{}' not found in theme directories.".format( template_name)) return output = _build_template(template_name, template, files, config, nav) if output.strip(): output_path = os.path.join(config['site_dir'], template_name) utils.write_file(output.encode('utf-8'), output_path) if template_name == 'sitemap.xml': log.debug("Gzipping template: %s", template_name) gz_filename = '{}.gz'.format(output_path) with open(gz_filename, 'wb') as f: timestamp = utils.get_build_timestamp() with gzip.GzipFile(fileobj=f, filename=gz_filename, mode='wb', mtime=timestamp) as gz_buf: gz_buf.write(output.encode('utf-8')) else: log.info("Template skipped: '{}' generated empty output.".format( template_name))
def on_config(self, config: config_options.Config) -> dict: """The config event is the first event called on build and is run immediately after the user configuration is loaded and validated. Any alterations to the config should be made here. https://www.mkdocs.org/user-guide/plugins/#on_config :param config: global configuration object :type config: config_options.Config :raises FileExistsError: if the template for the RSS feed is not found :return: plugin configuration object :rtype: dict """ # Skip if disabled if not self.config.get("enabled"): return config # check template dirs if not Path(DEFAULT_TEMPLATE_FILENAME).is_file(): raise FileExistsError(DEFAULT_TEMPLATE_FILENAME) self.tpl_file = Path(DEFAULT_TEMPLATE_FILENAME) self.tpl_folder = DEFAULT_TEMPLATE_FOLDER # start a feed dictionary using global config vars base_feed = { "author": config.get("site_author", None), "buildDate": formatdate(get_build_timestamp()), "copyright": config.get("copyright", None), "description": config.get("site_description", None), "entries": [], "generator": "{} - v{}".format(__title__, __version__), "html_url": self.util.get_site_url(config), "language": self.util.guess_locale(config), "pubDate": formatdate(get_build_timestamp()), "repo_url": config.get("repo_url", config.get("site_url", None)), "title": config.get("site_name", None), "ttl": self.config.get("feed_ttl", None), } # feed image if self.config.get("image"): base_feed["logo_url"] = self.config.get("image") # pattern to match pages included in output self.match_path_pattern = compile(self.config.get("match_path")) # date handling if self.config.get("date_from_meta") is not None: self.src_date_created = self.config.get("date_from_meta").get( "as_creation", False ) self.src_date_updated = self.config.get("date_from_meta").get( "as_update", False ) self.meta_datetime_format = self.config.get("date_from_meta").get( "datetime_format", "%Y-%m-%d %H:%M" ) logger.debug( "[rss-plugin] Dates will be retrieved from page meta (yaml " "frontmatter). The git log will be used as fallback." ) else: logger.debug("[rss-plugin] Dates will be retrieved from git log.") # create 2 final dicts self.feed_created = deepcopy(base_feed) self.feed_updated = deepcopy(base_feed) # final feed url if base_feed.get("html_url"): # concatenate both URLs self.feed_created["rss_url"] = ( base_feed.get("html_url") + OUTPUT_FEED_CREATED ) self.feed_updated["rss_url"] = ( base_feed.get("html_url") + OUTPUT_FEED_UPDATED ) else: logging.warning( "[rss-plugin] The variable `site_url` is not set in the MkDocs " "configuration file whereas a URL is mandatory to publish. " "See: https://validator.w3.org/feed/docs/rss2.html#requiredChannelElements" ) self.feed_created["rss_url"] = self.feed_updated["rss_url"] = None # ending event return config
def get_file_dates( self, in_page: Page, source_date_creation: str = "git", source_date_update: str = "git", meta_datetime_format: str = "%Y-%m-%d %H:%M", ) -> Tuple[int, int]: """Extract creation and update dates from page metadata (yaml frontmatter) or \ git log for given file. :param in_page: input page to work with :type in_page: Page :param source_date_creation: which source to use (git or meta tag) for creation \ date, defaults to "git" :type source_date_creation: str, optional :param source_date_update: which source to use (git or meta tag) for update \ date, defaults to "git" :type source_date_update: str, optional :param meta_datetime_format: datetime string format, defaults to "%Y-%m-%d %H:%M" :type meta_datetime_format: str, optional :return: tuple of timestamps (creation date, last commit date) :rtype: Tuple[int, int] """ # empty vars dt_created = dt_updated = None # if enabled, try to retrieve dates from page metadata if source_date_creation != "git" and in_page.meta.get(source_date_creation): dt_created = self.get_date_from_meta( date_metatag_value=in_page.meta.get(source_date_creation), meta_datetime_format=meta_datetime_format, ) if isinstance(dt_created, str): logger.error(dt_created) dt_created = None if source_date_update != "git" and in_page.meta.get(source_date_update): dt_updated = self.get_date_from_meta( date_metatag_value=in_page.meta.get(source_date_creation), meta_datetime_format=meta_datetime_format, ) if isinstance(dt_updated, str): logger.error(dt_updated) dt_updated = None # explore git log if self.git_is_valid: try: # only if dates have not been retrieved from page meta if not dt_created: dt_created = self.repo.log( in_page.file.abs_src_path, n=1, date="short", format="%at", diff_filter="AR", ) if not dt_updated: dt_updated = self.repo.log( in_page.file.abs_src_path, n=1, date="short", format="%at", ) except GitCommandError as err: logging.warning( "[rss-plugin] Unable to read git logs of '%s'. Is git log readable?" " Falling back to build date. " " Trace: %s" % (in_page.file.abs_src_path, err) ) except GitCommandNotFound as err: logging.error( "[rss-plugin] Unable to perform command 'git log'. Is git installed? " " Falling back to build date. " " Trace: %s" % err ) self.git_is_valid = 0 else: pass # return results if all([dt_created, dt_updated]): return ( int(dt_created), int(dt_updated), ) else: logging.warning( "[rss-plugin] Dates could not be retrieved for page: %s." % in_page.file.abs_src_path ) return ( get_build_timestamp(), get_build_timestamp(), )