diff --git a/docs/changelog.rst b/docs/changelog.rst index bac302c..ba650c0 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -14,10 +14,17 @@ Released on 2013-xx-xx. - Include symlinked directories in the source directory. - New setting to use symbolic links for original files (``orig_link``). - New setting for the video size (``video_size``). -- Avoid issues with corrupted exif data. - Add a colored formatter for verbose and debug modes. - ``webm_options`` is now a list with ffmpeg options, to allow better flexibility and compatibility with avconv. +- New setting to copy files from the source directory to the destination + (``files_to_copy``). + +Bugfixes: + +- Avoid issues with corrupted exif data. +- Fix exif data not read from .JPEG files. +- Fix whitespace issues with video filenames. Version 0.5.1 ~~~~~~~~~~~~~ diff --git a/sigal/__init__.py b/sigal/__init__.py index 21195d2..d6bc02a 100644 --- a/sigal/__init__.py +++ b/sigal/__init__.py @@ -45,6 +45,7 @@ from .gallery import Gallery from .log import init_logging from .pkgmeta import __version__ from .settings import read_settings +from .utils import copy _DEFAULT_CONFIG_FILE = 'sigal.conf.py' @@ -107,6 +108,13 @@ def build(source, destination, debug=False, verbose=False, force=False, gal = Gallery(settings, force=force, theme=theme, ncpu=ncpu) gal.build() + # copy extra files + for src, dst in settings['files_to_copy']: + src = os.path.join(settings['source'], src) + dst = os.path.join(settings['destination'], dst) + logger.debug('Copy %s to %s', src, dst) + copy(src, dst, symlink=settings['orig_link']) + print(('Done.\nProcessed {image} images ({image_skipped} skipped) and ' '{video} videos ({video_skipped} skipped) in {duration:.2f} ' 'seconds.').format(duration=time.time() - start_time, **gal.stats)) diff --git a/sigal/gallery.py b/sigal/gallery.py index e599148..be9d9ce 100644 --- a/sigal/gallery.py +++ b/sigal/gallery.py @@ -29,7 +29,6 @@ import logging import markdown import multiprocessing import os -import shutil import sys import zipfile @@ -40,6 +39,7 @@ from pprint import pformat from . import compat from .image import process_image from .log import colored, BLUE +from .utils import copy from .video import process_video from .writer import Writer @@ -320,14 +320,6 @@ def worker(args): return 'KeyboardException' -def copy(src, dst, symlink=False): - """Copy or symlink the file.""" - func = os.symlink if symlink else shutil.copy2 - if symlink and os.path.lexists(dst): - os.remove(dst) - func(src, dst) - - def get_metadata(path): """ Get album metadata from DESCRIPTION_FILE: diff --git a/sigal/settings.py b/sigal/settings.py index 2373a8b..2585b4c 100644 --- a/sigal/settings.py +++ b/sigal/settings.py @@ -31,6 +31,7 @@ _DEFAULT_CONFIG = { 'copy_exif_data': True, 'copyright': '', 'destination': '_build', + 'files_to_copy': (), 'google_analytics': '', 'img_ext_list': ['.jpg', '.jpeg', '.JPG', '.JPEG', '.png'], 'img_processor': 'ResizeToFit', diff --git a/sigal/templates/sigal.conf.py b/sigal/templates/sigal.conf.py index 139203b..7b04e7b 100644 --- a/sigal/templates/sigal.conf.py +++ b/sigal/templates/sigal.conf.py @@ -102,3 +102,8 @@ thumb_size = (280, 210) # Specify a different locale. If set to '', the default locale is used. # locale = '' + +# List of files to copy from the source directory to the destination. +# A symbolic link is used if ``orig_link`` is set to True (see above). +# files_to_copy = (('extra/robots.txt', 'robots.txt'), +# ('extra/favicon.ico', 'favicon.ico'),) diff --git a/sigal/utils.py b/sigal/utils.py new file mode 100644 index 0000000..4a40b16 --- /dev/null +++ b/sigal/utils.py @@ -0,0 +1,12 @@ +# -*- coding: utf-8 -*- + +import os +import shutil + + +def copy(src, dst, symlink=False): + """Copy or symlink the file.""" + func = os.symlink if symlink else shutil.copy2 + if symlink and os.path.lexists(dst): + os.remove(dst) + func(src, dst) diff --git a/tests/test_gallery.py b/tests/test_gallery.py index ea70932..7852c65 100644 --- a/tests/test_gallery.py +++ b/tests/test_gallery.py @@ -3,7 +3,7 @@ import os import pytest -from sigal.gallery import Gallery, PathsDb, get_metadata, copy +from sigal.gallery import Gallery, PathsDb, get_metadata from sigal.settings import read_settings CURRENT_DIR = os.path.dirname(__file__) @@ -128,16 +128,3 @@ def test_gallery(tmpdir): assert 'Sigal test gallery' in html - -def test_copy(tmpdir): - src = os.path.join(SAMPLE_DIR, 'pictures', 'dir2', - REF['dir2']['medias'][0]) - dst = str(tmpdir.join(REF['dir2']['medias'][0])) - copy(src, dst) - assert os.path.isfile(dst) - - src = os.path.join(SAMPLE_DIR, 'pictures', 'dir2', - REF['dir2']['medias'][1]) - dst = str(tmpdir.join(REF['dir2']['medias'][1])) - copy(src, dst, symlink=True) - assert os.path.islink(dst) diff --git a/tests/test_utils.py b/tests/test_utils.py new file mode 100644 index 0000000..a87ee3f --- /dev/null +++ b/tests/test_utils.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- + +import os +from sigal.utils import copy + +CURRENT_DIR = os.path.dirname(__file__) +SAMPLE_DIR = os.path.join(CURRENT_DIR, 'sample') + + +def test_copy(tmpdir): + filename = 'exo20101028-b-full.jpg' + src = os.path.join(SAMPLE_DIR, 'pictures', 'dir2', filename) + dst = str(tmpdir.join(filename)) + copy(src, dst) + assert os.path.isfile(dst) + + filename = 'm57_the_ring_nebula-587px.jpg' + src = os.path.join(SAMPLE_DIR, 'pictures', 'dir2', filename) + dst = str(tmpdir.join(filename)) + copy(src, dst, symlink=True) + assert os.path.islink(dst)