Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

move {ARTICLE,PAGE}_DIR -> {ARTICLE,PAGE}_PATHS and correlate with {ARTICLE,PAGE}_EXCLUDES #1322

Merged
merged 3 commits into from
Jun 25, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions docs/plugins.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ Alternatively, another method is to import them and add them to the list::
PLUGINS = [myplugin,]

If your plugins are not in an importable path, you can specify a list of paths
via the ``PLUGIN_PATH`` setting. As shown in the following example, paths in
the ``PLUGIN_PATH`` list can be absolute or relative to the settings file::
via the ``PLUGIN_PATHS`` setting. As shown in the following example, paths in
the ``PLUGIN_PATHS`` list can be absolute or relative to the settings file::

PLUGIN_PATH = ["plugins", "/srv/pelican/plugins"]
PLUGIN_PATHS = ["plugins", "/srv/pelican/plugins"]
PLUGINS = ["assets", "liquid_tags", "sitemap"]

Where to find plugins
Expand Down
11 changes: 7 additions & 4 deletions docs/settings.rst
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,12 @@ Setting name (followed by default value, if any)
``PATH`` Path to content directory to be processed by Pelican. If undefined,
and content path is not specified via an argument to the ``pelican``
command, Pelican will use the current working directory.
``PAGE_DIR = 'pages'`` Directory to look at for pages, relative to ``PATH``.
``PAGE_EXCLUDES = ()`` A list of directories to exclude when looking for pages.
``ARTICLE_DIR = ''`` Directory to look at for articles, relative to ``PATH``.
``ARTICLE_EXCLUDES = ('pages',)`` A list of directories to exclude when looking for articles.
``PAGE_PATHS = ['pages']`` A list of directories to look at for pages, relative to ``PATH``.
``PAGE_EXCLUDES = []`` A list of directories to exclude when looking for pages in addition
to ``ARTICLE_PATHS``.
``ARTICLE_PATHS = ['']`` A list of directories to look at for articles, relative to ``PATH``.
``ARTICLE_EXCLUDES = []`` A list of directories to exclude when looking for articles in addition
to ``PAGE_PATHS``.
``OUTPUT_SOURCES = False`` Set to True if you want to copy the articles and pages in their
original format (e.g. Markdown or reStructuredText) to the
specified ``OUTPUT_PATH``.
Expand All @@ -125,6 +127,7 @@ Setting name (followed by default value, if any)
not. Only set this to ``True`` when developing/testing and only
if you fully understand the effect it can have on links/feeds.
``PLUGINS = []`` The list of plugins to load. See :ref:`plugins`.
``PLUGIN_PATHS = []`` A list of directories where to look for plugins. See :ref:`plugins`.
``SITENAME = 'A Pelican Blog'`` Your site name
``SITEURL`` Base URL of your website. Not defined by default,
so it is best to specify your SITEURL; if you do not, feeds
Expand Down
4 changes: 2 additions & 2 deletions pelican/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,9 @@ def init_path(self):

def init_plugins(self):
self.plugins = []
logger.debug('Temporarily adding PLUGIN_PATH to system path')
logger.debug('Temporarily adding PLUGIN_PATHS to system path')
_sys_path = sys.path[:]
for pluginpath in self.settings['PLUGIN_PATH']:
for pluginpath in self.settings['PLUGIN_PATHS']:
sys.path.insert(0, pluginpath)
for plugin in self.settings['PLUGINS']:
# if it's a string, then import it
Expand Down
62 changes: 30 additions & 32 deletions pelican/generators.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,29 +110,30 @@ def _include_path(self, path, extensions=None):
return True
return False

def get_files(self, path, exclude=[], extensions=None):
def get_files(self, paths, exclude=[], extensions=None):
"""Return a list of files to use, based on rules

:param path: the path to search (relative to self.path)
:param paths: the list pf paths to search (relative to self.path)
:param exclude: the list of path to exclude
:param extensions: the list of allowed extensions (if False, all
extensions are allowed)
"""
files = []
root = os.path.join(self.path, path)

if os.path.isdir(root):
for dirpath, dirs, temp_files in os.walk(root, followlinks=True):
for e in exclude:
if e in dirs:
dirs.remove(e)
reldir = os.path.relpath(dirpath, self.path)
for f in temp_files:
fp = os.path.join(reldir, f)
if self._include_path(fp, extensions):
files.append(fp)
elif os.path.exists(root) and self._include_path(path, extensions):
files.append(path) # can't walk non-directories
for path in paths:
root = os.path.join(self.path, path)

if os.path.isdir(root):
for dirpath, dirs, temp_files in os.walk(root, followlinks=True):
for e in exclude:
if e in dirs:
dirs.remove(e)
reldir = os.path.relpath(dirpath, self.path)
for f in temp_files:
fp = os.path.join(reldir, f)
if self._include_path(fp, extensions):
files.append(fp)
elif os.path.exists(root) and self._include_path(path, extensions):
files.append(path) # can't walk non-directories
return files

def add_source_path(self, content):
Expand Down Expand Up @@ -462,7 +463,7 @@ def generate_context(self):
all_articles = []
all_drafts = []
for f in self.get_files(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should still support ARTICLE_DIR and deprecate it instead of removing it so soon. So we don't break peoples config without deprecating the settings.

ARTICLE_DIR should be added to ARTICLE_PATHS for now.

self.settings['ARTICLE_DIR'],
self.settings['ARTICLE_PATHS'],
exclude=self.settings['ARTICLE_EXCLUDES']):
article = self.get_cached_data(f, None)
if article is None:
Expand Down Expand Up @@ -586,7 +587,7 @@ def generate_context(self):
all_pages = []
hidden_pages = []
for f in self.get_files(
self.settings['PAGE_DIR'],
self.settings['PAGE_PATHS'],
exclude=self.settings['PAGE_EXCLUDES']):
page = self.get_cached_data(f, None)
if page is None:
Expand Down Expand Up @@ -660,20 +661,17 @@ def _copy_paths(self, paths, source, destination, output_path,

def generate_context(self):
self.staticfiles = []

# walk static paths
for static_path in self.settings['STATIC_PATHS']:
for f in self.get_files(
static_path, extensions=False):
static = self.readers.read_file(
base_path=self.path, path=f, content_class=Static,
fmt='static', context=self.context,
preread_signal=signals.static_generator_preread,
preread_sender=self,
context_signal=signals.static_generator_context,
context_sender=self)
self.staticfiles.append(static)
self.add_source_path(static)
for f in self.get_files(self.settings['STATIC_PATHS'],
extensions=False):
static = self.readers.read_file(
base_path=self.path, path=f, content_class=Static,
fmt='static', context=self.context,
preread_signal=signals.static_generator_preread,
preread_sender=self,
context_signal=signals.static_generator_context,
context_sender=self)
self.staticfiles.append(static)
self.add_source_path(static)
self._update_context(('staticfiles',))
signals.static_generator_finalized.send(self)

Expand Down
62 changes: 45 additions & 17 deletions pelican/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@
'themes', 'notmyidea')
DEFAULT_CONFIG = {
'PATH': os.curdir,
'ARTICLE_DIR': '',
'ARTICLE_EXCLUDES': ('pages',),
'PAGE_DIR': 'pages',
'PAGE_EXCLUDES': (),
'ARTICLE_PATHS': [''],
'ARTICLE_EXCLUDES': [],
'PAGE_PATHS': ['pages'],
'PAGE_EXCLUDES': [],
'THEME': DEFAULT_THEME,
'OUTPUT_PATH': 'output',
'READERS': {},
Expand Down Expand Up @@ -114,7 +114,7 @@
'ARTICLE_PERMALINK_STRUCTURE': '',
'TYPOGRIFY': False,
'SUMMARY_MAX_LENGTH': 50,
'PLUGIN_PATH': [],
'PLUGIN_PATHS': [],
'PLUGINS': [],
'PYGMENTS_RST_OPTIONS': {},
'TEMPLATE_PAGES': {},
Expand Down Expand Up @@ -147,13 +147,17 @@ def read_settings(path=None, override=None):
if p not in ('THEME') or os.path.exists(absp):
local_settings[p] = absp

if isinstance(local_settings['PLUGIN_PATH'], six.string_types):
logger.warning("Defining %s setting as string has been deprecated (should be a list)" % 'PLUGIN_PATH')
local_settings['PLUGIN_PATH'] = [local_settings['PLUGIN_PATH']]
else:
if 'PLUGIN_PATH' in local_settings and local_settings['PLUGIN_PATH'] is not None:
local_settings['PLUGIN_PATH'] = [os.path.abspath(os.path.normpath(os.path.join(os.path.dirname(path), pluginpath)))
if not isabs(pluginpath) else pluginpath for pluginpath in local_settings['PLUGIN_PATH']]
if 'PLUGIN_PATH' in local_settings:
logger.warning('PLUGIN_PATH setting has been replaced by '
'PLUGIN_PATHS, moving it to the new setting name.')
local_settings['PLUGIN_PATHS'] = local_settings['PLUGIN_PATH']
del local_settings['PLUGIN_PATH']
if isinstance(local_settings['PLUGIN_PATHS'], six.string_types):
logger.warning("Defining %s setting as string has been deprecated (should be a list)" % 'PLUGIN_PATHS')
local_settings['PLUGIN_PATHS'] = [local_settings['PLUGIN_PATHS']]
elif local_settings['PLUGIN_PATHS'] is not None:
local_settings['PLUGIN_PATHS'] = [os.path.abspath(os.path.normpath(os.path.join(os.path.dirname(path), pluginpath)))
if not isabs(pluginpath) else pluginpath for pluginpath in local_settings['PLUGIN_PATHS']]
else:
local_settings = copy.deepcopy(DEFAULT_CONFIG)

Expand Down Expand Up @@ -311,6 +315,16 @@ def configure_settings(settings):
key=lambda r: r[0],
)

# move {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 {}, moving it to {} list'.format(
old_key, new_key))
settings[new_key] = [settings[old_key]] # also make a list
del settings[old_key]

# Save people from accidentally setting a string rather than a list
path_keys = (
'ARTICLE_EXCLUDES',
Expand All @@ -324,13 +338,27 @@ def configure_settings(settings):
'PLUGINS',
'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]
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

for old, new, doc in [
('LESS_GENERATOR', 'the Webassets plugin', None),
Expand Down
2 changes: 1 addition & 1 deletion pelican/tests/test_generators.py
Original file line number Diff line number Diff line change
Expand Up @@ -372,8 +372,8 @@ def distill_pages(self, pages):

def test_generate_context(self):
settings = get_settings(filenames={})
settings['PAGE_DIR'] = 'TestPages' # relative to CUR_DIR
settings['CACHE_PATH'] = self.temp_cache
settings['PAGE_PATHS'] = ['TestPages'] # relative to CUR_DIR
settings['DEFAULT_DATE'] = (1970, 1, 1)

generator = PagesGenerator(
Expand Down
5 changes: 4 additions & 1 deletion pelican/tests/test_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,10 @@ def test_read_empty_settings(self):
# Providing no file should return the default values.
settings = read_settings(None)
expected = copy.deepcopy(DEFAULT_CONFIG)
expected['FEED_DOMAIN'] = '' # Added by configure settings
# Added by configure settings
expected['FEED_DOMAIN'] = ''
expected['ARTICLE_EXCLUDES'] = ['pages']
expected['PAGE_EXCLUDES'] = ['']
self.maxDiff = None
self.assertDictEqual(settings, expected)

Expand Down