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