diff --git a/pelican/__init__.py b/pelican/__init__.py index 6e9e676b..7f406c4f 100644 --- a/pelican/__init__.py +++ b/pelican/__init__.py @@ -154,7 +154,7 @@ class Pelican(object): context = self.settings.copy() context['filenames'] = {} # share the dict between all the generators - context['localsiteurl'] = self.settings.get('SITEURL') # share + context['localsiteurl'] = self.settings['SITEURL'] # share generators = [ cls( context, @@ -309,7 +309,7 @@ def get_instance(args): settings = read_settings(config_file, override=get_config(args)) - cls = settings.get('PELICAN_CLASS') + cls = settings['PELICAN_CLASS'] if isinstance(cls, six.string_types): module, cls_name = cls.rsplit('.', 1) module = __import__(module) diff --git a/pelican/contents.py b/pelican/contents.py index fec8af14..5f2e66b0 100644 --- a/pelican/contents.py +++ b/pelican/contents.py @@ -14,7 +14,7 @@ from datetime import datetime from pelican import signals -from pelican.settings import _DEFAULT_CONFIG +from pelican.settings import DEFAULT_CONFIG from pelican.utils import (slugify, truncate_html_words, memoized, strftime, python_2_unicode_compatible, deprecated_attribute, path_to_url) @@ -44,14 +44,14 @@ class Content(object): if metadata is None: metadata = {} if settings is None: - settings = copy.deepcopy(_DEFAULT_CONFIG) + settings = copy.deepcopy(DEFAULT_CONFIG) self.settings = settings self._content = content self._context = context self.translations = [] - local_metadata = dict(settings.get('DEFAULT_METADATA', ())) + local_metadata = dict(settings['DEFAULT_METADATA']) local_metadata.update(metadata) # set metadata as attributes diff --git a/pelican/generators.py b/pelican/generators.py index f2fa0e33..75b61df2 100644 --- a/pelican/generators.py +++ b/pelican/generators.py @@ -47,7 +47,7 @@ class Generator(object): self._templates_path = [] self._templates_path.append(os.path.expanduser( os.path.join(self.theme, 'templates'))) - self._templates_path += self.settings.get('EXTRA_TEMPLATES_PATHS', []) + self._templates_path += self.settings['EXTRA_TEMPLATES_PATHS'] theme_path = os.path.dirname(os.path.abspath(__file__)) @@ -60,7 +60,7 @@ class Generator(object): simple_loader, # implicit inheritance PrefixLoader({'!simple': simple_loader}) # explicit one ]), - extensions=self.settings.get('JINJA_EXTENSIONS', []), + extensions=self.settings['JINJA_EXTENSIONS'], ) logger.debug('template list: {0}'.format(self.env.list_templates())) @@ -69,7 +69,7 @@ class Generator(object): self.env.filters.update({'strftime': DateFormatter()}) # get custom Jinja filters from user settings - custom_filters = self.settings.get('JINJA_FILTERS', {}) + custom_filters = self.settings['JINJA_FILTERS'] self.env.filters.update(custom_filters) signals.generator_init.send(self) @@ -163,7 +163,7 @@ class TemplatePagesGenerator(Generator): self.env.loader.loaders.insert(0, _FileLoader(source, self.path)) try: template = self.env.get_template(source) - rurls = self.settings.get('RELATIVE_URLS') + rurls = self.settings['RELATIVE_URLS'] writer.write_file(dest, template, self.context, rurls) finally: del self.env.loader.loaders[0] @@ -283,9 +283,9 @@ class ArticlesGenerator(Generator): dates=archive, blog=True) period_save_as = { - 'year' : self.settings.get('YEAR_ARCHIVE_SAVE_AS'), - 'month': self.settings.get('MONTH_ARCHIVE_SAVE_AS'), - 'day' : self.settings.get('DAY_ARCHIVE_SAVE_AS') + 'year' : self.settings['YEAR_ARCHIVE_SAVE_AS'], + 'month': self.settings['MONTH_ARCHIVE_SAVE_AS'], + 'day' : self.settings['DAY_ARCHIVE_SAVE_AS'], } period_date_key = { @@ -302,8 +302,8 @@ class ArticlesGenerator(Generator): def generate_direct_templates(self, write): """Generate direct templates pages""" - PAGINATED_TEMPLATES = self.settings.get('PAGINATED_DIRECT_TEMPLATES') - for template in self.settings.get('DIRECT_TEMPLATES'): + PAGINATED_TEMPLATES = self.settings['PAGINATED_DIRECT_TEMPLATES'] + for template in self.settings['DIRECT_TEMPLATES']: paginated = {} if template in PAGINATED_TEMPLATES: paginated = {'articles': self.articles, 'dates': self.dates} @@ -358,7 +358,7 @@ class ArticlesGenerator(Generator): def generate_pages(self, writer): """Generate the pages on the disk""" write = partial(writer.write_file, - relative_urls=self.settings.get('RELATIVE_URLS')) + relative_urls=self.settings['RELATIVE_URLS']) # to minimize the number of relative path stuff modification # in writer, articles pass first @@ -546,7 +546,7 @@ class PagesGenerator(Generator): self.hidden_translations, self.hidden_pages): writer.write_file(page.save_as, self.get_template(page.template), self.context, page=page, - relative_urls=self.settings.get('RELATIVE_URLS')) + relative_urls=self.settings['RELATIVE_URLS']) class StaticGenerator(Generator): @@ -613,14 +613,8 @@ class PdfGenerator(Generator): super(PdfGenerator, self).__init__(*args, **kwargs) try: from rst2pdf.createpdf import RstToPdf - if 'PDF_STYLE_PATH' in self.settings.keys(): - pdf_style_path = os.path.join(self.settings['PDF_STYLE_PATH']) - else: - pdf_style_path = '' - - if 'PDF_STYLE' in self.settings.keys(): - pdf_style = self.settings.get('PDF_STYLE', 'twelvepoint') - + pdf_style_path = os.path.join(self.settings['PDF_STYLE_PATH']) + pdf_style = self.settings['PDF_STYLE'] self.pdfcreator = RstToPdf(breakside=0, stylesheets=[pdf_style], style_path=[pdf_style_path]) diff --git a/pelican/readers.py b/pelican/readers.py index b5fed611..816464ef 100644 --- a/pelican/readers.py +++ b/pelican/readers.py @@ -157,12 +157,10 @@ class RstReader(Reader): class MarkdownReader(Reader): enabled = bool(Markdown) file_extensions = ['md', 'markdown', 'mkd', 'mdown'] - default_extensions = ['codehilite(css_class=highlight)', 'extra'] def __init__(self, *args, **kwargs): super(MarkdownReader, self).__init__(*args, **kwargs) - self.extensions = self.settings.get('MD_EXTENSIONS', - self.default_extensions) + self.extensions = self.settings['MD_EXTENSIONS'] self.extensions.append('meta') self._md = Markdown(extensions=self.extensions) @@ -309,7 +307,7 @@ class AsciiDocReader(Reader): content = StringIO() ad = AsciiDocAPI() - options = self.settings.get('ASCIIDOC_OPTIONS', []) + options = self.settings['ASCIIDOC_OPTIONS'] if isinstance(options, (str, unicode)): options = [m.strip() for m in options.split(',')] options = self.default_options + options @@ -362,7 +360,7 @@ def read_file(path, fmt=None, settings=None): metadata.update(reader_metadata) # eventually filter the content with typogrify if asked so - if content and settings and settings.get('TYPOGRIFY'): + if content and settings and settings['TYPOGRIFY']: from typogrify.filters import typogrify content = typogrify(content) metadata['title'] = typogrify(metadata['title']) diff --git a/pelican/settings.py b/pelican/settings.py index 091999a7..34a2b42a 100644 --- a/pelican/settings.py +++ b/pelican/settings.py @@ -25,84 +25,86 @@ logger = logging.getLogger(__name__) DEFAULT_THEME = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'themes', 'notmyidea') -_DEFAULT_CONFIG = {'PATH': os.curdir, - 'ARTICLE_DIR': '', - 'ARTICLE_EXCLUDES': ('pages',), - 'PAGE_DIR': 'pages', - 'PAGE_EXCLUDES': (), - 'THEME': DEFAULT_THEME, - 'OUTPUT_PATH': 'output', - 'MARKUP': ('rst', 'md'), - 'STATIC_PATHS': ['images', ], - 'THEME_STATIC_PATHS': ['static', ], - 'FEED_ALL_ATOM': os.path.join('feeds', 'all.atom.xml'), - 'CATEGORY_FEED_ATOM': os.path.join('feeds', '%s.atom.xml'), - 'TRANSLATION_FEED_ATOM': os.path.join( - 'feeds', 'all-%s.atom.xml'), - 'FEED_MAX_ITEMS': '', - 'SITEURL': '', - 'SITENAME': 'A Pelican Blog', - 'DISPLAY_PAGES_ON_MENU': True, - 'DISPLAY_CATEGORIES_ON_MENU': True, - 'PDF_GENERATOR': False, - '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, - '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': os.path.join('pages', '{slug}.html'), - 'PAGE_LANG_URL': 'pages/{slug}-{lang}.html', - 'PAGE_LANG_SAVE_AS': os.path.join( - 'pages', '{slug}-{lang}.html'), - 'STATIC_URL': '{path}', - 'STATIC_SAVE_AS': '{path}', - 'CATEGORY_URL': 'category/{slug}.html', - 'CATEGORY_SAVE_AS': os.path.join('category', '{slug}.html'), - 'TAG_URL': 'tag/{slug}.html', - 'TAG_SAVE_AS': os.path.join('tag', '{slug}.html'), - 'AUTHOR_URL': 'author/{slug}.html', - 'AUTHOR_SAVE_AS': os.path.join('author', '{slug}.html'), - 'YEAR_ARCHIVE_SAVE_AS': False, - 'MONTH_ARCHIVE_SAVE_AS': False, - 'DAY_ARCHIVE_SAVE_AS': False, - 'RELATIVE_URLS': False, - 'DEFAULT_LANG': 'en', - 'TAG_CLOUD_STEPS': 4, - 'TAG_CLOUD_MAX_ITEMS': 100, - 'DIRECT_TEMPLATES': ('index', 'tags', 'categories', - 'archives'), - 'EXTRA_TEMPLATES_PATHS': [], - 'PAGINATED_DIRECT_TEMPLATES': ('index', ), - 'PELICAN_CLASS': 'pelican.Pelican', - 'DEFAULT_DATE_FORMAT': '%a %d %B %Y', - 'DATE_FORMATS': {}, - 'JINJA_EXTENSIONS': [], - 'LOCALE': '', # defaults to user locale - 'DEFAULT_PAGINATION': False, - 'DEFAULT_ORPHANS': 0, - 'DEFAULT_METADATA': (), - 'FILENAME_METADATA': '(?P\d{4}-\d{2}-\d{2}).*', - 'PATH_METADATA': '', - 'FILES_TO_COPY': (), - 'DEFAULT_STATUS': 'published', - 'ARTICLE_PERMALINK_STRUCTURE': '', - 'TYPOGRIFY': False, - 'SUMMARY_MAX_LENGTH': 50, - 'PLUGIN_PATH': '', - 'PLUGINS': [], - 'TEMPLATE_PAGES': {}, - 'IGNORE_FILES': ['.#*'] - } - +DEFAULT_CONFIG = { + 'PATH': os.curdir, + 'ARTICLE_DIR': '', + 'ARTICLE_EXCLUDES': ('pages',), + 'PAGE_DIR': 'pages', + 'PAGE_EXCLUDES': (), + 'THEME': DEFAULT_THEME, + 'OUTPUT_PATH': 'output', + 'MARKUP': ('rst', 'md'), + 'STATIC_PATHS': ['images', ], + 'THEME_STATIC_PATHS': ['static', ], + 'FEED_ALL_ATOM': os.path.join('feeds', 'all.atom.xml'), + 'CATEGORY_FEED_ATOM': os.path.join('feeds', '%s.atom.xml'), + 'TRANSLATION_FEED_ATOM': os.path.join('feeds', 'all-%s.atom.xml'), + 'FEED_MAX_ITEMS': '', + 'SITEURL': '', + 'SITENAME': 'A Pelican Blog', + 'DISPLAY_PAGES_ON_MENU': True, + 'DISPLAY_CATEGORIES_ON_MENU': True, + 'PDF_GENERATOR': False, + '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, + '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': os.path.join('pages', '{slug}.html'), + 'PAGE_LANG_URL': 'pages/{slug}-{lang}.html', + 'PAGE_LANG_SAVE_AS': os.path.join('pages', '{slug}-{lang}.html'), + 'STATIC_URL': '{path}', + 'STATIC_SAVE_AS': '{path}', + 'PDF_STYLE_PATH': '', + 'PDF_STYLE': 'twelvepoint', + 'CATEGORY_URL': 'category/{slug}.html', + 'CATEGORY_SAVE_AS': os.path.join('category', '{slug}.html'), + 'TAG_URL': 'tag/{slug}.html', + 'TAG_SAVE_AS': os.path.join('tag', '{slug}.html'), + 'AUTHOR_URL': 'author/{slug}.html', + 'AUTHOR_SAVE_AS': os.path.join('author', '{slug}.html'), + 'YEAR_ARCHIVE_SAVE_AS': False, + 'MONTH_ARCHIVE_SAVE_AS': False, + 'DAY_ARCHIVE_SAVE_AS': False, + 'RELATIVE_URLS': False, + 'DEFAULT_LANG': 'en', + 'TAG_CLOUD_STEPS': 4, + 'TAG_CLOUD_MAX_ITEMS': 100, + 'DIRECT_TEMPLATES': ('index', 'tags', 'categories', 'archives'), + 'EXTRA_TEMPLATES_PATHS': [], + 'PAGINATED_DIRECT_TEMPLATES': ('index', ), + 'PELICAN_CLASS': 'pelican.Pelican', + 'DEFAULT_DATE_FORMAT': '%a %d %B %Y', + 'DATE_FORMATS': {}, + 'ASCIIDOC_OPTIONS': [], + 'MD_EXTENSIONS': ['codehilite(css_class=highlight)', 'extra'], + 'JINJA_EXTENSIONS': [], + 'JINJA_FILTERS': {}, + 'LOCALE': [], # defaults to user locale + 'DEFAULT_PAGINATION': False, + 'DEFAULT_ORPHANS': 0, + 'DEFAULT_METADATA': (), + 'FILENAME_METADATA': '(?P\d{4}-\d{2}-\d{2}).*', + 'PATH_METADATA': '', + 'FILES_TO_COPY': (), + 'DEFAULT_STATUS': 'published', + 'ARTICLE_PERMALINK_STRUCTURE': '', + 'TYPOGRIFY': False, + 'SUMMARY_MAX_LENGTH': 50, + 'PLUGIN_PATH': '', + 'PLUGINS': [], + 'TEMPLATE_PAGES': {}, + 'IGNORE_FILES': ['.#*'], + } def read_settings(path=None, override=None): if path: @@ -116,7 +118,7 @@ def read_settings(path=None, override=None): if p not in ('THEME', 'PLUGIN_PATH') or os.path.exists(absp): local_settings[p] = absp else: - local_settings = copy.deepcopy(_DEFAULT_CONFIG) + local_settings = copy.deepcopy(DEFAULT_CONFIG) if override: local_settings.update(override) @@ -124,7 +126,7 @@ def read_settings(path=None, override=None): return configure_settings(local_settings) -def get_settings_from_module(module=None, default_settings=_DEFAULT_CONFIG): +def get_settings_from_module(module=None, default_settings=DEFAULT_CONFIG): """Loads settings from a module, returns a dictionary.""" context = copy.deepcopy(default_settings) @@ -134,7 +136,7 @@ def get_settings_from_module(module=None, default_settings=_DEFAULT_CONFIG): return context -def get_settings_from_file(path, default_settings=_DEFAULT_CONFIG): +def get_settings_from_file(path, default_settings=DEFAULT_CONFIG): """Loads settings from a file path, returning a dict.""" name, ext = os.path.splitext(os.path.basename(path)) @@ -163,15 +165,34 @@ def configure_settings(settings): raise Exception("Could not find the theme %s" % settings['THEME']) - # if locales is not a list, make it one - locales = settings['LOCALE'] + # standardize strings to lowercase strings + for key in [ + 'DEFAULT_LANG', + ]: + if key in settings: + settings[key] = settings[key].lower() - if isinstance(locales, six.string_types): - locales = [locales] + # standardize strings to lists + for key in [ + 'LOCALE', + ]: + if key in settings and isinstance(settings[key], six.string_types): + settings[key] = [settings[key]] + + # check settings that must be a particular type + for key, types in [ + ('OUTPUT_SOURCES_EXTENSION', six.string_types), + ('FILENAME_METADATA', six.string_types), + ]: + if key in settings and not isinstance(settings[key], types): + value = settings.pop(key) + logger.warn( + 'Detected misconfigured {} ({}), ' + 'falling back to the default ({})'.format( + key, value, DEFAULT_CONFIG[key])) # try to set the different locales, fallback on the default. - if not locales: - locales = _DEFAULT_CONFIG['LOCALE'] + locales = settings.get('LOCALE', DEFAULT_CONFIG['LOCALE']) for locale_ in locales: try: @@ -213,31 +234,6 @@ def configure_settings(settings): 'http://docs.getpelican.com/en/latest/settings.html#timezone ' 'for more information') - if 'LESS_GENERATOR' in settings: - logger.warning( - 'The LESS_GENERATOR setting has been removed in favor ' - 'of the Webassets plugin') - - if 'OUTPUT_SOURCES_EXTENSION' in settings: - if not isinstance(settings['OUTPUT_SOURCES_EXTENSION'], - six.string_types): - settings['OUTPUT_SOURCES_EXTENSION'] = ( - _DEFAULT_CONFIG['OUTPUT_SOURCES_EXTENSION']) - logger.warning( - 'Detected misconfiguration with OUTPUT_SOURCES_EXTENSION, ' - 'falling back to the default extension ' + - _DEFAULT_CONFIG['OUTPUT_SOURCES_EXTENSION']) - - filename_metadata = settings.get('FILENAME_METADATA') - 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']) - # Save people from accidentally setting a string rather than a list path_keys = ( 'ARTICLE_EXCLUDES', @@ -257,6 +253,15 @@ def configure_settings(settings): 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] + settings[PATH_KEY] = DEFAULT_CONFIG[PATH_KEY] + + for old,new,doc in [ + ('LESS_GENERATOR', 'the Webassets plugin', None), + ]: + if old in settings: + message = 'The {} setting has been removed in favor of {}' + if doc: + message += ', see {} for details' + logger.warning(message) return settings diff --git a/pelican/tests/support.py b/pelican/tests/support.py index c02a3e34..a4fd2c35 100644 --- a/pelican/tests/support.py +++ b/pelican/tests/support.py @@ -18,7 +18,7 @@ from tempfile import mkdtemp from shutil import rmtree from pelican.contents import Article -from pelican.settings import _DEFAULT_CONFIG +from pelican.settings import DEFAULT_CONFIG @contextmanager @@ -161,10 +161,14 @@ def locale_available(locale_): return True -def get_settings(): - settings = _DEFAULT_CONFIG.copy() - settings['DIRECT_TEMPLATES'] = ['archives'] - settings['filenames'] = {} +def get_settings(**kwargs): + """Provide tweaked setting dictionaries for testing + + Set keyword arguments to override specific settings. + """ + settings = DEFAULT_CONFIG.copy() + for key,value in kwargs.items(): + settings[key] = value return settings diff --git a/pelican/tests/test_contents.py b/pelican/tests/test_contents.py index 0ec6bf21..c081639d 100644 --- a/pelican/tests/test_contents.py +++ b/pelican/tests/test_contents.py @@ -4,10 +4,10 @@ from __future__ import unicode_literals from datetime import datetime from sys import platform -from .support import unittest +from .support import unittest, get_settings from pelican.contents import Page, Article, URLWrapper -from pelican.settings import _DEFAULT_CONFIG +from pelican.settings import DEFAULT_CONFIG from pelican.utils import truncate_html_words from pelican.signals import content_object_init from jinja2.utils import generate_lorem_ipsum @@ -62,7 +62,7 @@ class TestPage(unittest.TestCase): # If a :SUMMARY_MAX_LENGTH: is set, and there is no other summary, # generated summary should not exceed the given length. page_kwargs = self._copy_page_kwargs() - settings = _DEFAULT_CONFIG.copy() + settings = get_settings() page_kwargs['settings'] = settings del page_kwargs['metadata']['summary'] settings['SUMMARY_MAX_LENGTH'] = None @@ -83,7 +83,7 @@ class TestPage(unittest.TestCase): def test_defaultlang(self): # If no lang is given, default to the default one. page = Page(**self.page_kwargs) - self.assertEqual(page.lang, _DEFAULT_CONFIG['DEFAULT_LANG']) + self.assertEqual(page.lang, DEFAULT_CONFIG['DEFAULT_LANG']) # it is possible to specify the lang in the metadata infos self.page_kwargs['metadata'].update({'lang': 'fr', }) @@ -108,8 +108,7 @@ class TestPage(unittest.TestCase): page = Page(**self.page_kwargs) self.assertIn('summary', page.url_format.keys()) page.metadata['directory'] = 'test-dir' - page.settings = _DEFAULT_CONFIG.copy() - page.settings['PAGE_SAVE_AS'] = '{directory}/{slug}' + page.settings = get_settings(PAGE_SAVE_AS='{directory}/{slug}') self.assertEqual(page.save_as, 'test-dir/foo-bar') def test_datetime(self): @@ -123,10 +122,9 @@ class TestPage(unittest.TestCase): page = Page(**page_kwargs) self.assertEqual(page.locale_date, - dt.strftime(_DEFAULT_CONFIG['DEFAULT_DATE_FORMAT'])) + dt.strftime(DEFAULT_CONFIG['DEFAULT_DATE_FORMAT'])) - page_kwargs['settings'] = dict([(x, _DEFAULT_CONFIG[x]) for x in - _DEFAULT_CONFIG]) + page_kwargs['settings'] = get_settings() # I doubt this can work on all platforms ... if platform == "win32": diff --git a/pelican/tests/test_generators.py b/pelican/tests/test_generators.py index fa57322d..e3b8e20a 100644 --- a/pelican/tests/test_generators.py +++ b/pelican/tests/test_generators.py @@ -11,7 +11,7 @@ from shutil import rmtree from pelican.generators import (ArticlesGenerator, PagesGenerator, TemplatePagesGenerator) from pelican.writers import Writer -from pelican.settings import _DEFAULT_CONFIG +from pelican.settings import DEFAULT_CONFIG from pelican.tests.support import unittest, get_settings CUR_DIR = os.path.dirname(__file__) @@ -29,7 +29,7 @@ class TestArticlesGenerator(unittest.TestCase): for each test. """ if self.generator is None: - settings = get_settings() + settings = get_settings(filenames={}) settings['ARTICLE_DIR'] = 'content' settings['DEFAULT_CATEGORY'] = 'Default' settings['DEFAULT_DATE'] = (1970, 1, 1) @@ -53,16 +53,16 @@ class TestArticlesGenerator(unittest.TestCase): def test_generate_feeds(self): settings = get_settings() - generator = ArticlesGenerator(settings, - {'FEED_ALL_ATOM': settings['FEED_ALL_ATOM']}, None, + generator = ArticlesGenerator(settings, settings, None, settings['THEME'], None, settings['MARKUP']) writer = MagicMock() generator.generate_feeds(writer) writer.write_feed.assert_called_with([], settings, 'feeds/all.atom.xml') - generator = ArticlesGenerator(settings, {'FEED_ALL_ATOM': None}, None, - settings['THEME'], None, None) + generator = ArticlesGenerator( + settings, get_settings(FEED_ALL_ATOM=None), None, + settings['THEME'], None, None) writer = MagicMock() generator.generate_feeds(writer) self.assertFalse(writer.write_feed.called) @@ -117,15 +117,15 @@ class TestArticlesGenerator(unittest.TestCase): def test_do_not_use_folder_as_category(self): - settings = _DEFAULT_CONFIG.copy() + settings = DEFAULT_CONFIG.copy() settings['ARTICLE_DIR'] = 'content' settings['DEFAULT_CATEGORY'] = 'Default' settings['DEFAULT_DATE'] = (1970, 1, 1) settings['USE_FOLDER_AS_CATEGORY'] = False settings['filenames'] = {} - generator = ArticlesGenerator(settings.copy(), settings, - CUR_DIR, _DEFAULT_CONFIG['THEME'], None, - _DEFAULT_CONFIG['MARKUP']) + generator = ArticlesGenerator( + settings.copy(), settings, CUR_DIR, DEFAULT_CONFIG['THEME'], None, + DEFAULT_CONFIG['MARKUP']) generator.generate_context() # test for name # categories are grouped by slug; if two categories have the same slug @@ -144,7 +144,7 @@ class TestArticlesGenerator(unittest.TestCase): def test_direct_templates_save_as_default(self): - settings = get_settings() + settings = get_settings(filenames={}) generator = ArticlesGenerator(settings, settings, None, settings['THEME'], None, settings['MARKUP']) @@ -212,7 +212,7 @@ class TestPageGenerator(unittest.TestCase): return distilled def test_generate_context(self): - settings = get_settings() + settings = get_settings(filenames={}) settings['PAGE_DIR'] = 'TestPages' settings['DEFAULT_DATE'] = (1970, 1, 1) diff --git a/pelican/tests/test_readers.py b/pelican/tests/test_readers.py index f3427066..a48301f9 100644 --- a/pelican/tests/test_readers.py +++ b/pelican/tests/test_readers.py @@ -5,7 +5,7 @@ import datetime import os from pelican import readers -from pelican.tests.support import unittest +from pelican.tests.support import unittest, get_settings CUR_DIR = os.path.dirname(__file__) CONTENT_PATH = os.path.join(CUR_DIR, 'content') @@ -15,11 +15,18 @@ def _path(*args): return os.path.join(CONTENT_PATH, *args) -class RstReaderTest(unittest.TestCase): +class ReaderTest(unittest.TestCase): + + def read_file(self, path, **kwargs): + # Isolate from future API changes to readers.read_file + return readers.read_file( + _path(path), settings=get_settings(**kwargs)) + + +class RstReaderTest(ReaderTest): def test_article_with_metadata(self): - reader = readers.RstReader({}) - content, metadata = reader.read(_path('article_with_metadata.rst')) + content, metadata = self.read_file(path='article_with_metadata.rst') expected = { 'category': 'yeah', 'author': 'Alexis Métaireau', @@ -36,8 +43,9 @@ class RstReaderTest(unittest.TestCase): self.assertEqual(value, metadata[key], key) def test_article_with_filename_metadata(self): - content, metadata = readers.read_file( - _path('2012-11-29_rst_w_filename_meta#foo-bar.rst')) + content, metadata = self.read_file( + path='2012-11-29_rst_w_filename_meta#foo-bar.rst', + FILENAME_METADATA=None) expected = { 'category': 'yeah', 'author': 'Alexis Métaireau', @@ -46,11 +54,9 @@ class RstReaderTest(unittest.TestCase): for key, value in metadata.items(): self.assertEqual(value, expected[key], key) - content, metadata = readers.read_file( - _path('2012-11-29_rst_w_filename_meta#foo-bar.rst'), - settings={ - 'FILENAME_METADATA': '(?P\d{4}-\d{2}-\d{2}).*' - }) + content, metadata = self.read_file( + path='2012-11-29_rst_w_filename_meta#foo-bar.rst', + FILENAME_METADATA='(?P\d{4}-\d{2}-\d{2}).*') expected = { 'category': 'yeah', 'author': 'Alexis Métaireau', @@ -60,13 +66,12 @@ class RstReaderTest(unittest.TestCase): for key, value in metadata.items(): self.assertEqual(value, expected[key], key) - content, metadata = readers.read_file( - _path('2012-11-29_rst_w_filename_meta#foo-bar.rst'), - settings={ - 'FILENAME_METADATA': '(?P\d{4}-\d{2}-\d{2})_' - '_(?P.*)' - '#(?P.*)-(?P.*)' - }) + content, metadata = self.read_file( + path='2012-11-29_rst_w_filename_meta#foo-bar.rst', + FILENAME_METADATA=( + '(?P\d{4}-\d{2}-\d{2})_' + '_(?P.*)' + '#(?P.*)-(?P.*)')) expected = { 'category': 'yeah', 'author': 'Alexis Métaireau', @@ -80,7 +85,7 @@ class RstReaderTest(unittest.TestCase): def test_article_metadata_key_lowercase(self): # Keys of metadata should be lowercase. - reader = readers.RstReader({}) + reader = readers.RstReader(settings=get_settings()) content, metadata = reader.read( _path('article_with_uppercase_metadata.rst')) @@ -91,7 +96,7 @@ class RstReaderTest(unittest.TestCase): def test_typogrify(self): # if nothing is specified in the settings, the content should be # unmodified - content, _ = readers.read_file(_path('article.rst')) + content, _ = self.read_file(path='article.rst') expected = ('

This is some content. With some stuff to ' '"typogrify".

\n

Now with added ' 'support for ' @@ -101,8 +106,7 @@ class RstReaderTest(unittest.TestCase): try: # otherwise, typogrify should be applied - content, _ = readers.read_file(_path('article.rst'), - settings={'TYPOGRIFY': True}) + content, _ = self.read_file(path='article.rst', TYPOGRIFY=True) expected = ('

This is some content. With some stuff to ' '“typogrify”.

\n

Now with added ' 'support for ' @@ -113,11 +117,11 @@ class RstReaderTest(unittest.TestCase): return unittest.skip('need the typogrify distribution') -class MdReaderTest(unittest.TestCase): +class MdReaderTest(ReaderTest): @unittest.skipUnless(readers.Markdown, "markdown isn't installed") def test_article_with_metadata(self): - reader = readers.MarkdownReader({}) + reader = readers.MarkdownReader(settings=get_settings()) content, metadata = reader.read( _path('article_with_md_extension.md')) expected = { @@ -146,7 +150,7 @@ class MdReaderTest(unittest.TestCase): @unittest.skipUnless(readers.Markdown, "markdown isn't installed") def test_article_with_footnote(self): - reader = readers.MarkdownReader({}) + reader = readers.MarkdownReader(settings=get_settings()) content, metadata = reader.read( _path('article_with_markdown_and_footnote.md')) expected_content = ( @@ -182,7 +186,7 @@ class MdReaderTest(unittest.TestCase): @unittest.skipUnless(readers.Markdown, "markdown isn't installed") def test_article_with_file_extensions(self): - reader = readers.MarkdownReader({}) + reader = readers.MarkdownReader(settings=get_settings()) # test to ensure the md file extension is being processed by the # correct reader content, metadata = reader.read( @@ -221,9 +225,9 @@ class MdReaderTest(unittest.TestCase): def test_article_with_markdown_markup_extension(self): # test to ensure the markdown markup extension is being processed as # expected - content, metadata = readers.read_file( - _path('article_with_markdown_markup_extensions.md'), - settings={'MD_EXTENSIONS': ['toc', 'codehilite', 'extra']}) + content, metadata = self.read_file( + path='article_with_markdown_markup_extensions.md', + MD_EXTENSIONS=['toc', 'codehilite', 'extra']) expected = ('

\n' '
    \n' '
  • Level1
      \n' @@ -239,8 +243,9 @@ class MdReaderTest(unittest.TestCase): @unittest.skipUnless(readers.Markdown, "markdown isn't installed") def test_article_with_filename_metadata(self): - content, metadata = readers.read_file( - _path('2012-11-30_md_w_filename_meta#foo-bar.md')) + content, metadata = self.read_file( + path='2012-11-30_md_w_filename_meta#foo-bar.md', + FILENAME_METADATA=None) expected = { 'category': 'yeah', 'author': 'Alexis Métaireau', @@ -248,11 +253,9 @@ class MdReaderTest(unittest.TestCase): for key, value in expected.items(): self.assertEqual(value, metadata[key], key) - content, metadata = readers.read_file( - _path('2012-11-30_md_w_filename_meta#foo-bar.md'), - settings={ - 'FILENAME_METADATA': '(?P\d{4}-\d{2}-\d{2}).*' - }) + content, metadata = self.read_file( + path='2012-11-30_md_w_filename_meta#foo-bar.md', + FILENAME_METADATA='(?P\d{4}-\d{2}-\d{2}).*') expected = { 'category': 'yeah', 'author': 'Alexis Métaireau', @@ -261,13 +264,12 @@ class MdReaderTest(unittest.TestCase): for key, value in expected.items(): self.assertEqual(value, metadata[key], key) - content, metadata = readers.read_file( - _path('2012-11-30_md_w_filename_meta#foo-bar.md'), - settings={ - 'FILENAME_METADATA': '(?P\d{4}-\d{2}-\d{2})' - '_(?P.*)' - '#(?P.*)-(?P.*)' - }) + content, metadata = self.read_file( + path='2012-11-30_md_w_filename_meta#foo-bar.md', + FILENAME_METADATA=( + '(?P\d{4}-\d{2}-\d{2})' + '_(?P.*)' + '#(?P.*)-(?P.*)')) expected = { 'category': 'yeah', 'author': 'Alexis Métaireau', @@ -279,14 +281,13 @@ class MdReaderTest(unittest.TestCase): self.assertEqual(value, metadata[key], key) -class AdReaderTest(unittest.TestCase): +class AdReaderTest(ReaderTest): @unittest.skipUnless(readers.asciidoc, "asciidoc isn't installed") def test_article_with_asc_extension(self): # Ensure the asc extension is being processed by the correct reader - reader = readers.AsciiDocReader({}) - content, metadata = reader.read( - _path('article_with_asc_extension.asc')) + content, metadata = self.read_file( + path='article_with_asc_extension.asc') expected = ('
      \n

      ' 'Used for pelican test

      \n' '

      The quick brown fox jumped over' @@ -316,10 +317,9 @@ class AdReaderTest(unittest.TestCase): self.assertEqual(content, expected) -class HTMLReaderTest(unittest.TestCase): +class HTMLReaderTest(ReaderTest): def test_article_with_comments(self): - reader = readers.HTMLReader({}) - content, metadata = reader.read(_path('article_with_comments.html')) + content, metadata = self.read_file(path='article_with_comments.html') self.assertEqual(''' Body content @@ -327,8 +327,7 @@ class HTMLReaderTest(unittest.TestCase): ''', content) def test_article_with_keywords(self): - reader = readers.HTMLReader({}) - content, metadata = reader.read(_path('article_with_keywords.html')) + content, metadata = self.read_file(path='article_with_keywords.html') expected = { 'tags': ['foo', 'bar', 'foobar'], } @@ -337,8 +336,7 @@ class HTMLReaderTest(unittest.TestCase): self.assertEqual(value, metadata[key], key) def test_article_with_metadata(self): - reader = readers.HTMLReader({}) - content, metadata = reader.read(_path('article_with_metadata.html')) + content, metadata = self.read_file(path='article_with_metadata.html') expected = { 'category': 'yeah', 'author': 'Alexis Métaireau', @@ -353,9 +351,8 @@ class HTMLReaderTest(unittest.TestCase): self.assertEqual(value, metadata[key], key) def test_article_with_null_attributes(self): - reader = readers.HTMLReader({}) - content, metadata = reader.read( - _path('article_with_null_attributes.html')) + content, metadata = self.read_file( + path='article_with_null_attributes.html') self.assertEqual(''' Ensure that empty attributes are copied properly. @@ -364,9 +361,8 @@ class HTMLReaderTest(unittest.TestCase): def test_article_metadata_key_lowercase(self): # Keys of metadata should be lowercase. - reader = readers.HTMLReader({}) - content, metadata = reader.read( - _path('article_with_uppercase_metadata.html')) + content, metadata = self.read_file( + path='article_with_uppercase_metadata.html') self.assertIn('category', metadata, 'Key should be lowercase.') self.assertEqual('Yeah', metadata.get('category'), 'Value keeps cases.') diff --git a/pelican/tests/test_settings.py b/pelican/tests/test_settings.py index da251675..b1e813e1 100644 --- a/pelican/tests/test_settings.py +++ b/pelican/tests/test_settings.py @@ -5,7 +5,7 @@ import os from os.path import dirname, abspath, join from pelican.settings import (read_settings, configure_settings, - _DEFAULT_CONFIG, DEFAULT_THEME) + DEFAULT_CONFIG, DEFAULT_THEME) from pelican.tests.support import unittest @@ -27,7 +27,7 @@ class TestSettingsConfiguration(unittest.TestCase): def test_keep_default_settings(self): # Keep default settings if not defined. self.assertEqual(self.settings.get('DEFAULT_CATEGORY'), - _DEFAULT_CONFIG['DEFAULT_CATEGORY']) + DEFAULT_CONFIG['DEFAULT_CATEGORY']) def test_dont_copy_small_keys(self): # Do not copy keys not in caps. @@ -36,7 +36,7 @@ class TestSettingsConfiguration(unittest.TestCase): def test_read_empty_settings(self): # Providing no file should return the default values. settings = read_settings(None) - expected = copy.deepcopy(_DEFAULT_CONFIG) + expected = copy.deepcopy(DEFAULT_CONFIG) expected['FEED_DOMAIN'] = '' # Added by configure settings self.maxDiff = None self.assertDictEqual(settings, expected) @@ -55,7 +55,7 @@ class TestSettingsConfiguration(unittest.TestCase): # This assumes 'SITENAME': 'A Pelican Blog' settings = read_settings(None) settings['SITENAME'] = 'Not a Pelican Blog' - self.assertNotEqual(settings['SITENAME'], _DEFAULT_CONFIG['SITENAME']) + self.assertNotEqual(settings['SITENAME'], DEFAULT_CONFIG['SITENAME']) def test_path_settings_safety(self): """Don't let people setting the static path listings to strs""" @@ -69,9 +69,9 @@ class TestSettingsConfiguration(unittest.TestCase): } configure_settings(settings) self.assertEqual(settings['STATIC_PATHS'], - _DEFAULT_CONFIG['STATIC_PATHS']) + DEFAULT_CONFIG['STATIC_PATHS']) self.assertEqual(settings['THEME_STATIC_PATHS'], - _DEFAULT_CONFIG['THEME_STATIC_PATHS']) + DEFAULT_CONFIG['THEME_STATIC_PATHS']) def test_configure_settings(self): #Manipulations to settings should be applied correctly. diff --git a/pelican/writers.py b/pelican/writers.py index 27246e4f..fe37b25d 100644 --- a/pelican/writers.py +++ b/pelican/writers.py @@ -155,10 +155,10 @@ class Writer(object): for key in paginated.keys(): object_list = paginated[key] - if self.settings.get('DEFAULT_PAGINATION'): + if self.settings['DEFAULT_PAGINATION']: paginators[key] = Paginator(object_list, - self.settings.get('DEFAULT_PAGINATION'), - self.settings.get('DEFAULT_ORPHANS')) + self.settings['DEFAULT_PAGINATION'], + self.settings['DEFAULT_ORPHANS']) else: paginators[key] = Paginator(object_list, len(object_list))