mirror of
https://github.com/getpelican/pelican.git
synced 2025-10-15 20:28:56 +02:00
Assigned filtering IDs to logger messages
Any ID has common scheme 'log-level.module.description', so it contains three period-separated groups with possible dashes inside each group. List of all IDs can be obtained by the following command (in an Unix environment): ``` $ grep -R "'id': '" pelican | sed -e "s/.*'id': '\([^']\+\)'.*/\1/" | sort -u ``` Fixes #1594.
This commit is contained in:
parent
c2968ccf39
commit
b3a5d87a9e
11 changed files with 196 additions and 97 deletions
|
|
@ -107,7 +107,7 @@ Setting name (followed by default value, if any)
|
|||
and the message to be ignored.
|
||||
For example: ``[(logging.WARN, 'TAG_SAVE_AS is set to False')]``
|
||||
``LOG_FILTER_IDS = []`` A list of containing IDs of messages to be ignored.
|
||||
For example: ``['warn.img.alt.empty']``
|
||||
For example: ``['warn.readers.empty-alt-attribute']``
|
||||
``READERS = {}`` A dictionary of file extensions / Reader classes for Pelican to
|
||||
process or ignore. For example, to avoid processing .html files,
|
||||
set: ``READERS = {'html': None}``. To add a custom reader for the
|
||||
|
|
@ -780,7 +780,7 @@ It's hard to ignore a group of messages containing dynamic substrings (e.g.
|
|||
paths to files). Such messages can be ignored using the ``LOG_FILTER_IDS``
|
||||
setting.
|
||||
|
||||
For example: ``['warn.img.alt.empty']``
|
||||
For example: ``['warn.readers.empty-alt-attribute']``
|
||||
|
||||
.. _reading_only_modified_content:
|
||||
|
||||
|
|
|
|||
|
|
@ -55,7 +55,8 @@ class Pelican(object):
|
|||
|
||||
def init_path(self):
|
||||
if not any(p in sys.path for p in ['', os.curdir]):
|
||||
logger.debug("Adding current directory to system path")
|
||||
logger.debug("Adding current directory to system path",
|
||||
extra={'id': 'debug.init.adding-cwd-to-system-path'})
|
||||
sys.path.insert(0, '')
|
||||
|
||||
def init_plugins(self):
|
||||
|
|
@ -67,7 +68,8 @@ class Pelican(object):
|
|||
for plugin in self.settings['PLUGINS']:
|
||||
# if it's a string, then import it
|
||||
if isinstance(plugin, six.string_types):
|
||||
logger.debug("Loading plugin `%s`", plugin)
|
||||
logger.debug("Loading plugin `%s`", plugin,
|
||||
extra={'id': 'debug.init.loading-plugin'})
|
||||
try:
|
||||
plugin = __import__(plugin, globals(), locals(),
|
||||
str('module'))
|
||||
|
|
@ -76,10 +78,12 @@ class Pelican(object):
|
|||
"Cannot load plugin `%s`\n%s", plugin, e)
|
||||
continue
|
||||
|
||||
logger.debug("Registering plugin `%s`", plugin.__name__)
|
||||
logger.debug("Registering plugin `%s`", plugin.__name__,
|
||||
extra={'id': 'debug.init.registering-plugin'})
|
||||
plugin.register()
|
||||
self.plugins.append(plugin)
|
||||
logger.debug('Restoring system path')
|
||||
logger.debug('Restoring system path',
|
||||
extra={'id': 'debug.init.restoring-system-path'})
|
||||
sys.path = _sys_path
|
||||
|
||||
def _handle_deprecation(self):
|
||||
|
|
@ -87,7 +91,8 @@ class Pelican(object):
|
|||
if self.settings.get('CLEAN_URLS', False):
|
||||
logger.warning('Found deprecated `CLEAN_URLS` in settings.'
|
||||
' Modifying the following settings for the'
|
||||
' same behaviour.')
|
||||
' same behaviour.',
|
||||
extra={'id': 'warn.init.clean-urls-deprected'})
|
||||
|
||||
self.settings['ARTICLE_URL'] = '{slug}/'
|
||||
self.settings['ARTICLE_LANG_URL'] = '{slug}-{lang}/'
|
||||
|
|
@ -96,17 +101,21 @@ class Pelican(object):
|
|||
|
||||
for setting in ('ARTICLE_URL', 'ARTICLE_LANG_URL', 'PAGE_URL',
|
||||
'PAGE_LANG_URL'):
|
||||
logger.warning("%s = '%s'", setting, self.settings[setting])
|
||||
logger.warning("%s = '%s'", setting, self.settings[setting],
|
||||
extra={'id': 'warn.init.clean-urls-deprected'})
|
||||
|
||||
if self.settings.get('AUTORELOAD_IGNORE_CACHE'):
|
||||
logger.warning('Found deprecated `AUTORELOAD_IGNORE_CACHE` in '
|
||||
'settings. Use --ignore-cache instead.')
|
||||
'settings. Use --ignore-cache instead.',
|
||||
extra={'id': 'warn.init.autoreload-ignore-cache'})
|
||||
self.settings.pop('AUTORELOAD_IGNORE_CACHE')
|
||||
|
||||
if self.settings.get('ARTICLE_PERMALINK_STRUCTURE', False):
|
||||
logger.warning('Found deprecated `ARTICLE_PERMALINK_STRUCTURE` in'
|
||||
' settings. Modifying the following settings for'
|
||||
' the same behaviour.')
|
||||
logger.warning(
|
||||
'Found deprecated `ARTICLE_PERMALINK_STRUCTURE` in'
|
||||
' settings. Modifying the following settings for'
|
||||
' the same behaviour.',
|
||||
extra={'id': 'warn.init.article-permalink-structure'})
|
||||
|
||||
structure = self.settings['ARTICLE_PERMALINK_STRUCTURE']
|
||||
|
||||
|
|
@ -126,7 +135,9 @@ class Pelican(object):
|
|||
'PAGE_SAVE_AS', 'PAGE_LANG_SAVE_AS'):
|
||||
self.settings[setting] = os.path.join(structure,
|
||||
self.settings[setting])
|
||||
logger.warning("%s = '%s'", setting, self.settings[setting])
|
||||
logger.warning(
|
||||
"%s = '%s'", setting, self.settings[setting],
|
||||
extra={'id': 'warn.init.article-permalink-structure'})
|
||||
|
||||
for new, old in [('FEED', 'FEED_ATOM'), ('TAG_FEED', 'TAG_FEED_ATOM'),
|
||||
('CATEGORY_FEED', 'CATEGORY_FEED_ATOM'),
|
||||
|
|
@ -137,7 +148,8 @@ class Pelican(object):
|
|||
'to %(old)s in your settings and theme for the same '
|
||||
'behavior. Temporarily setting %(old)s for backwards '
|
||||
'compatibility.',
|
||||
{'new': new, 'old': old}
|
||||
{'new': new, 'old': old},
|
||||
extra={'id': 'warn.init.feed-setting-deprecated'}
|
||||
)
|
||||
self.settings[old] = self.settings[new]
|
||||
|
||||
|
|
@ -229,7 +241,8 @@ class Pelican(object):
|
|||
|
||||
for v in value:
|
||||
if isinstance(v, type):
|
||||
logger.debug('Found generator: %s', v)
|
||||
logger.debug('Found generator: %s', v,
|
||||
extra={'id': 'debug.init.found-generator'})
|
||||
generators.append(v)
|
||||
|
||||
# StaticGenerator must run last, so it can identify files that
|
||||
|
|
@ -247,11 +260,13 @@ class Pelican(object):
|
|||
else:
|
||||
writer = writers[0]
|
||||
if writers_found == 1:
|
||||
logger.debug('Found writer: %s', writer)
|
||||
logger.debug('Found writer: %s', writer,
|
||||
extra={'id': 'debug.init.found-writer'})
|
||||
else:
|
||||
logger.warning(
|
||||
'%s writers found, using only first one: %s',
|
||||
writers_found, writer)
|
||||
writers_found, writer,
|
||||
extra={'id': 'debug.init.many-writers-found'})
|
||||
return writer(self.output_path, settings=self.settings)
|
||||
|
||||
|
||||
|
|
@ -385,8 +400,10 @@ def main():
|
|||
args = parse_arguments()
|
||||
init(args.verbosity, args.fatal)
|
||||
|
||||
logger.debug('Pelican version: %s', __version__)
|
||||
logger.debug('Python version: %s', sys.version.split()[0])
|
||||
logger.debug('Pelican version: %s', __version__,
|
||||
extra={'id': 'debug.init.pelican-version'})
|
||||
logger.debug('Python version: %s', sys.version.split()[0],
|
||||
extra={'id': 'debug.init.python-version'})
|
||||
|
||||
try:
|
||||
pelican, settings = get_instance(args)
|
||||
|
|
@ -455,33 +472,42 @@ def main():
|
|||
', '.join(k for k, v in modified.items() if v)))
|
||||
|
||||
if modified['content'] is None:
|
||||
logger.warning('No valid files found in content.')
|
||||
logger.warning(
|
||||
'No valid files found in content.',
|
||||
extra={'id': 'warn.init.no-valid-content'})
|
||||
|
||||
if modified['theme'] is None:
|
||||
logger.warning('Empty theme folder. Using `basic` '
|
||||
'theme.')
|
||||
logger.warning(
|
||||
'Empty theme folder. Using `basic` theme.',
|
||||
extra={'id': 'warn.init.empty-theme-folder'})
|
||||
|
||||
pelican.run()
|
||||
|
||||
except KeyboardInterrupt:
|
||||
logger.warning("Keyboard interrupt, quitting.")
|
||||
logger.warning(
|
||||
"Keyboard interrupt, quitting.",
|
||||
extra={'id': 'warn.init.keyboard-interrupt'})
|
||||
break
|
||||
|
||||
except Exception as e:
|
||||
if (args.verbosity == logging.DEBUG):
|
||||
raise
|
||||
logger.warning(
|
||||
'Caught exception "%s". Reloading.', e)
|
||||
'Caught exception "%s". Reloading.', e,
|
||||
extra={'id': 'warn.init.caught-exception'})
|
||||
|
||||
finally:
|
||||
time.sleep(.5) # sleep to avoid cpu load
|
||||
|
||||
else:
|
||||
if next(watchers['content']) is None:
|
||||
logger.warning('No valid files found in content.')
|
||||
logger.warning(
|
||||
'No valid files found in content.',
|
||||
extra={'id': 'warn.init.no-valid-content-files'})
|
||||
|
||||
if next(watchers['theme']) is None:
|
||||
logger.warning('Empty theme folder. Using `basic` theme.')
|
||||
logger.warning('Empty theme folder. Using `basic` theme.',
|
||||
extra={'id': 'warn.init.empty-theme-folder'})
|
||||
|
||||
pelican.run()
|
||||
|
||||
|
|
|
|||
|
|
@ -38,14 +38,16 @@ class FileDataCacher(object):
|
|||
except (IOError, OSError) as err:
|
||||
logger.debug('Cannot load cache %s (this is normal on first '
|
||||
'run). Proceeding with empty cache.\n%s',
|
||||
self._cache_path, err)
|
||||
self._cache_path, err,
|
||||
extra={'id': 'debug.cache.load'})
|
||||
self._cache = {}
|
||||
except pickle.PickleError as err:
|
||||
logger.warning('Cannot unpickle cache %s, cache may be using '
|
||||
'an incompatible protocol (see pelican '
|
||||
'caching docs). '
|
||||
'Proceeding with empty cache.\n%s',
|
||||
self._cache_path, err)
|
||||
self._cache_path, err,
|
||||
extra={'id': 'warn.cache.unpickle'})
|
||||
self._cache = {}
|
||||
else:
|
||||
self._cache = {}
|
||||
|
|
@ -71,7 +73,8 @@ class FileDataCacher(object):
|
|||
pickle.dump(self._cache, fhandle)
|
||||
except (IOError, OSError, pickle.PicklingError) as err:
|
||||
logger.warning('Could not save cache %s\n ... %s',
|
||||
self._cache_path, err)
|
||||
self._cache_path, err,
|
||||
extra={'id': 'warn.cache.save'})
|
||||
|
||||
|
||||
class FileStampDataCacher(FileDataCacher):
|
||||
|
|
@ -100,7 +103,8 @@ class FileStampDataCacher(FileDataCacher):
|
|||
|
||||
self._filestamp_func = filestamp_func
|
||||
except AttributeError as err:
|
||||
logger.warning('Could not get hashing function\n\t%s', err)
|
||||
logger.warning('Could not get hashing function\n\t%s', err,
|
||||
extra={'id': 'warn.cache.hash'})
|
||||
self._filestamp_func = None
|
||||
|
||||
def cache_data(self, filename, data):
|
||||
|
|
@ -122,7 +126,8 @@ class FileStampDataCacher(FileDataCacher):
|
|||
return self._filestamp_func(filename)
|
||||
except (IOError, OSError, TypeError) as err:
|
||||
logger.warning('Cannot get modification stamp for %s\n\t%s',
|
||||
filename, err)
|
||||
filename, err,
|
||||
extra={'id': 'warn.cache.get-timestamp'})
|
||||
return ''
|
||||
|
||||
def get_cached_data(self, filename, default=None):
|
||||
|
|
|
|||
|
|
@ -241,7 +241,8 @@ class Content(object):
|
|||
logger.warning(
|
||||
"%s used {attach} link syntax on a "
|
||||
"non-static file. Use {filename} instead.",
|
||||
self.get_relative_source_path())
|
||||
self.get_relative_source_path(), extra={
|
||||
'id': 'warn.contents.non-static-attach'})
|
||||
origin = '/'.join((siteurl, linked_content.url))
|
||||
origin = origin.replace('\\', '/') # for Windows paths.
|
||||
else:
|
||||
|
|
@ -249,7 +250,8 @@ class Content(object):
|
|||
"Unable to find `%s`, skipping url replacement.",
|
||||
value.geturl(), extra={
|
||||
'limit_msg': ("Other resources were not found "
|
||||
"and their urls not replaced")})
|
||||
"and their urls not replaced"),
|
||||
'id': 'warn.contents.unable-to-find-url'})
|
||||
elif what == 'category':
|
||||
origin = '/'.join((siteurl, Category(path, self.settings).url))
|
||||
elif what == 'tag':
|
||||
|
|
@ -262,7 +264,8 @@ class Content(object):
|
|||
logger.warning(
|
||||
"Replacement Indicator '%s' not recognized, "
|
||||
"skipping replacement",
|
||||
what)
|
||||
what, extra={
|
||||
'id': 'warn.contents.unknown-replacement-indicator'})
|
||||
|
||||
# keep all other parts, such as query, fragment, etc.
|
||||
parts = list(value)
|
||||
|
|
@ -313,7 +316,8 @@ class Content(object):
|
|||
"""deprecated function to access summary"""
|
||||
|
||||
logger.warning('_get_summary() has been deprecated since 3.6.4. '
|
||||
'Use the summary decorator instead')
|
||||
'Use the summary decorator instead',
|
||||
extra={'id': 'warn.contents.get-summary-deprecated'})
|
||||
return self.summary
|
||||
|
||||
@summary.setter
|
||||
|
|
@ -447,7 +451,8 @@ class Static(Page):
|
|||
"{filename} link behavior instead.",
|
||||
content.get_relative_source_path(),
|
||||
self.get_relative_source_path(), reason,
|
||||
extra={'limit_msg': "More {attach} warnings silenced."})
|
||||
extra={'limit_msg': "More {attach} warnings silenced.",
|
||||
'id': 'warn.contents.link-relocation-failed'})
|
||||
|
||||
# We never override an override, because we don't want to interfere
|
||||
# with user-defined overrides that might be in EXTRA_PATH_METADATA.
|
||||
|
|
|
|||
|
|
@ -71,7 +71,8 @@ class Generator(object):
|
|||
extensions=self.settings['JINJA_EXTENSIONS'],
|
||||
)
|
||||
|
||||
logger.debug('Template list: %s', self.env.list_templates())
|
||||
logger.debug('Template list: %s', self.env.list_templates(),
|
||||
extra={'id': 'debug.generators.template-list'})
|
||||
|
||||
# provide utils.strftime as a jinja filter
|
||||
self.env.filters.update({'strftime': DateFormatter()})
|
||||
|
|
@ -728,7 +729,8 @@ class StaticGenerator(Generator):
|
|||
save_as = os.path.join(self.output_path, sc.save_as)
|
||||
mkdir_p(os.path.dirname(save_as))
|
||||
shutil.copy2(source_path, save_as)
|
||||
logger.info('Copying %s to %s', sc.source_path, sc.save_as)
|
||||
logger.info('Copying %s to %s', sc.source_path, sc.save_as,
|
||||
extra={'id': 'info.generators.copying'})
|
||||
|
||||
|
||||
class SourceFileGenerator(Generator):
|
||||
|
|
@ -743,7 +745,8 @@ class SourceFileGenerator(Generator):
|
|||
copy(obj.source_path, dest)
|
||||
|
||||
def generate_output(self, writer=None):
|
||||
logger.info('Generating source files...')
|
||||
logger.info('Generating source files...',
|
||||
extra={'id': 'info.generators.generating-source-files'})
|
||||
for obj in chain(self.context['articles'], self.context['pages']):
|
||||
self._create_source(obj)
|
||||
for obj_trans in obj.translations:
|
||||
|
|
|
|||
|
|
@ -269,7 +269,8 @@ class MarkdownReader(BaseReader):
|
|||
logger.warning(
|
||||
'Duplicate definition of `%s` '
|
||||
'for %s. Using first one.',
|
||||
name, self._source_path)
|
||||
name, self._source_path,
|
||||
extra={'id': 'warn.readers.duplicate-metadata-def'})
|
||||
output[name] = self.process_metadata(name, value[0])
|
||||
elif len(value) > 1:
|
||||
# handle list metadata as list of string
|
||||
|
|
@ -389,9 +390,11 @@ class HTMLReader(BaseReader):
|
|||
if name is None:
|
||||
attr_list = ['{}="{}"'.format(k, v) for k, v in attrs]
|
||||
attr_serialized = ', '.join(attr_list)
|
||||
logger.warning("Meta tag in file %s does not have a 'name' "
|
||||
"attribute, skipping. Attributes: %s",
|
||||
self._filename, attr_serialized)
|
||||
logger.warning(
|
||||
"Meta tag in file %s does not have a 'name' "
|
||||
"attribute, skipping. Attributes: %s",
|
||||
self._filename, attr_serialized,
|
||||
extra={'id': 'warn.readers.unknown-meta-tag-attribute'})
|
||||
return
|
||||
name = name.lower()
|
||||
contents = self._attr_value(attrs, 'content', '')
|
||||
|
|
@ -404,7 +407,8 @@ class HTMLReader(BaseReader):
|
|||
self._filename,
|
||||
extra={'limit_msg': "Other files have meta tag "
|
||||
"attribute 'contents' that should "
|
||||
"be changed to 'content'"})
|
||||
"be changed to 'content'",
|
||||
'id': 'warn.readers.contents-meta-tag-used'})
|
||||
|
||||
if name == 'keywords':
|
||||
name = 'tags'
|
||||
|
|
@ -444,8 +448,10 @@ class Readers(FileStampDataCacher):
|
|||
|
||||
for cls in [BaseReader] + BaseReader.__subclasses__():
|
||||
if not cls.enabled:
|
||||
logger.debug('Missing dependencies for %s',
|
||||
', '.join(cls.file_extensions))
|
||||
logger.debug(
|
||||
'Missing dependencies for %s',
|
||||
', '.join(cls.file_extensions),
|
||||
extra={'id': 'debug.readers.missing-dependencies'})
|
||||
continue
|
||||
|
||||
for ext in cls.file_extensions:
|
||||
|
|
@ -484,7 +490,8 @@ class Readers(FileStampDataCacher):
|
|||
source_path = posixize_path(os.path.relpath(path, base_path))
|
||||
logger.debug(
|
||||
'Read file %s -> %s',
|
||||
source_path, content_class.__name__)
|
||||
source_path, content_class.__name__,
|
||||
extra={'id': 'debug.readers.read-file'})
|
||||
|
||||
if not fmt:
|
||||
_, ext = os.path.splitext(os.path.basename(path))
|
||||
|
|
@ -497,7 +504,8 @@ class Readers(FileStampDataCacher):
|
|||
if preread_signal:
|
||||
logger.debug(
|
||||
'Signal %s.send(%s)',
|
||||
preread_signal.name, preread_sender)
|
||||
preread_signal.name, preread_sender,
|
||||
extra={'id': 'debug.readers.signal-send'})
|
||||
preread_signal.send(preread_sender)
|
||||
|
||||
reader = self.readers[fmt]
|
||||
|
|
@ -556,7 +564,8 @@ class Readers(FileStampDataCacher):
|
|||
logger.debug(
|
||||
'Signal %s.send(%s, <metadata>)',
|
||||
context_signal.name,
|
||||
context_sender)
|
||||
context_sender,
|
||||
extra={'id': 'debug.readers.signal-send-metadata'})
|
||||
context_signal.send(context_sender, metadata=metadata)
|
||||
|
||||
return content_class(content=content, metadata=metadata,
|
||||
|
|
@ -593,7 +602,7 @@ def find_empty_alt(content, path):
|
|||
'Empty alt attribute for image %s in %s',
|
||||
os.path.basename(match[1] + match[5]), path,
|
||||
extra={'limit_msg': 'Other images have empty alt attributes',
|
||||
'id': 'warn.img.alt.empty'})
|
||||
'id': 'warn.readers.empty-alt-attribute'})
|
||||
|
||||
|
||||
def default_metadata(settings=None, process=None):
|
||||
|
|
|
|||
|
|
@ -156,13 +156,17 @@ def read_settings(path=None, override=None):
|
|||
local_settings[p] = absp
|
||||
|
||||
if 'PLUGIN_PATH' in local_settings:
|
||||
logger.warning('PLUGIN_PATH setting has been replaced by '
|
||||
'PLUGIN_PATHS, moving it to the new setting name.')
|
||||
logger.warning(
|
||||
'PLUGIN_PATH setting has been replaced by '
|
||||
'PLUGIN_PATHS, moving it to the new setting name.',
|
||||
extra={'id': 'warn.settings.plugin-path-deprecated'})
|
||||
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 PLUGIN_PATHS setting as string "
|
||||
"has been deprecated (should be a list)")
|
||||
logger.warning(
|
||||
"Defining PLUGIN_PATHS setting as string "
|
||||
"has been deprecated (should be a list)",
|
||||
extra={'id': 'warn.settings.plugin-paths-is-a-string'})
|
||||
local_settings['PLUGIN_PATHS'] = [local_settings['PLUGIN_PATHS']]
|
||||
elif local_settings['PLUGIN_PATHS'] is not None:
|
||||
def getabs(path, pluginpath):
|
||||
|
|
@ -267,7 +271,8 @@ def configure_settings(settings):
|
|||
logger.warn(
|
||||
'Detected misconfigured %s (%s), '
|
||||
'falling back to the default (%s)',
|
||||
key, value, DEFAULT_CONFIG[key])
|
||||
key, value, DEFAULT_CONFIG[key],
|
||||
extra={'id': 'warn.settings.misconfigured-setting'})
|
||||
|
||||
# try to set the different locales, fallback on the default.
|
||||
locales = settings.get('LOCALE', DEFAULT_CONFIG['LOCALE'])
|
||||
|
|
@ -279,14 +284,17 @@ def configure_settings(settings):
|
|||
except locale.Error:
|
||||
pass
|
||||
else:
|
||||
logger.warning("LOCALE option doesn't contain a correct value")
|
||||
logger.warning("LOCALE option doesn't contain a correct value",
|
||||
extra={'id': 'warn.settings.incorrect-locale'})
|
||||
|
||||
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.")
|
||||
logger.warning(
|
||||
"Removed extraneous trailing slash from SITEURL.",
|
||||
extra={'id': 'warn.settings.siteurl-trailing-slash'})
|
||||
# If SITEURL is defined but FEED_DOMAIN isn't,
|
||||
# set FEED_DOMAIN to SITEURL
|
||||
if 'FEED_DOMAIN' not in settings:
|
||||
|
|
@ -298,7 +306,8 @@ def configure_settings(settings):
|
|||
settings.get('WITH_FUTURE_DATES', False):
|
||||
logger.warning(
|
||||
"WITH_FUTURE_DATES conflicts with CONTENT_CACHING_LAYER "
|
||||
"set to 'generator', use 'reader' layer instead")
|
||||
"set to 'generator', use 'reader' layer instead",
|
||||
extra={'id': 'warn.settings.conflicting-cache-setting'})
|
||||
|
||||
# Warn if feeds are generated with both SITEURL & FEED_DOMAIN undefined
|
||||
feed_keys = [
|
||||
|
|
@ -313,14 +322,16 @@ def configure_settings(settings):
|
|||
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')
|
||||
' not be valid',
|
||||
extra={'id': 'warn.settings.not-set-siteurl'})
|
||||
|
||||
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')
|
||||
'for more information',
|
||||
extra={'id': 'warn.settings.no-timezone'})
|
||||
|
||||
# fix up pagination rules
|
||||
from pelican.paginator import PaginationRule
|
||||
|
|
@ -342,7 +353,8 @@ def configure_settings(settings):
|
|||
if old_key in settings:
|
||||
logger.warning(
|
||||
'Deprecated setting %s, moving it to %s list',
|
||||
old_key, new_key)
|
||||
old_key, new_key,
|
||||
extra={'id': 'warn.settings.dir-paths-setting-deprecated'})
|
||||
settings[new_key] = [settings[old_key]] # also make a list
|
||||
del settings[old_key]
|
||||
|
||||
|
|
@ -367,15 +379,18 @@ def configure_settings(settings):
|
|||
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)
|
||||
PATH_KEY,
|
||||
extra={'id': 'warn.settings.setting-must-be-list'})
|
||||
settings[PATH_KEY] = DEFAULT_CONFIG[PATH_KEY]
|
||||
|
||||
# Save people from declaring MD_EXTENSIONS as a list rather than a dict
|
||||
if not isinstance(settings.get('MD_EXTENSIONS', {}), dict):
|
||||
logger.warning('The format of the MD_EXTENSIONS setting has '
|
||||
'changed. It should now be a dict mapping '
|
||||
'fully-qualified extension names to their '
|
||||
'configurations. Falling back to the default.')
|
||||
logger.warning(
|
||||
'The format of the MD_EXTENSIONS setting has '
|
||||
'changed. It should now be a dict mapping '
|
||||
'fully-qualified extension names to their '
|
||||
'configurations. Falling back to the default.',
|
||||
extra={'id': 'warn.settings.bad-format-of-md-extensions'})
|
||||
settings['MD_EXTENSIONS'] = DEFAULT_CONFIG['MD_EXTENSIONS']
|
||||
|
||||
# Add {PAGE,ARTICLE}_PATHS to {ARTICLE,PAGE}_EXCLUDES
|
||||
|
|
@ -401,6 +416,7 @@ def configure_settings(settings):
|
|||
old, new)
|
||||
if doc:
|
||||
message += ', see {} for details'.format(doc)
|
||||
logger.warning(message)
|
||||
logger.warning(message, extra={
|
||||
'id': 'warn.settings.setting-was-removed'})
|
||||
|
||||
return settings
|
||||
|
|
|
|||
|
|
@ -152,7 +152,9 @@ def wp2fields(xml, wp_custpost=False):
|
|||
title = unescape(item.title.contents[0])
|
||||
except IndexError:
|
||||
title = 'No title [%s]' % item.find('post_name').string
|
||||
logger.warning('Post "%s" is lacking a proper title', title)
|
||||
logger.warning(
|
||||
'Post "%s" is lacking a proper title', title,
|
||||
extra={'id': 'warn.pelican-import.post-no-proper-title'})
|
||||
|
||||
filename = item.find('post_name').string
|
||||
post_id = item.find('post_id').string
|
||||
|
|
@ -671,7 +673,9 @@ def download_attachments(output_path, urls):
|
|||
locations.append(os.path.join(localpath, filename))
|
||||
except (URLError, IOError) as e:
|
||||
# Python 2.7 throws an IOError rather Than URLError
|
||||
logger.warning("No file could be downloaded from %s\n%s", url, e)
|
||||
logger.warning(
|
||||
"No file could be downloaded from %s\n%s", url, e,
|
||||
extra={'id': 'warn.pelican-import.no-attachments-downloaded'})
|
||||
return locations
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -97,7 +97,8 @@ class URLWrapper(object):
|
|||
setting = "%s_%s" % (self.__class__.__name__.upper(), key)
|
||||
value = self.settings[setting]
|
||||
if not isinstance(value, six.string_types):
|
||||
logger.warning('%s is set to %s', setting, value)
|
||||
logger.warning('%s is set to %s', setting, value, extra={
|
||||
'id': 'warn.urlwrappers.setting-is-not-a-string'})
|
||||
return value
|
||||
else:
|
||||
if get_page_name:
|
||||
|
|
|
|||
|
|
@ -206,9 +206,11 @@ def deprecated_attribute(old, new, since=None, remove=None, doc=None):
|
|||
message.append(
|
||||
' and will be removed by version {}'.format(version))
|
||||
message.append('. Use {} instead.'.format(new))
|
||||
logger.warning(''.join(message))
|
||||
logger.warning(''.join(message), extra={
|
||||
'id': 'warn.utils.attribute-deprecated'})
|
||||
logger.debug(''.join(six.text_type(x) for x
|
||||
in traceback.format_stack()))
|
||||
in traceback.format_stack()),
|
||||
extra={'id': 'debug.utils.attribute-deprecated'})
|
||||
|
||||
def fget(self):
|
||||
_warn()
|
||||
|
|
@ -318,7 +320,8 @@ def copy(source, destination, ignores=None):
|
|||
|
||||
def walk_error(err):
|
||||
logger.warning("While copying %s: %s: %s",
|
||||
source_, err.filename, err.strerror)
|
||||
source_, err.filename, err.strerror,
|
||||
extra={'id': 'warn.utils.copy-walk-error'})
|
||||
|
||||
source_ = os.path.abspath(os.path.expanduser(source))
|
||||
destination_ = os.path.abspath(os.path.expanduser(destination))
|
||||
|
|
@ -328,24 +331,29 @@ def copy(source, destination, ignores=None):
|
|||
|
||||
if any(fnmatch.fnmatch(os.path.basename(source), ignore)
|
||||
for ignore in ignores):
|
||||
logger.info('Not copying %s due to ignores', source_)
|
||||
logger.info('Not copying %s due to ignores', source_,
|
||||
extra={'id': 'info.utils.not-copying-ignore'})
|
||||
return
|
||||
|
||||
if os.path.isfile(source_):
|
||||
dst_dir = os.path.dirname(destination_)
|
||||
if not os.path.exists(dst_dir):
|
||||
logger.info('Creating directory %s', dst_dir)
|
||||
logger.info('Creating directory %s', dst_dir,
|
||||
extra={'id': 'info.utils.creating-directory'})
|
||||
os.makedirs(dst_dir)
|
||||
logger.info('Copying %s to %s', source_, destination_)
|
||||
logger.info('Copying %s to %s', source_, destination_,
|
||||
extra={'id': 'info.utils.copying'})
|
||||
shutil.copy2(source_, destination_)
|
||||
|
||||
elif os.path.isdir(source_):
|
||||
if not os.path.exists(destination_):
|
||||
logger.info('Creating directory %s', destination_)
|
||||
logger.info('Creating directory %s', destination_,
|
||||
extra={'id': 'info.utils.creating-directory'})
|
||||
os.makedirs(destination_)
|
||||
if not os.path.isdir(destination_):
|
||||
logger.warning('Cannot copy %s (a directory) to %s (a file)',
|
||||
source_, destination_)
|
||||
source_, destination_,
|
||||
extra={'id': 'warn.utils.cannot-copy-dir-to-file'})
|
||||
return
|
||||
|
||||
for src_dir, subdirs, others in os.walk(source_):
|
||||
|
|
@ -358,7 +366,8 @@ def copy(source, destination, ignores=None):
|
|||
for i in ignores))
|
||||
|
||||
if not os.path.isdir(dst_dir):
|
||||
logger.info('Creating directory %s', dst_dir)
|
||||
logger.info('Creating directory %s', dst_dir,
|
||||
extra={'id': 'warn.utils.creating-directory'})
|
||||
# Parent directories are known to exist, so 'mkdir' suffices.
|
||||
os.mkdir(dst_dir)
|
||||
|
||||
|
|
@ -366,19 +375,22 @@ def copy(source, destination, ignores=None):
|
|||
src_path = os.path.join(src_dir, o)
|
||||
dst_path = os.path.join(dst_dir, o)
|
||||
if os.path.isfile(src_path):
|
||||
logger.info('Copying %s to %s', src_path, dst_path)
|
||||
logger.info('Copying %s to %s', src_path, dst_path,
|
||||
extra={'id': 'info.utils.copying'})
|
||||
shutil.copy2(src_path, dst_path)
|
||||
else:
|
||||
logger.warning('Skipped copy %s (not a file or '
|
||||
'directory) to %s',
|
||||
src_path, dst_path)
|
||||
src_path, dst_path,
|
||||
extra={'id': 'warn.utils.skipped-copy'})
|
||||
|
||||
|
||||
def clean_output_dir(path, retention):
|
||||
"""Remove all files from output directory except those in retention list"""
|
||||
|
||||
if not os.path.exists(path):
|
||||
logger.debug("Directory already removed: %s", path)
|
||||
logger.debug("Directory already removed: %s", path,
|
||||
extra={'id': 'warn.utils.directory-already-removed'})
|
||||
return
|
||||
|
||||
if not os.path.isdir(path):
|
||||
|
|
@ -393,18 +405,21 @@ def clean_output_dir(path, retention):
|
|||
file = os.path.join(path, filename)
|
||||
if any(filename == retain for retain in retention):
|
||||
logger.debug("Skipping deletion; %s is on retention list: %s",
|
||||
filename, file)
|
||||
filename, file,
|
||||
extra={'id': 'debug.utils.skipping-deletion'})
|
||||
elif os.path.isdir(file):
|
||||
try:
|
||||
shutil.rmtree(file)
|
||||
logger.debug("Deleted directory %s", file)
|
||||
logger.debug("Deleted directory %s", file,
|
||||
extra={'id': 'debug.utils.deleted-directory'})
|
||||
except Exception as e:
|
||||
logger.error("Unable to delete directory %s; %s",
|
||||
file, e)
|
||||
elif os.path.isfile(file) or os.path.islink(file):
|
||||
try:
|
||||
os.remove(file)
|
||||
logger.debug("Deleted file/link %s", file)
|
||||
logger.debug("Deleted file/link %s", file,
|
||||
extra={'id': 'debug.utils.deleted-file'})
|
||||
except Exception as e:
|
||||
logger.error("Unable to delete file %s; %s", file, e)
|
||||
else:
|
||||
|
|
@ -629,10 +644,14 @@ def process_translations(content_list, order_by=None):
|
|||
lang_items = list(lang_items)
|
||||
len_ = len(lang_items)
|
||||
if len_ > 1:
|
||||
logger.warning('There are %s variants of "%s" with lang %s',
|
||||
len_, slug, lang)
|
||||
logger.warning(
|
||||
'There are %s variants of "%s" with lang %s',
|
||||
len_, slug, lang,
|
||||
extra={'id': 'warn.utils.many-translation-variants'})
|
||||
for x in lang_items:
|
||||
logger.warning('\t%s', x.source_path)
|
||||
logger.warning(
|
||||
'\t%s', x.source_path,
|
||||
extra={'id': 'warn.utils.many-translation-variants'})
|
||||
|
||||
# find items with default language
|
||||
default_lang_items = list(filter(
|
||||
|
|
@ -647,7 +666,8 @@ def process_translations(content_list, order_by=None):
|
|||
logger.warning(
|
||||
'Empty slug for %s. You can fix this by '
|
||||
'adding a title or a slug to your content',
|
||||
default_lang_items[0].source_path)
|
||||
default_lang_items[0].source_path,
|
||||
extra={'id': 'warn.utils.empty-slug'})
|
||||
index.extend(default_lang_items)
|
||||
translations.extend([x for x in items if x not in default_lang_items])
|
||||
for a in items:
|
||||
|
|
@ -677,11 +697,13 @@ def process_translations(content_list, order_by=None):
|
|||
except AttributeError:
|
||||
logger.warning(
|
||||
'There is no "%s" attribute in the item '
|
||||
'metadata. Defaulting to slug order.', order_by)
|
||||
'metadata. Defaulting to slug order.', order_by,
|
||||
extra={'id': 'warn.utils.translations-index-sorting'})
|
||||
else:
|
||||
logger.warning(
|
||||
'Invalid *_ORDER_BY setting (%s).'
|
||||
'Valid options are strings and functions.', order_by)
|
||||
'Valid options are strings and functions.', order_by,
|
||||
extra={'id': 'warn.utils.order-by-is-invalid'})
|
||||
|
||||
return index, translations
|
||||
|
||||
|
|
@ -704,7 +726,9 @@ def folder_watcher(path, extensions, ignores=[]):
|
|||
try:
|
||||
yield os.stat(os.path.join(root, f)).st_mtime
|
||||
except OSError as e:
|
||||
logger.warning('Caught Exception: %s', e)
|
||||
logger.warning(
|
||||
'Caught Exception: %s', e,
|
||||
extra={'id': 'warn.utils.caugh-exception'})
|
||||
|
||||
LAST_MTIME = 0
|
||||
while True:
|
||||
|
|
@ -727,7 +751,9 @@ def file_watcher(path):
|
|||
try:
|
||||
mtime = os.stat(path).st_mtime
|
||||
except OSError as e:
|
||||
logger.warning('Caught Exception: %s', e)
|
||||
logger.warning(
|
||||
'Caught Exception: %s', e,
|
||||
extra={'id': 'warn.utils.caugh-exception'})
|
||||
continue
|
||||
|
||||
if mtime > LAST_MTIME:
|
||||
|
|
|
|||
|
|
@ -74,11 +74,13 @@ class Writer(object):
|
|||
raise RuntimeError('File %s is set to be overridden twice'
|
||||
% filename)
|
||||
else:
|
||||
logger.info('Skipping %s', filename)
|
||||
logger.info('Skipping %s', filename,
|
||||
extra={'id': 'info.writers.skip'})
|
||||
filename = os.devnull
|
||||
elif filename in self._written_files:
|
||||
if override:
|
||||
logger.info('Overwriting %s', filename)
|
||||
logger.info('Overwriting %s', filename,
|
||||
extra={'id': 'info.writers.overwrite'})
|
||||
else:
|
||||
raise RuntimeError('File %s is to be overwritten' % filename)
|
||||
if override:
|
||||
|
|
@ -129,7 +131,8 @@ class Writer(object):
|
|||
encoding = 'utf-8' if six.PY3 else None
|
||||
with self._open_w(complete_path, encoding, override_output) as fp:
|
||||
feed.write(fp, 'utf-8')
|
||||
logger.info('Writing %s', complete_path)
|
||||
logger.info('Writing %s', complete_path,
|
||||
extra={'id': 'info.writers.write-feed'})
|
||||
|
||||
signals.feed_written.send(
|
||||
complete_path, context=context, feed=feed)
|
||||
|
|
@ -174,7 +177,8 @@ class Writer(object):
|
|||
|
||||
with self._open_w(path, 'utf-8', override=override) as f:
|
||||
f.write(output)
|
||||
logger.info('Writing %s', path)
|
||||
logger.info('Writing %s', path,
|
||||
extra={'id': 'into.writers.render-template-to-file'})
|
||||
|
||||
# Send a signal to say we're writing a file with some specific
|
||||
# local context.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue