Esempio n. 1
0
    def test_custom_pagination_pattern_last_page(self):
        from pelican.paginator import PaginationRule
        settings = get_settings()
        settings['PAGINATION_PATTERNS'] = [
            PaginationRule(*r) for r in [
                (1, '/{url}1/', '{base_name}/1/index.html'),
                (2, '/{url}{number}/', '{base_name}/{number}/index.html'),
                (-1, '/{url}', '{base_name}/index.html'),
            ]
        ]

        self.page_kwargs['metadata']['author'] = Author('Blogger', settings)
        object_list = [
            Article(**self.page_kwargs),
            Article(**self.page_kwargs),
            Article(**self.page_kwargs)
        ]
        paginator = Paginator('blog/index.html', '//blog.my.site/',
                              object_list, settings, 1)
        # The URL *has to* stay absolute (with // in the front), so verify that
        page1 = paginator.page(1)
        self.assertEqual(page1.save_as, 'blog/1/index.html')
        self.assertEqual(page1.url, '//blog.my.site/1/')
        page2 = paginator.page(2)
        self.assertEqual(page2.save_as, 'blog/2/index.html')
        self.assertEqual(page2.url, '//blog.my.site/2/')
        page3 = paginator.page(3)
        self.assertEqual(page3.save_as, 'blog/index.html')
        self.assertEqual(page3.url, '//blog.my.site/')
Esempio n. 2
0
    def test_save_as_preservation(self):
        settings = get_settings()
        # 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],
        )

        object_list = [
            Article(**self.page_kwargs),
            Article(**self.page_kwargs)
        ]
        paginator = Paginator('foobar.foo', object_list, settings)
        page = paginator.page(1)
        self.assertEqual(page.save_as, 'foobar.foo')
Esempio n. 3
0
    def test_custom_pagination_pattern(self):
        from pelican.paginator import PaginationRule
        settings = get_settings()
        settings['PAGINATION_PATTERNS'] = [
            PaginationRule(*r)
            for r in [(1, '/{url}', '{base_name}/index.html'),
                      (2, '/{url}{number}/',
                       '{base_name}/{number}/index.html')]
        ]

        self.page_kwargs['metadata']['author'] = Author('Blogger', settings)
        object_list = [
            Article(**self.page_kwargs),
            Article(**self.page_kwargs)
        ]
        paginator = Paginator('blog/index.html', '//blog.my.site/',
                              object_list, settings, 1)
        page1 = paginator.page(1)
        self.assertEqual(page1.save_as, 'blog/index.html')
        self.assertEqual(page1.url, '//blog.my.site/')
        page2 = paginator.page(2)
        self.assertEqual(page2.save_as, 'blog/2/index.html')
        self.assertEqual(page2.url, '//blog.my.site/2/')
Esempio n. 4
0
def configure_settings(settings):
    """Provide optimizations, error checking, and warnings for the given
    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'])
    LimitFilter._ignore.update(set(log_filter))

    # 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 %s" % settings['THEME'])

    # make paths selected for writing absolute if necessary
    settings['WRITE_SELECTED'] = [
        os.path.abspath(path) for path in settings.get(
            'WRITE_SELECTED', DEFAULT_CONFIG['WRITE_SELECTED'])
    ]

    # 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], 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 %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'])

    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']

    # check content caching layer and warn of incompatibilities
    if settings.get('CACHE_CONTENT', False) and \
            settings.get('CONTENT_CACHING_LAYER', '') == 'generator' and \
            settings.get('WITH_FUTURE_DATES', False):
        logger.warning(
            "WITH_FUTURE_DATES conflicts with CONTENT_CACHING_LAYER "
            "set to 'generator', use 'reader' layer instead")

    # 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')

    if 'TIMEZONE' not in settings:
        logger.warning(
            'No timezone information specified in the settings. Assuming'
            ' your timezone is UTC for feed generation. Check '
            'http://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],
    )

    # 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], six.string_types):
            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

    return settings
Esempio n. 5
0
def configure_settings(settings):
    """Provide optimizations, error checking, and warnings for the given
    settings.
    Also, specify the log messages to be ignored.
    """
    if not 'PATH' 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
    LimitFilter.ignore.update(
        set(settings.get('LOG_FILTER', DEFAULT_CONFIG['LOG_FILTER'])))

    # 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 %s" % settings['THEME'])

    # make paths selected for writing absolute if necessary
    settings['WRITE_SELECTED'] = [
        os.path.abspath(path) for path in settings.get(
            'WRITE_SELECTED', DEFAULT_CONFIG['WRITE_SELECTED'])
    ]

    # standardize strings to lowercase strings
    for key in [
            'DEFAULT_LANG',
    ]:
        if key in settings:
            settings[key] = settings[key].lower()

    # 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.
    locales = settings.get('LOCALE', DEFAULT_CONFIG['LOCALE'])

    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 option doesn't contain a correct value")

    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 not 'FEED_DOMAIN' in settings:
            settings['FEED_DOMAIN'] = settings['SITEURL']

    # check content caching layer and warn of incompatibilities
    if (settings.get('CACHE_CONTENT', False)
            and settings.get('CONTENT_CACHING_LAYER', '') == 'generator'
            and settings.get('WITH_FUTURE_DATES',
                             DEFAULT_CONFIG['WITH_FUTURE_DATES'])):
        logger.warning('WITH_FUTURE_DATES conflicts with '
                       "CONTENT_CACHING_LAYER set to 'generator', "
                       "use 'reader' layer instead")

    # 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')

    if not 'TIMEZONE' in settings:
        logger.warning(
            'No timezone information specified in the settings. Assuming'
            ' your timezone is UTC for feed generation. Check '
            'http://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],
    )

    # Save people from accidentally setting a string rather than a list
    path_keys = (
        'ARTICLE_EXCLUDES',
        'DEFAULT_METADATA',
        'DIRECT_TEMPLATES',
        'EXTRA_TEMPLATES_PATHS',
        'FILES_TO_COPY',
        'IGNORE_FILES',
        'JINJA_EXTENSIONS',
        'PAGINATED_DIRECT_TEMPLATES',
        'PLUGINS',
        'STATIC_PATHS',
        'THEME_STATIC_PATHS',
    )
    for PATH_KEY in filter(lambda k: k in settings, path_keys):
        if isinstance(settings[PATH_KEY], six.string_types):
            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]

    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/blob/master/docs/settings.rst#path-metadata'
         ),
    ]:
        if old in settings:
            message = 'The {} setting has been removed in favor of {}'.format(
                old, new)
            if doc:
                message += ', see {} for details'.format(doc)
            logger.warning(message)

    return settings