diff --git a/pelican/settings.py b/pelican/settings.py index 59dc5922..dcc52460 100644 --- a/pelican/settings.py +++ b/pelican/settings.py @@ -68,26 +68,45 @@ _DEFAULT_CONFIG = {'PATH': None, def read_settings(filename=None): + if filename: + local_settings = get_settings_from_file(filename) + else: + local_settings = _DEFAULT_CONFIG + configured_settings = configure_settings(local_settings, None, filename) + return configured_settings + + +def get_settings_from_file(filename, default_settings=None): """Load a Python file into a dictionary. """ - context = _DEFAULT_CONFIG.copy() + if default_settings == None: + default_settings = _DEFAULT_CONFIG + context = default_settings.copy() if filename: tempdict = {} execfile(filename, tempdict) for key in tempdict: if key.isupper(): context[key] = tempdict[key] + return context - # Make the paths relative to the settings file + +def configure_settings(settings, default_settings=None, filename=None): + """Provide optimizations, error checking, and warnings for loaded settings""" + if default_settings is None: + default_settings = _DEFAULT_CONFIG + + # Make the paths relative to the settings file + if filename: for path in ['PATH', 'OUTPUT_PATH']: - if path in context: - if context[path] is not None and not isabs(context[path]): - context[path] = os.path.abspath(os.path.normpath( - os.path.join(os.path.dirname(filename), context[path])) + if path in settings: + if settings[path] is not None and not isabs(settings[path]): + settings[path] = os.path.abspath(os.path.normpath( + os.path.join(os.path.dirname(filename), settings[path])) ) # if locales is not a list, make it one - locales = context['LOCALE'] + locales = settings['LOCALE'] if isinstance(locales, basestring): locales = [locales] @@ -105,11 +124,20 @@ def read_settings(filename=None): else: log.warn("LOCALE option doesn't contain a correct value") - if not 'TIMEZONE' in context: + # If SITEURL is defined but FEED_DOMAIN isn't, set FEED_DOMAIN = SITEURL + if ('SITEURL' in settings) and (not 'FEED_DOMAIN' in settings): + settings['FEED_DOMAIN'] = settings['SITEURL'] + + # Warn if feeds are generated with both SITEURL & FEED_DOMAIN undefined + if (('FEED' in settings) or ('FEED_RSS' in settings)) and (not 'FEED_DOMAIN' in settings): + log.warn("Since feed URLs should always be absolute, you should specify " + "FEED_DOMAIN in your settings. (e.g., 'FEED_DOMAIN = " + "http://www.example.com')") + + if not 'TIMEZONE' in settings: log.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") - # set the locale - return context + return settings diff --git a/samples/pelican.conf.py b/samples/pelican.conf.py index de52cd8a..bffe57f6 100755 --- a/samples/pelican.conf.py +++ b/samples/pelican.conf.py @@ -11,7 +11,6 @@ REVERSE_CATEGORY_ORDER = True LOCALE = "" DEFAULT_PAGINATION = 4 -FEED_DOMAIN = SITEURL FEED_RSS = 'feeds/all.rss.xml' CATEGORY_FEED_RSS = 'feeds/%s.rss.xml' @@ -30,7 +29,7 @@ SOCIAL = (('twitter', 'http://twitter.com/ametaireau'), DEFAULT_METADATA = (('yeah', 'it is'),) # static paths will be copied under the same name -STATIC_PATHS = ["pictures",] +STATIC_PATHS = ["pictures", ] # A list of files to copy from the source to the destination FILES_TO_COPY = (('extra/robots.txt', 'robots.txt'),) @@ -38,4 +37,3 @@ FILES_TO_COPY = (('extra/robots.txt', 'robots.txt'),) # foobar will not be used, because it's not in caps. All configuration keys # have to be in caps foobar = "barbaz" - diff --git a/tests/test_settings.py b/tests/test_settings.py index 571f66a1..489c624a 100644 --- a/tests/test_settings.py +++ b/tests/test_settings.py @@ -5,12 +5,13 @@ except ImportError, e: from os.path import dirname, abspath, join -from pelican.settings import read_settings, _DEFAULT_CONFIG +from pelican.settings import read_settings, configure_settings, _DEFAULT_CONFIG -class TestSettingsFromFile(unittest2.TestCase): - """Providing a file, it should read it, replace the default values and - append new values to the settings, if any +class TestSettingsConfiguration(unittest2.TestCase): + """Provided a file, it should read it, replace the default values, + append new values to the settings (if any), and apply basic settings + optimizations. """ def setUp(self): self.PATH = abspath(dirname(__file__)) @@ -35,3 +36,15 @@ class TestSettingsFromFile(unittest2.TestCase): """providing no file should return the default values.""" settings = read_settings(None) self.assertDictEqual(settings, _DEFAULT_CONFIG) + + def test_configure_settings(self): + """Manipulations to settings should be applied correctly.""" + + # FEED_DOMAIN, if undefined, should default to SITEURL + settings = {'SITEURL': 'http://blog.notmyidea.org', 'LOCALE': ''} + configure_settings(settings) + self.assertEqual(settings['FEED_DOMAIN'], 'http://blog.notmyidea.org') + + settings = {'FEED_DOMAIN': 'http://feeds.example.com', 'LOCALE': ''} + configure_settings(settings) + self.assertEqual(settings['FEED_DOMAIN'], 'http://feeds.example.com')