varia.website/plugins/show_source/show_source.py

87 lines
3.2 KiB
Python

import os
import logging
from urlparse import urljoin
import six
from pelican import signals
from pelican.utils import pelican_open
if not six.PY3:
from codecs import open
logger = logging.getLogger(__name__)
source_files = []
PROCESS = ['articles', 'pages', 'drafts']
def link_source_files(generator):
"""
Processes each article/page object and formulates copy from and copy
to destinations, as well as adding a source file URL as an attribute.
"""
# Get all attributes from the generator that are articles or pages
posts = [
getattr(generator, attr, None) for attr in PROCESS
if getattr(generator, attr, None) is not None]
# Work on each item
for post in posts[0]:
if not 'SHOW_SOURCE_ON_SIDEBAR' in generator.settings and \
not 'SHOW_SOURCE_IN_SECTION' in generator.settings:
return
# Only try this when specified in metadata or SHOW_SOURCE_ALL_POSTS
# override is present in settings
if 'SHOW_SOURCE_ALL_POSTS' in generator.settings or \
'show_source' in post.metadata:
# Source file name can be optionally set in config
show_source_filename = generator.settings.get(
'SHOW_SOURCE_FILENAME', '{}.txt'.format(post.slug)
)
try:
# Get the full path to the original source file
source_out = os.path.join(
post.settings['OUTPUT_PATH'], post.save_as
)
# Get the path to the original source file
source_out_path = os.path.split(source_out)[0]
# Create 'copy to' destination for writing later
copy_to = os.path.join(
source_out_path, show_source_filename
)
# Add file to published path
source_url = urljoin(
post.save_as, show_source_filename
)
except Exception:
return
# Format post source dict & populate
out = dict()
out['copy_raw_from'] = post.source_path
out['copy_raw_to'] = copy_to
logger.debug('Linked %s to %s', post.source_path, copy_to)
source_files.append(out)
# Also add the source path to the post as an attribute for tpls
post.show_source_url = source_url
def _copy_from_to(from_file, to_file):
"""
A very rough and ready copy from / to function.
"""
with pelican_open(from_file) as text_in:
encoding = 'utf-8'
with open(to_file, 'w', encoding=encoding) as text_out:
text_out.write(text_in)
logger.info('Writing %s', to_file)
def write_source_files(*args, **kwargs):
"""
Called by the `page_writer_finalized` signal to process source files.
"""
for source in source_files:
_copy_from_to(source['copy_raw_from'], source['copy_raw_to'])
def register():
"""
Calls the shots, based on signals
"""
signals.article_generator_finalized.connect(link_source_files)
signals.page_generator_finalized.connect(link_source_files)
signals.page_writer_finalized.connect(write_source_files)