diff --git a/docs/settings.rst b/docs/settings.rst index 282ce912..971c55dc 100644 --- a/docs/settings.rst +++ b/docs/settings.rst @@ -21,7 +21,7 @@ this file will be passed to the templates as well. ================================================ ===================================================== -Setting name (default value) what does it do? +Setting name (default value) what does it do? ================================================ ===================================================== `AUTHOR` Default author (put your name) `CATEGORY_FEED` ('feeds/%s.atom.xml'[1]_) Where to put the atom categories feeds. @@ -32,7 +32,7 @@ Setting name (default value) what does it do? `DEFAULT_CATEGORY` (``'misc'``) The default category to fallback on. `DEFAULT_DATE_FORMAT` (``'%a %d %B %Y'``) The default date format you want to use. `DEFAULT_LANG` (``'en'``) The default language to use. -`DEFAULT_METADATA` (``()``) A list containing the default metadata for +`DEFAULT_METADATA` (``()``) A list containing the default metadata for each content (articles, pages, etc.) `DEFAULT_ORPHANS` (0) The minimum number of articles allowed on the last page. Use this when you don't want to @@ -47,8 +47,11 @@ Setting name (default value) what does it do? informations from the metadata `FEED` (``'feeds/all.atom.xml'``) relative url to output the atom feed. `FEED_RSS` (``None``, i.e. no RSS) relative url to output the rss feed. +`FILES_TO_COPY` (``()``, no files) A list of tuples (source, destination) of files + to copy from the source directory to the + output path `JINJA_EXTENSIONS` (``[]``) A list of any Jinja2 extensions you want to use. -`DELETE_OUTPUT_DIRECTORY` (``False``) Delete the output directory instead of just updating all +`DELETE_OUTPUT_DIRECTORY` (``False``) Delete the output directory instead of just updating all the generated files. `LOCALE` (''[2]_) Change the locale. `MARKUP` (``('rst', 'md')``) A list of available markup languages you want diff --git a/pelican/generators.py b/pelican/generators.py index 3948afdc..97c28631 100755 --- a/pelican/generators.py +++ b/pelican/generators.py @@ -11,7 +11,7 @@ import random from jinja2 import Environment, FileSystemLoader from jinja2.exceptions import TemplateNotFound -from pelican.utils import copytree, get_relative_path, process_translations, open +from pelican.utils import copy, get_relative_path, process_translations, open from pelican.contents import Article, Page, is_valid_content from pelican.readers import read_file from pelican.log import * @@ -298,9 +298,10 @@ class StaticGenerator(Generator): def _copy_paths(self, paths, source, destination, output_path, final_path=None): + """Copy all the paths from source to destination""" for path in paths: - copytree(path, source, os.path.join(output_path, destination), - final_path) + copy(path, source, os.path.join(output_path, destination), final_path, + overwrite=True) def generate_output(self, writer): self._copy_paths(self.settings['STATIC_PATHS'], self.path, @@ -308,6 +309,10 @@ class StaticGenerator(Generator): self._copy_paths(self.settings['THEME_STATIC_PATHS'], self.theme, 'theme', self.output_path, '.') + # copy all the files needed + for source, destination in self.settings['FILES_TO_COPY']: + copy(source, self.path, self.output_path, destination, overwrite=True) + class PdfGenerator(Generator): """Generate PDFs on the output dir, for all articles and pages coming from diff --git a/pelican/settings.py b/pelican/settings.py index c42a8bb0..a744f465 100644 --- a/pelican/settings.py +++ b/pelican/settings.py @@ -38,6 +38,7 @@ _DEFAULT_CONFIG = {'PATH': None, 'DEFAULT_PAGINATION': 5, 'DEFAULT_ORPHANS': 0, 'DEFAULT_METADATA': (), + 'FILES_TO_COPY': (), } def read_settings(filename): diff --git a/pelican/utils.py b/pelican/utils.py index 6b456e17..41733149 100644 --- a/pelican/utils.py +++ b/pelican/utils.py @@ -42,20 +42,38 @@ def slugify(value): value = unicode(re.sub('[^\w\s-]', '', value).strip().lower()) return re.sub('[-\s]+', '-', value) -def copytree(path, origin, destination, topath=None): - """Copy path from origin to destination, silent any errors""" - - if not topath: - topath = path - try: - fromp = os.path.expanduser(os.path.join(origin, path)) - to = os.path.expanduser(os.path.join(destination, topath)) - shutil.copytree(fromp, to) - info('copying %s to %s' % (fromp, to)) +def copy(path, source, destination, destination_path=None, overwrite=False): + """Copy path from origin to destination. - except OSError: - pass + The function is able to copy either files or directories. + :param path: the path to be copied from the source to the destination + :param source: the source dir + :param destination: the destination dir + :param destination_path: the destination path (optional) + :param overwrite: wether to overwrite the destination if already exists or not + + """ + if not destination_path: + destination_path = path + + source_ = os.path.abspath(os.path.expanduser(os.path.join(source, path))) + destination_ = os.path.abspath( + os.path.expanduser(os.path.join(destination, destination_path))) + + if os.path.isdir(source_): + try: + shutil.copytree(source_, destination_) + info('copying %s to %s' % (source_, destination_)) + except OSError: + if overwrite: + shutil.rmtree(destination_) + shutil.copytree(source_, destination_) + info('replacement of %s with %s' % (source_, destination_)) + + elif os.path.isfile(source_): + shutil.copy(source_, destination_) + info('copying %s to %s' % (source_, destination_)) def clean_output_dir(path): """Remove all the files from the output directory""" diff --git a/samples/content/extra/robots.txt b/samples/content/extra/robots.txt new file mode 100644 index 00000000..ae5b0d05 --- /dev/null +++ b/samples/content/extra/robots.txt @@ -0,0 +1,2 @@ +User-agent: * +Disallow: /static/pictures diff --git a/samples/pelican.conf.py b/samples/pelican.conf.py index 20eb1605..2cb9df27 100755 --- a/samples/pelican.conf.py +++ b/samples/pelican.conf.py @@ -27,4 +27,8 @@ SOCIAL = (('twitter', 'http://twitter.com/ametaireau'), # global metadata to all the contents DEFAULT_METADATA = (('yeah', 'it is'),) +# static paths will be copied under the same name STATIC_PATHS = ["pictures",] + +# A list of files to copy from the source to the destination +FILES_TO_COPY = (('extra/robots.txt', 'robots.txt'),)