2011-02-01 22:49:33 +00:00
|
|
|
# -*- coding: utf-8 -*-
|
2013-01-11 02:57:43 +01:00
|
|
|
from __future__ import unicode_literals, print_function
|
|
|
|
|
import six
|
|
|
|
|
|
2012-08-29 12:17:59 -07:00
|
|
|
import copy
|
2012-08-01 13:36:47 -04:00
|
|
|
import imp
|
|
|
|
|
import inspect
|
2010-10-30 00:56:40 +01:00
|
|
|
import os
|
2011-02-01 21:44:50 +00:00
|
|
|
import locale
|
2012-03-20 13:01:21 +00:00
|
|
|
import logging
|
|
|
|
|
|
|
|
|
|
from os.path import isabs
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
2010-10-30 00:56:40 +01:00
|
|
|
|
2011-05-31 12:44:40 +02:00
|
|
|
|
2011-01-13 00:46:10 +01:00
|
|
|
DEFAULT_THEME = os.sep.join([os.path.dirname(os.path.abspath(__file__)),
|
2010-10-30 16:47:59 +01:00
|
|
|
"themes/notmyidea"])
|
2012-03-23 09:04:57 +00:00
|
|
|
_DEFAULT_CONFIG = {'PATH': '.',
|
2012-03-06 00:29:56 +01:00
|
|
|
'ARTICLE_DIR': '',
|
|
|
|
|
'ARTICLE_EXCLUDES': ('pages',),
|
|
|
|
|
'PAGE_DIR': 'pages',
|
|
|
|
|
'PAGE_EXCLUDES': (),
|
2011-05-10 23:18:11 +01:00
|
|
|
'THEME': DEFAULT_THEME,
|
2010-10-30 00:56:40 +01:00
|
|
|
'OUTPUT_PATH': 'output/',
|
2010-10-31 00:08:16 +01:00
|
|
|
'MARKUP': ('rst', 'md'),
|
2012-03-09 16:21:38 +01:00
|
|
|
'STATIC_PATHS': ['images', ],
|
|
|
|
|
'THEME_STATIC_PATHS': ['static', ],
|
2012-10-25 16:49:24 +02:00
|
|
|
'FEED_ALL_ATOM': 'feeds/all.atom.xml',
|
2012-07-16 09:35:05 -07:00
|
|
|
'CATEGORY_FEED_ATOM': 'feeds/%s.atom.xml',
|
2012-10-22 16:34:55 +02:00
|
|
|
'TRANSLATION_FEED_ATOM': 'feeds/all-%s.atom.xml',
|
2011-08-02 23:29:34 +00:00
|
|
|
'FEED_MAX_ITEMS': '',
|
2012-07-14 17:05:04 -07:00
|
|
|
'SITEURL': '',
|
2010-10-30 00:56:40 +01:00
|
|
|
'SITENAME': 'A Pelican Blog',
|
2010-11-05 02:05:00 +00:00
|
|
|
'DISPLAY_PAGES_ON_MENU': True,
|
2010-12-02 03:22:24 +00:00
|
|
|
'PDF_GENERATOR': False,
|
2012-09-07 08:46:38 +02:00
|
|
|
'OUTPUT_SOURCES': False,
|
2012-09-28 14:59:05 +02:00
|
|
|
'OUTPUT_SOURCES_EXTENSION': '.text',
|
2012-09-23 10:04:51 +02:00
|
|
|
'USE_FOLDER_AS_CATEGORY': True,
|
2010-11-07 14:35:10 +00:00
|
|
|
'DEFAULT_CATEGORY': 'misc',
|
2011-11-26 23:23:19 +00:00
|
|
|
'WITH_FUTURE_DATES': True,
|
2010-11-18 03:33:57 +00:00
|
|
|
'CSS_FILE': 'main.css',
|
2012-07-18 11:18:48 -07:00
|
|
|
'NEWEST_FIRST_ARCHIVES': True,
|
2011-02-01 01:57:39 +00:00
|
|
|
'REVERSE_CATEGORY_ORDER': False,
|
2011-05-07 19:27:33 +01:00
|
|
|
'DELETE_OUTPUT_DIRECTORY': False,
|
2011-12-23 22:01:32 +00:00
|
|
|
'ARTICLE_URL': '{slug}.html',
|
|
|
|
|
'ARTICLE_SAVE_AS': '{slug}.html',
|
|
|
|
|
'ARTICLE_LANG_URL': '{slug}-{lang}.html',
|
|
|
|
|
'ARTICLE_LANG_SAVE_AS': '{slug}-{lang}.html',
|
|
|
|
|
'PAGE_URL': 'pages/{slug}.html',
|
|
|
|
|
'PAGE_SAVE_AS': 'pages/{slug}.html',
|
|
|
|
|
'PAGE_LANG_URL': 'pages/{slug}-{lang}.html',
|
|
|
|
|
'PAGE_LANG_SAVE_AS': 'pages/{slug}-{lang}.html',
|
2013-01-04 13:54:08 -05:00
|
|
|
'STATIC_URL': '{path}',
|
|
|
|
|
'STATIC_SAVE_AS': '{path}',
|
2012-04-30 19:43:09 +11:00
|
|
|
'CATEGORY_URL': 'category/{slug}.html',
|
|
|
|
|
'CATEGORY_SAVE_AS': 'category/{slug}.html',
|
2012-03-11 01:16:32 +01:00
|
|
|
'TAG_URL': 'tag/{slug}.html',
|
|
|
|
|
'TAG_SAVE_AS': 'tag/{slug}.html',
|
2013-01-11 02:57:43 +01:00
|
|
|
'AUTHOR_URL': 'author/{slug}.html',
|
|
|
|
|
'AUTHOR_SAVE_AS': 'author/{slug}.html',
|
2010-12-22 03:19:35 +03:00
|
|
|
'RELATIVE_URLS': True,
|
2010-12-20 22:50:54 +00:00
|
|
|
'DEFAULT_LANG': 'en',
|
2011-01-01 23:08:29 +03:00
|
|
|
'TAG_CLOUD_STEPS': 4,
|
|
|
|
|
'TAG_CLOUD_MAX_ITEMS': 100,
|
2013-03-03 20:12:31 -08:00
|
|
|
'DIRECT_TEMPLATES': ('index', 'tags', 'categories',
|
|
|
|
|
'archives'),
|
2012-11-28 00:29:30 +01:00
|
|
|
'EXTRA_TEMPLATES_PATHS': [],
|
2011-03-23 10:25:38 +03:00
|
|
|
'PAGINATED_DIRECT_TEMPLATES': ('index', ),
|
2010-12-25 17:26:24 +03:00
|
|
|
'PELICAN_CLASS': 'pelican.Pelican',
|
2011-02-01 21:44:50 +00:00
|
|
|
'DEFAULT_DATE_FORMAT': '%a %d %B %Y',
|
|
|
|
|
'DATE_FORMATS': {},
|
2010-12-29 13:21:21 +00:00
|
|
|
'JINJA_EXTENSIONS': [],
|
2013-03-10 20:11:36 -07:00
|
|
|
'LOCALE': '', # defaults to user locale
|
2011-12-22 13:56:36 +00:00
|
|
|
'DEFAULT_PAGINATION': False,
|
2011-02-14 16:24:54 +01:00
|
|
|
'DEFAULT_ORPHANS': 0,
|
2011-05-07 19:56:55 +01:00
|
|
|
'DEFAULT_METADATA': (),
|
2012-11-28 00:29:30 +01:00
|
|
|
'FILENAME_METADATA': '(?P<date>\d{4}-\d{2}-\d{2}).*',
|
2013-01-04 14:30:40 -05:00
|
|
|
'PATH_METADATA': '',
|
2011-05-07 22:46:56 +01:00
|
|
|
'FILES_TO_COPY': (),
|
2011-05-08 14:58:57 +01:00
|
|
|
'DEFAULT_STATUS': 'published',
|
2012-03-11 02:48:36 +01:00
|
|
|
'ARTICLE_PERMALINK_STRUCTURE': '',
|
|
|
|
|
'TYPOGRIFY': False,
|
2012-06-11 08:39:13 -04:00
|
|
|
'SUMMARY_MAX_LENGTH': 50,
|
2011-06-18 01:03:53 +02:00
|
|
|
'PLUGINS': [],
|
2012-12-19 16:26:00 +02:00
|
|
|
'TEMPLATE_PAGES': {},
|
|
|
|
|
'IGNORE_FILES': []
|
2011-05-10 23:18:11 +01:00
|
|
|
}
|
2010-10-30 00:56:40 +01:00
|
|
|
|
2012-03-09 16:21:38 +01:00
|
|
|
|
2013-01-04 10:50:09 -05:00
|
|
|
def read_settings(path=None, override=None):
|
|
|
|
|
if path:
|
|
|
|
|
local_settings = get_settings_from_file(path)
|
2012-10-16 01:35:35 +02:00
|
|
|
# Make the paths relative to the settings file
|
|
|
|
|
for p in ['PATH', 'OUTPUT_PATH', 'THEME']:
|
|
|
|
|
if p in local_settings and local_settings[p] is not None \
|
|
|
|
|
and not isabs(local_settings[p]):
|
|
|
|
|
absp = os.path.abspath(os.path.normpath(os.path.join(
|
2013-01-04 10:50:09 -05:00
|
|
|
os.path.dirname(path), local_settings[p])))
|
2013-01-03 12:19:27 -05:00
|
|
|
if p != 'THEME' or os.path.exists(absp):
|
2012-10-16 01:35:35 +02:00
|
|
|
local_settings[p] = absp
|
2012-03-22 07:58:04 -07:00
|
|
|
else:
|
2012-08-29 12:17:59 -07:00
|
|
|
local_settings = copy.deepcopy(_DEFAULT_CONFIG)
|
2012-10-16 01:35:35 +02:00
|
|
|
|
|
|
|
|
if override:
|
|
|
|
|
local_settings.update(override)
|
|
|
|
|
|
|
|
|
|
return configure_settings(local_settings)
|
2012-03-22 07:58:04 -07:00
|
|
|
|
|
|
|
|
|
2012-08-01 13:36:47 -04:00
|
|
|
def get_settings_from_module(module=None, default_settings=_DEFAULT_CONFIG):
|
2013-03-10 20:11:36 -07:00
|
|
|
"""Loads settings from a module, returns a dictionary."""
|
2012-08-01 13:36:47 -04:00
|
|
|
|
2012-08-29 12:17:59 -07:00
|
|
|
context = copy.deepcopy(default_settings)
|
2012-08-01 13:36:47 -04:00
|
|
|
if module is not None:
|
2012-10-16 01:35:35 +02:00
|
|
|
context.update(
|
|
|
|
|
(k, v) for k, v in inspect.getmembers(module) if k.isupper())
|
2012-03-22 07:58:04 -07:00
|
|
|
return context
|
|
|
|
|
|
2011-02-01 21:44:50 +00:00
|
|
|
|
2013-01-04 10:50:09 -05:00
|
|
|
def get_settings_from_file(path, default_settings=_DEFAULT_CONFIG):
|
2013-03-10 20:11:36 -07:00
|
|
|
"""Loads settings from a file path, returning a dict."""
|
2012-08-01 13:36:47 -04:00
|
|
|
|
2013-01-04 10:50:09 -05:00
|
|
|
name = os.path.basename(path).rpartition('.')[0]
|
|
|
|
|
module = imp.load_source(name, path)
|
2012-08-01 13:36:47 -04:00
|
|
|
return get_settings_from_module(module, default_settings=default_settings)
|
|
|
|
|
|
|
|
|
|
|
2012-10-16 01:35:35 +02:00
|
|
|
def configure_settings(settings):
|
2013-03-10 20:11:36 -07:00
|
|
|
"""Provide optimizations, error checking and warnings for the given
|
|
|
|
|
settings.
|
|
|
|
|
|
2012-10-16 01:35:35 +02:00
|
|
|
"""
|
|
|
|
|
if not 'PATH' in settings or not os.path.isdir(settings['PATH']):
|
|
|
|
|
raise Exception('You need to specify a path containing the content'
|
2012-10-24 23:34:38 +02:00
|
|
|
' (see pelican --help for more information)')
|
2012-10-16 01:35:35 +02:00
|
|
|
|
2013-03-10 20:11:36 -07:00
|
|
|
# lookup the theme in "pelican/themes" if the given one doesn't exist
|
2012-10-16 01:35:35 +02:00
|
|
|
if not os.path.isdir(settings['THEME']):
|
|
|
|
|
theme_path = os.sep.join([os.path.dirname(
|
|
|
|
|
os.path.abspath(__file__)), "themes/%s" % settings['THEME']])
|
|
|
|
|
if os.path.exists(theme_path):
|
|
|
|
|
settings['THEME'] = theme_path
|
|
|
|
|
else:
|
|
|
|
|
raise Exception("Impossible to find the theme %s"
|
2012-10-24 23:34:38 +02:00
|
|
|
% settings['THEME'])
|
2011-07-02 15:15:21 -05:00
|
|
|
|
2011-05-19 17:28:45 +01:00
|
|
|
# if locales is not a list, make it one
|
2012-03-22 07:58:04 -07:00
|
|
|
locales = settings['LOCALE']
|
2011-05-19 17:28:45 +01:00
|
|
|
|
2013-01-11 02:57:43 +01:00
|
|
|
if isinstance(locales, six.string_types):
|
2011-05-19 18:00:17 +01:00
|
|
|
locales = [locales]
|
2011-05-19 17:28:45 +01:00
|
|
|
|
|
|
|
|
# try to set the different locales, fallback on the default.
|
2011-05-31 12:44:40 +02:00
|
|
|
if not locales:
|
|
|
|
|
locales = _DEFAULT_CONFIG['LOCALE']
|
|
|
|
|
|
2011-05-19 18:10:21 +01:00
|
|
|
for locale_ in locales:
|
2011-05-19 17:28:45 +01:00
|
|
|
try:
|
2013-01-11 02:57:43 +01:00
|
|
|
locale.setlocale(locale.LC_ALL, str(locale_))
|
2012-08-29 12:17:59 -07:00
|
|
|
break # break if it is successful
|
2011-05-19 17:28:45 +01:00
|
|
|
except locale.Error:
|
|
|
|
|
pass
|
2011-05-19 18:10:21 +01:00
|
|
|
else:
|
2012-03-20 13:01:21 +00:00
|
|
|
logger.warn("LOCALE option doesn't contain a correct value")
|
2011-05-19 17:28:45 +01:00
|
|
|
|
2012-03-23 07:16:23 -07:00
|
|
|
if ('SITEURL' in settings):
|
|
|
|
|
# If SITEURL has a trailing slash, remove it and provide a warning
|
|
|
|
|
siteurl = settings['SITEURL']
|
2012-04-18 07:16:51 -07:00
|
|
|
if (siteurl.endswith('/')):
|
2012-03-23 07:16:23 -07:00
|
|
|
settings['SITEURL'] = siteurl[:-1]
|
|
|
|
|
logger.warn("Removed extraneous trailing slash from SITEURL.")
|
2013-03-03 20:12:31 -08:00
|
|
|
# If SITEURL is defined but FEED_DOMAIN isn't,
|
|
|
|
|
# set FEED_DOMAIN to SITEURL
|
2012-03-23 07:16:23 -07:00
|
|
|
if not 'FEED_DOMAIN' in settings:
|
|
|
|
|
settings['FEED_DOMAIN'] = settings['SITEURL']
|
2012-03-22 07:58:04 -07:00
|
|
|
|
|
|
|
|
# Warn if feeds are generated with both SITEURL & FEED_DOMAIN undefined
|
2012-10-31 12:49:17 +01:00
|
|
|
feed_keys = ['FEED_ATOM', 'FEED_RSS',
|
|
|
|
|
'FEED_ALL_ATOM', 'FEED_ALL_RSS',
|
|
|
|
|
'CATEGORY_FEED_ATOM', 'CATEGORY_FEED_RSS',
|
|
|
|
|
'TAG_FEED_ATOM', 'TAG_FEED_RSS',
|
|
|
|
|
'TRANSLATION_FEED_ATOM', 'TRANSLATION_FEED_RSS',
|
2012-10-25 16:50:27 +02:00
|
|
|
]
|
|
|
|
|
|
2012-11-07 20:52:59 +01:00
|
|
|
if any(settings.get(k) for k in feed_keys):
|
|
|
|
|
if not settings.get('FEED_DOMAIN'):
|
2013-03-03 20:12:31 -08:00
|
|
|
logger.warn(
|
|
|
|
|
"Since feed URLs should always be absolute, you should specify"
|
|
|
|
|
" FEED_DOMAIN in your settings. (e.g., 'FEED_DOMAIN = "
|
|
|
|
|
"http://www.example.com')")
|
2012-11-07 20:52:59 +01:00
|
|
|
|
|
|
|
|
if not settings.get('SITEURL'):
|
2013-03-03 20:12:31 -08:00
|
|
|
logger.warn('Feeds generated without SITEURL set properly may not'
|
|
|
|
|
' be valid')
|
2012-03-22 07:58:04 -07:00
|
|
|
|
|
|
|
|
if not 'TIMEZONE' in settings:
|
2013-03-03 20:12:31 -08:00
|
|
|
logger.warn(
|
|
|
|
|
'No timezone information specified in the settings. Assuming'
|
|
|
|
|
' your timezone is UTC for feed generation. Check '
|
|
|
|
|
'http://docs.notmyidea.org/alexis/pelican/settings.html#timezone '
|
|
|
|
|
'for more information')
|
2011-08-18 13:58:04 +02:00
|
|
|
|
2012-10-24 23:34:38 +02:00
|
|
|
if 'LESS_GENERATOR' in settings:
|
2013-03-03 20:12:31 -08:00
|
|
|
logger.warn(
|
|
|
|
|
'The LESS_GENERATOR setting has been removed in favor '
|
|
|
|
|
'of the Webassets plugin')
|
2012-05-07 17:11:57 +02:00
|
|
|
|
2012-09-28 14:59:05 +02:00
|
|
|
if 'OUTPUT_SOURCES_EXTENSION' in settings:
|
2013-03-03 20:12:31 -08:00
|
|
|
if not isinstance(settings['OUTPUT_SOURCES_EXTENSION'],
|
|
|
|
|
six.string_types):
|
|
|
|
|
settings['OUTPUT_SOURCES_EXTENSION'] = (
|
|
|
|
|
_DEFAULT_CONFIG['OUTPUT_SOURCES_EXTENSION'])
|
|
|
|
|
logger.warn(
|
|
|
|
|
'Detected misconfiguration with OUTPUT_SOURCES_EXTENSION, '
|
|
|
|
|
'falling back to the default extension ' +
|
|
|
|
|
_DEFAULT_CONFIG['OUTPUT_SOURCES_EXTENSION'])
|
2012-09-28 14:59:05 +02:00
|
|
|
|
2012-11-28 00:29:30 +01:00
|
|
|
filename_metadata = settings.get('FILENAME_METADATA')
|
2013-03-03 20:12:31 -08:00
|
|
|
if filename_metadata and not isinstance(filename_metadata,
|
|
|
|
|
six.string_types):
|
|
|
|
|
logger.error(
|
|
|
|
|
'Detected misconfiguration with FILENAME_METADATA '
|
|
|
|
|
'setting (must be string or compiled pattern), falling '
|
|
|
|
|
'back to the default')
|
|
|
|
|
settings['FILENAME_METADATA'] = (
|
|
|
|
|
_DEFAULT_CONFIG['FILENAME_METADATA'])
|
2012-11-28 00:29:30 +01:00
|
|
|
|
2012-03-22 07:58:04 -07:00
|
|
|
return settings
|