1
0
Fork 0
forked from github/pelican
pelican-theme/pelican/settings.py

742 lines
25 KiB
Python
Raw Normal View History

import copy
2019-11-17 19:19:37 +03:00
import importlib.util
import inspect
import locale
import logging
2015-06-16 09:25:09 +02:00
import os
import re
2023-10-11 19:29:17 +02:00
import sys
2015-06-16 09:25:09 +02:00
from os.path import isabs
2020-05-21 21:43:06 -06:00
from pathlib import Path
from types import ModuleType
from typing import Any, Dict, Optional
2015-06-16 09:25:09 +02:00
from pelican.log import LimitFilter
def load_source(name: str, path: str) -> ModuleType:
2019-11-17 19:19:37 +03:00
spec = importlib.util.spec_from_file_location(name, path)
mod = importlib.util.module_from_spec(spec)
2023-10-11 19:29:17 +02:00
sys.modules[name] = mod
2019-11-17 19:19:37 +03:00
spec.loader.exec_module(mod)
return mod
logger = logging.getLogger(__name__)
Settings = Dict[str, Any]
DEFAULT_THEME = os.path.join(
os.path.dirname(os.path.abspath(__file__)), "themes", "notmyidea"
)
DEFAULT_CONFIG = {
"PATH": os.curdir,
"ARTICLE_PATHS": [""],
"ARTICLE_EXCLUDES": [],
"PAGE_PATHS": ["pages"],
"PAGE_EXCLUDES": [],
"THEME": DEFAULT_THEME,
"OUTPUT_PATH": "output",
"READERS": {},
"STATIC_PATHS": ["images"],
"STATIC_EXCLUDES": [],
"STATIC_EXCLUDE_SOURCES": True,
"THEME_STATIC_DIR": "theme",
"THEME_STATIC_PATHS": [
"static",
],
"FEED_ALL_ATOM": "feeds/all.atom.xml",
"CATEGORY_FEED_ATOM": "feeds/{slug}.atom.xml",
"AUTHOR_FEED_ATOM": "feeds/{slug}.atom.xml",
"AUTHOR_FEED_RSS": "feeds/{slug}.rss.xml",
"TRANSLATION_FEED_ATOM": "feeds/all-{lang}.atom.xml",
"FEED_MAX_ITEMS": 100,
"RSS_FEED_SUMMARY_ONLY": True,
"FEED_APPEND_REF": False,
"SITEURL": "",
"SITENAME": "A Pelican Blog",
"DISPLAY_PAGES_ON_MENU": True,
"DISPLAY_CATEGORIES_ON_MENU": True,
"DOCUTILS_SETTINGS": {},
"OUTPUT_SOURCES": False,
"OUTPUT_SOURCES_EXTENSION": ".text",
"USE_FOLDER_AS_CATEGORY": True,
"DEFAULT_CATEGORY": "misc",
"WITH_FUTURE_DATES": True,
"CSS_FILE": "main.css",
"NEWEST_FIRST_ARCHIVES": True,
"REVERSE_CATEGORY_ORDER": False,
"DELETE_OUTPUT_DIRECTORY": False,
"OUTPUT_RETENTION": [],
"INDEX_SAVE_AS": "index.html",
"ARTICLE_URL": "{slug}.html",
"ARTICLE_SAVE_AS": "{slug}.html",
"ARTICLE_ORDER_BY": "reversed-date",
"ARTICLE_LANG_URL": "{slug}-{lang}.html",
"ARTICLE_LANG_SAVE_AS": "{slug}-{lang}.html",
"DRAFT_URL": "drafts/{slug}.html",
"DRAFT_SAVE_AS": "drafts/{slug}.html",
"DRAFT_LANG_URL": "drafts/{slug}-{lang}.html",
"DRAFT_LANG_SAVE_AS": "drafts/{slug}-{lang}.html",
"PAGE_URL": "pages/{slug}.html",
"PAGE_SAVE_AS": "pages/{slug}.html",
"PAGE_ORDER_BY": "basename",
"PAGE_LANG_URL": "pages/{slug}-{lang}.html",
"PAGE_LANG_SAVE_AS": "pages/{slug}-{lang}.html",
"DRAFT_PAGE_URL": "drafts/pages/{slug}.html",
"DRAFT_PAGE_SAVE_AS": "drafts/pages/{slug}.html",
"DRAFT_PAGE_LANG_URL": "drafts/pages/{slug}-{lang}.html",
"DRAFT_PAGE_LANG_SAVE_AS": "drafts/pages/{slug}-{lang}.html",
"STATIC_URL": "{path}",
"STATIC_SAVE_AS": "{path}",
"STATIC_CREATE_LINKS": False,
"STATIC_CHECK_IF_MODIFIED": False,
"CATEGORY_URL": "category/{slug}.html",
"CATEGORY_SAVE_AS": "category/{slug}.html",
"TAG_URL": "tag/{slug}.html",
"TAG_SAVE_AS": "tag/{slug}.html",
"AUTHOR_URL": "author/{slug}.html",
"AUTHOR_SAVE_AS": "author/{slug}.html",
"PAGINATION_PATTERNS": [
(1, "{name}{extension}", "{name}{extension}"),
(2, "{name}{number}{extension}", "{name}{number}{extension}"),
],
"YEAR_ARCHIVE_URL": "",
"YEAR_ARCHIVE_SAVE_AS": "",
"MONTH_ARCHIVE_URL": "",
"MONTH_ARCHIVE_SAVE_AS": "",
"DAY_ARCHIVE_URL": "",
"DAY_ARCHIVE_SAVE_AS": "",
"RELATIVE_URLS": False,
"DEFAULT_LANG": "en",
"ARTICLE_TRANSLATION_ID": "slug",
"PAGE_TRANSLATION_ID": "slug",
"DIRECT_TEMPLATES": ["index", "tags", "categories", "authors", "archives"],
"THEME_TEMPLATES_OVERRIDES": [],
"PAGINATED_TEMPLATES": {
"index": None,
"tag": None,
"category": None,
"author": None,
},
"PELICAN_CLASS": "pelican.Pelican",
"DEFAULT_DATE_FORMAT": "%a %d %B %Y",
"DATE_FORMATS": {},
"MARKDOWN": {
"extension_configs": {
"markdown.extensions.codehilite": {"css_class": "highlight"},
"markdown.extensions.extra": {},
"markdown.extensions.meta": {},
},
"output_format": "html5",
},
"JINJA_FILTERS": {},
"JINJA_GLOBALS": {},
"JINJA_TESTS": {},
"JINJA_ENVIRONMENT": {
"trim_blocks": True,
"lstrip_blocks": True,
"extensions": [],
},
"LOG_FILTER": [],
"LOCALE": [""], # defaults to user locale
"DEFAULT_PAGINATION": False,
"DEFAULT_ORPHANS": 0,
"DEFAULT_METADATA": {},
"FILENAME_METADATA": r"(?P<date>\d{4}-\d{2}-\d{2}).*",
"PATH_METADATA": "",
"EXTRA_PATH_METADATA": {},
"ARTICLE_PERMALINK_STRUCTURE": "",
"TYPOGRIFY": False,
"TYPOGRIFY_IGNORE_TAGS": [],
"TYPOGRIFY_DASHES": "default",
"SUMMARY_END_SUFFIX": "",
"SUMMARY_MAX_LENGTH": 50,
"PLUGIN_PATHS": [],
"PLUGINS": None,
"PYGMENTS_RST_OPTIONS": {},
"TEMPLATE_PAGES": {},
"TEMPLATE_EXTENSIONS": [".html"],
"IGNORE_FILES": [".#*"],
"SLUG_REGEX_SUBSTITUTIONS": [
(r"[^\w\s-]", ""), # remove non-alphabetical/whitespace/'-' chars
(r"(?u)\A\s*", ""), # strip leading whitespace
(r"(?u)\s*\Z", ""), # strip trailing whitespace
(r"[-\s]+", "-"), # reduce multiple whitespace or '-' to single '-'
],
"INTRASITE_LINK_REGEX": "[{|](?P<what>.*?)[|}]",
"SLUGIFY_SOURCE": "title",
"SLUGIFY_USE_UNICODE": False,
"SLUGIFY_PRESERVE_CASE": False,
"CACHE_CONTENT": False,
"CONTENT_CACHING_LAYER": "reader",
"CACHE_PATH": "cache",
"GZIP_CACHE": True,
"CHECK_MODIFIED_METHOD": "mtime",
"LOAD_CONTENT_CACHE": False,
"FORMATTED_FIELDS": ["summary"],
"PORT": 8000,
"BIND": "127.0.0.1",
2015-06-16 09:25:09 +02:00
}
PYGMENTS_RST_OPTIONS = None
def read_settings(
path: Optional[str] = None, override: Optional[Settings] = None
) -> Settings:
settings = override or {}
if path:
settings = dict(get_settings_from_file(path), **settings)
if settings:
settings = handle_deprecated_settings(settings)
if path:
# Make relative paths absolute
def getabs(maybe_relative, base_path=path):
if isabs(maybe_relative):
return maybe_relative
return os.path.abspath(
os.path.normpath(
os.path.join(os.path.dirname(base_path), maybe_relative)
)
)
for p in ["PATH", "OUTPUT_PATH", "THEME", "CACHE_PATH"]:
if settings.get(p) is not None:
absp = getabs(settings[p])
# THEME may be a name rather than a path
if p != "THEME" or os.path.exists(absp):
settings[p] = absp
if settings.get("PLUGIN_PATHS") is not None:
settings["PLUGIN_PATHS"] = [
getabs(pluginpath) for pluginpath in settings["PLUGIN_PATHS"]
]
settings = dict(copy.deepcopy(DEFAULT_CONFIG), **settings)
settings = configure_settings(settings)
# This is because there doesn't seem to be a way to pass extra
# parameters to docutils directive handlers, so we have to have a
# variable here that we'll import from within Pygments.run (see
# rstdirectives.py) to see what the user defaults were.
2024-05-30 10:33:50 -05:00
global PYGMENTS_RST_OPTIONS # noqa: PLW0603
PYGMENTS_RST_OPTIONS = settings.get("PYGMENTS_RST_OPTIONS", None)
return settings
2012-03-22 07:58:04 -07:00
def get_settings_from_module(module: Optional[ModuleType] = None) -> Settings:
2013-03-10 20:11:36 -07:00
"""Loads settings from a module, returns a dictionary."""
context = {}
if module is not None:
context.update((k, v) for k, v in inspect.getmembers(module) if k.isupper())
2012-03-22 07:58:04 -07:00
return context
def get_settings_from_file(path: str) -> Settings:
2013-03-10 20:11:36 -07:00
"""Loads settings from a file path, returning a dict."""
name, ext = os.path.splitext(os.path.basename(path))
module = load_source(name, path)
return get_settings_from_module(module)
def get_jinja_environment(settings: Settings) -> Settings:
"""Sets the environment for Jinja"""
jinja_env = settings.setdefault(
"JINJA_ENVIRONMENT", DEFAULT_CONFIG["JINJA_ENVIRONMENT"]
)
# Make sure we include the defaults if the user has set env variables
for key, value in DEFAULT_CONFIG["JINJA_ENVIRONMENT"].items():
if key not in jinja_env:
jinja_env[key] = value
return settings
def _printf_s_to_format_field(printf_string: str, format_field: str) -> str:
"""Tries to replace %s with {format_field} in the provided printf_string.
Raises ValueError in case of failure.
"""
TEST_STRING = "PELICAN_PRINTF_S_DEPRECATION"
expected = printf_string % TEST_STRING
2024-05-30 09:05:36 -05:00
result = printf_string.replace("{", "{{").replace("}", "}}") % f"{{{format_field}}}"
if result.format(**{format_field: TEST_STRING}) != expected:
raise ValueError(f"Failed to safely replace %s with {{{format_field}}}")
return result
def handle_deprecated_settings(settings: Settings) -> Settings:
"""Converts deprecated settings and issues warnings. Issues an exception
if both old and new setting is specified.
"""
# PLUGIN_PATH -> PLUGIN_PATHS
if "PLUGIN_PATH" in settings:
logger.warning(
"PLUGIN_PATH setting has been replaced by "
"PLUGIN_PATHS, moving it to the new setting name."
)
settings["PLUGIN_PATHS"] = settings["PLUGIN_PATH"]
del settings["PLUGIN_PATH"]
# PLUGIN_PATHS: str -> [str]
if isinstance(settings.get("PLUGIN_PATHS"), str):
logger.warning(
"Defining PLUGIN_PATHS setting as string "
"has been deprecated (should be a list)"
)
settings["PLUGIN_PATHS"] = [settings["PLUGIN_PATHS"]]
# JINJA_EXTENSIONS -> JINJA_ENVIRONMENT > extensions
if "JINJA_EXTENSIONS" in settings:
logger.warning(
"JINJA_EXTENSIONS setting has been deprecated, "
"moving it to JINJA_ENVIRONMENT setting."
)
settings["JINJA_ENVIRONMENT"]["extensions"] = settings["JINJA_EXTENSIONS"]
del settings["JINJA_EXTENSIONS"]
# {ARTICLE,PAGE}_DIR -> {ARTICLE,PAGE}_PATHS
for key in ["ARTICLE", "PAGE"]:
old_key = key + "_DIR"
new_key = key + "_PATHS"
if old_key in settings:
logger.warning(
"Deprecated setting %s, moving it to %s list", old_key, new_key
)
settings[new_key] = [settings[old_key]] # also make a list
del settings[old_key]
# EXTRA_TEMPLATES_PATHS -> THEME_TEMPLATES_OVERRIDES
if "EXTRA_TEMPLATES_PATHS" in settings:
logger.warning(
"EXTRA_TEMPLATES_PATHS is deprecated use "
"THEME_TEMPLATES_OVERRIDES instead."
)
2024-05-30 10:53:38 -05:00
if settings.get("THEME_TEMPLATES_OVERRIDES"):
raise Exception(
"Setting both EXTRA_TEMPLATES_PATHS and "
"THEME_TEMPLATES_OVERRIDES is not permitted. Please move to "
"only setting THEME_TEMPLATES_OVERRIDES."
)
settings["THEME_TEMPLATES_OVERRIDES"] = settings["EXTRA_TEMPLATES_PATHS"]
del settings["EXTRA_TEMPLATES_PATHS"]
# MD_EXTENSIONS -> MARKDOWN
if "MD_EXTENSIONS" in settings:
logger.warning(
"MD_EXTENSIONS is deprecated use MARKDOWN "
"instead. Falling back to the default."
)
settings["MARKDOWN"] = DEFAULT_CONFIG["MARKDOWN"]
# LESS_GENERATOR -> Webassets plugin
# FILES_TO_COPY -> STATIC_PATHS, EXTRA_PATH_METADATA
for old, new, doc in [
("LESS_GENERATOR", "the Webassets plugin", None),
(
"FILES_TO_COPY",
"STATIC_PATHS and EXTRA_PATH_METADATA",
"https://github.com/getpelican/pelican/"
2024-06-25 11:33:28 +02:00
"blob/main/docs/settings.rst#path-metadata",
),
]:
if old in settings:
message = f"The {old} setting has been removed in favor of {new}"
if doc:
message += f", see {doc} for details"
logger.warning(message)
# PAGINATED_DIRECT_TEMPLATES -> PAGINATED_TEMPLATES
if "PAGINATED_DIRECT_TEMPLATES" in settings:
message = "The {} setting has been removed in favor of {}".format(
"PAGINATED_DIRECT_TEMPLATES", "PAGINATED_TEMPLATES"
)
logger.warning(message)
# set PAGINATED_TEMPLATES
if "PAGINATED_TEMPLATES" not in settings:
settings["PAGINATED_TEMPLATES"] = {
"tag": None,
"category": None,
"author": None,
}
for t in settings["PAGINATED_DIRECT_TEMPLATES"]:
if t not in settings["PAGINATED_TEMPLATES"]:
settings["PAGINATED_TEMPLATES"][t] = None
del settings["PAGINATED_DIRECT_TEMPLATES"]
# {SLUG,CATEGORY,TAG,AUTHOR}_SUBSTITUTIONS ->
# {SLUG,CATEGORY,TAG,AUTHOR}_REGEX_SUBSTITUTIONS
url_settings_url = "http://docs.getpelican.com/en/latest/settings.html#url-settings"
flavours = {"SLUG", "CATEGORY", "TAG", "AUTHOR"}
old_values = {
f: settings[f + "_SUBSTITUTIONS"]
for f in flavours
if f + "_SUBSTITUTIONS" in settings
}
new_values = {
f: settings[f + "_REGEX_SUBSTITUTIONS"]
for f in flavours
if f + "_REGEX_SUBSTITUTIONS" in settings
}
if old_values and new_values:
raise Exception(
"Setting both {new_key} and {old_key} (or variants thereof) is "
"not permitted. Please move to only setting {new_key}.".format(
old_key="SLUG_SUBSTITUTIONS", new_key="SLUG_REGEX_SUBSTITUTIONS"
)
)
if old_values:
message = (
"{} and variants thereof are deprecated and will be "
"removed in the future. Please use {} and variants thereof "
"instead. Check {}.".format(
"SLUG_SUBSTITUTIONS", "SLUG_REGEX_SUBSTITUTIONS", url_settings_url
)
)
logger.warning(message)
if old_values.get("SLUG"):
2024-05-30 09:05:36 -05:00
for f in ("CATEGORY", "TAG"):
if old_values.get(f):
old_values[f] = old_values["SLUG"] + old_values[f]
old_values["AUTHOR"] = old_values.get("AUTHOR", [])
for f in flavours:
if old_values.get(f) is not None:
regex_subs = []
# by default will replace non-alphanum characters
replace = True
for tpl in old_values[f]:
try:
src, dst, skip = tpl
if skip:
replace = False
except ValueError:
src, dst = tpl
regex_subs.append((re.escape(src), dst.replace("\\", r"\\")))
if replace:
regex_subs += [
(r"[^\w\s-]", ""),
(r"(?u)\A\s*", ""),
(r"(?u)\s*\Z", ""),
(r"[-\s]+", "-"),
]
else:
regex_subs += [
(r"(?u)\A\s*", ""),
(r"(?u)\s*\Z", ""),
]
settings[f + "_REGEX_SUBSTITUTIONS"] = regex_subs
settings.pop(f + "_SUBSTITUTIONS", None)
# `%s` -> '{slug}` or `{lang}` in FEED settings
for key in ["TRANSLATION_FEED_ATOM", "TRANSLATION_FEED_RSS"]:
2020-05-21 21:43:06 -06:00
if (
settings.get(key)
and not isinstance(settings[key], Path)
and "%s" in settings[key]
2020-05-21 21:43:06 -06:00
):
logger.warning("%%s usage in %s is deprecated, use {lang} instead.", key)
try:
settings[key] = _printf_s_to_format_field(settings[key], "lang")
except ValueError:
logger.warning(
"Failed to convert %%s to {lang} for %s. "
"Falling back to default.",
key,
)
settings[key] = DEFAULT_CONFIG[key]
for key in [
"AUTHOR_FEED_ATOM",
"AUTHOR_FEED_RSS",
"CATEGORY_FEED_ATOM",
"CATEGORY_FEED_RSS",
"TAG_FEED_ATOM",
"TAG_FEED_RSS",
]:
2020-05-21 21:43:06 -06:00
if (
settings.get(key)
and not isinstance(settings[key], Path)
and "%s" in settings[key]
2020-05-21 21:43:06 -06:00
):
logger.warning("%%s usage in %s is deprecated, use {slug} instead.", key)
try:
settings[key] = _printf_s_to_format_field(settings[key], "slug")
except ValueError:
logger.warning(
"Failed to convert %%s to {slug} for %s. "
"Falling back to default.",
key,
)
settings[key] = DEFAULT_CONFIG[key]
# CLEAN_URLS
if settings.get("CLEAN_URLS", False):
logger.warning(
"Found deprecated `CLEAN_URLS` in settings."
" Modifying the following settings for the"
" same behaviour."
)
settings["ARTICLE_URL"] = "{slug}/"
settings["ARTICLE_LANG_URL"] = "{slug}-{lang}/"
settings["PAGE_URL"] = "pages/{slug}/"
settings["PAGE_LANG_URL"] = "pages/{slug}-{lang}/"
for setting in ("ARTICLE_URL", "ARTICLE_LANG_URL", "PAGE_URL", "PAGE_LANG_URL"):
logger.warning("%s = '%s'", setting, settings[setting])
# AUTORELOAD_IGNORE_CACHE -> --ignore-cache
if settings.get("AUTORELOAD_IGNORE_CACHE"):
logger.warning(
"Found deprecated `AUTORELOAD_IGNORE_CACHE` in "
"settings. Use --ignore-cache instead."
)
settings.pop("AUTORELOAD_IGNORE_CACHE")
# ARTICLE_PERMALINK_STRUCTURE
if settings.get("ARTICLE_PERMALINK_STRUCTURE", False):
logger.warning(
"Found deprecated `ARTICLE_PERMALINK_STRUCTURE` in"
" settings. Modifying the following settings for"
" the same behaviour."
)
structure = settings["ARTICLE_PERMALINK_STRUCTURE"]
# Convert %(variable) into {variable}.
structure = re.sub(r"%\((\w+)\)s", r"{\g<1>}", structure)
# Convert %x into {date:%x} for strftime
structure = re.sub(r"(%[A-z])", r"{date:\g<1>}", structure)
# Strip a / prefix
structure = re.sub("^/", "", structure)
for setting in (
"ARTICLE_URL",
"ARTICLE_LANG_URL",
"PAGE_URL",
"PAGE_LANG_URL",
"DRAFT_URL",
"DRAFT_LANG_URL",
"ARTICLE_SAVE_AS",
"ARTICLE_LANG_SAVE_AS",
"DRAFT_SAVE_AS",
"DRAFT_LANG_SAVE_AS",
"PAGE_SAVE_AS",
"PAGE_LANG_SAVE_AS",
):
settings[setting] = os.path.join(structure, settings[setting])
logger.warning("%s = '%s'", setting, settings[setting])
# {,TAG,CATEGORY,TRANSLATION}_FEED -> {,TAG,CATEGORY,TRANSLATION}_FEED_ATOM
for new, old in [
("FEED", "FEED_ATOM"),
("TAG_FEED", "TAG_FEED_ATOM"),
("CATEGORY_FEED", "CATEGORY_FEED_ATOM"),
("TRANSLATION_FEED", "TRANSLATION_FEED_ATOM"),
]:
if settings.get(new, False):
logger.warning(
"Found deprecated `%(new)s` in settings. Modify %(new)s "
"to %(old)s in your settings and theme for the same "
"behavior. Temporarily setting %(old)s for backwards "
"compatibility.",
{"new": new, "old": old},
)
settings[old] = settings[new]
# Warn if removed WRITE_SELECTED is present
if "WRITE_SELECTED" in settings:
logger.warning(
"WRITE_SELECTED is present in settings but this functionality was removed. "
"It will have no effect."
)
return settings
def configure_settings(settings: Settings) -> Settings:
"""Provide optimizations, error checking, and warnings for the given
2013-03-10 20:11:36 -07:00
settings.
Also, specify the log messages to be ignored.
"""
if "PATH" not in settings or not os.path.isdir(settings["PATH"]):
raise Exception(
"You need to specify a path containing the content"
" (see pelican --help for more information)"
)
# specify the log messages to be ignored
log_filter = settings.get("LOG_FILTER", DEFAULT_CONFIG["LOG_FILTER"])
2015-06-16 09:25:09 +02:00
LimitFilter._ignore.update(set(log_filter))
2013-03-10 20:11:36 -07:00
# lookup the theme in "pelican/themes" if the given one doesn't exist
if not os.path.isdir(settings["THEME"]):
theme_path = os.path.join(
os.path.dirname(os.path.abspath(__file__)), "themes", settings["THEME"]
)
if os.path.exists(theme_path):
settings["THEME"] = theme_path
else:
raise Exception("Could not find the theme {}".format(settings["THEME"]))
2011-07-02 15:15:21 -05:00
# standardize strings to lowercase strings
for key in ["DEFAULT_LANG"]:
if key in settings:
settings[key] = settings[key].lower()
# set defaults for Jinja environment
settings = get_jinja_environment(settings)
# standardize strings to lists
for key in ["LOCALE"]:
if key in settings and isinstance(settings[key], str):
settings[key] = [settings[key]]
# check settings that must be a particular type
for key, types in [
("OUTPUT_SOURCES_EXTENSION", str),
("FILENAME_METADATA", str),
2015-06-16 09:25:09 +02:00
]:
if key in settings and not isinstance(settings[key], types):
value = settings.pop(key)
2015-06-16 09:25:09 +02:00
logger.warn(
"Detected misconfigured %s (%s), falling back to the default (%s)",
key,
value,
DEFAULT_CONFIG[key],
)
# try to set the different locales, fallback on the default.
locales = settings.get("LOCALE", DEFAULT_CONFIG["LOCALE"])
2011-05-31 12:44:40 +02:00
for locale_ in locales:
try:
locale.setlocale(locale.LC_ALL, str(locale_))
break # break if it is successful
except locale.Error:
pass
else:
logger.warning(
"Locale could not be set. Check the LOCALE setting, ensuring it "
"is valid and available on your system."
)
if "SITEURL" in settings:
# If SITEURL has a trailing slash, remove it and provide a warning
siteurl = settings["SITEURL"]
if siteurl.endswith("/"):
settings["SITEURL"] = siteurl[:-1]
logger.warning("Removed extraneous trailing slash from SITEURL.")
# If SITEURL is defined but FEED_DOMAIN isn't,
# set FEED_DOMAIN to SITEURL
if "FEED_DOMAIN" not in settings:
settings["FEED_DOMAIN"] = settings["SITEURL"]
2012-03-22 07:58:04 -07:00
# check content caching layer and warn of incompatibilities
if (
settings.get("CACHE_CONTENT", False)
and settings.get("CONTENT_CACHING_LAYER", "") == "generator"
and not settings.get("WITH_FUTURE_DATES", True)
):
logger.warning(
"WITH_FUTURE_DATES conflicts with CONTENT_CACHING_LAYER "
"set to 'generator', use 'reader' layer instead"
)
2012-03-22 07:58:04 -07:00
# Warn if feeds are generated with both SITEURL & FEED_DOMAIN undefined
feed_keys = [
"FEED_ATOM",
"FEED_RSS",
"FEED_ALL_ATOM",
"FEED_ALL_RSS",
"CATEGORY_FEED_ATOM",
"CATEGORY_FEED_RSS",
"AUTHOR_FEED_ATOM",
"AUTHOR_FEED_RSS",
"TAG_FEED_ATOM",
"TAG_FEED_RSS",
"TRANSLATION_FEED_ATOM",
"TRANSLATION_FEED_RSS",
]
if any(settings.get(k) for k in feed_keys):
if not settings.get("SITEURL"):
logger.warning(
"Feeds generated without SITEURL set properly may not be valid"
)
2012-03-22 07:58:04 -07:00
if "TIMEZONE" not in settings:
logger.warning(
"No timezone information specified in the settings. Assuming"
" your timezone is UTC for feed generation. Check "
"https://docs.getpelican.com/en/latest/settings.html#TIMEZONE "
"for more information"
)
# fix up pagination rules
from pelican.paginator import PaginationRule
pagination_rules = [
PaginationRule(*r)
for r in settings.get(
"PAGINATION_PATTERNS",
DEFAULT_CONFIG["PAGINATION_PATTERNS"],
)
]
settings["PAGINATION_PATTERNS"] = sorted(
pagination_rules,
key=lambda r: r[0],
)
2013-03-23 19:56:45 -07:00
# Save people from accidentally setting a string rather than a list
path_keys = (
"ARTICLE_EXCLUDES",
"DEFAULT_METADATA",
"DIRECT_TEMPLATES",
"THEME_TEMPLATES_OVERRIDES",
"FILES_TO_COPY",
"IGNORE_FILES",
"PAGINATED_DIRECT_TEMPLATES",
"PLUGINS",
"STATIC_EXCLUDES",
"STATIC_PATHS",
"THEME_STATIC_PATHS",
"ARTICLE_PATHS",
"PAGE_PATHS",
)
for PATH_KEY in filter(lambda k: k in settings, path_keys):
if isinstance(settings[PATH_KEY], str):
logger.warning(
"Detected misconfiguration with %s setting "
"(must be a list), falling back to the default",
PATH_KEY,
)
settings[PATH_KEY] = DEFAULT_CONFIG[PATH_KEY]
# Add {PAGE,ARTICLE}_PATHS to {ARTICLE,PAGE}_EXCLUDES
mutually_exclusive = ("ARTICLE", "PAGE")
for type_1, type_2 in [mutually_exclusive, mutually_exclusive[::-1]]:
try:
includes = settings[type_1 + "_PATHS"]
excludes = settings[type_2 + "_EXCLUDES"]
for path in includes:
if path not in excludes:
excludes.append(path)
except KeyError:
continue # setting not specified, nothing to do
2012-03-22 07:58:04 -07:00
return settings