diff --git a/docs/changelog.rst b/docs/changelog.rst index ba523a9..357e169 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -22,6 +22,8 @@ Released on 2014-xx-xx. ``albums_sort_reverse``, ``medias_sort_attr``, ``medias_sort_reverse``. - New setting ``autorotate_images`` to disable autorotation of images, and warn about the incompatibility between autorotation and EXIF copy. +- New settings ``ignore_directories`` and ``ignore_files`` to filter + directories and files with pattern matching. Version 0.6.0 ~~~~~~~~~~~~~ diff --git a/sigal/gallery.py b/sigal/gallery.py index d924e25..b9846ee 100644 --- a/sigal/gallery.py +++ b/sigal/gallery.py @@ -24,6 +24,7 @@ from __future__ import absolute_import, print_function import codecs +import fnmatch import logging import markdown import multiprocessing @@ -393,19 +394,42 @@ class Gallery(object): albums = self.albums = {} src_path = self.settings['source'] + ignore_dirs = settings['ignore_directories'] + ignore_files = settings['ignore_files'] + for path, dirs, files in os.walk(src_path, followlinks=True, topdown=False): relpath = os.path.relpath(path, src_path) + # Test if the directory match the ignore_dirs settings + if ignore_dirs and any(fnmatch.fnmatch(relpath, ignore) + for ignore in ignore_dirs): + self.logger.info('Ignoring %s', relpath) + continue + + # Remove files that match the ignore_files settings + if ignore_files: + files_path = {join(relpath, f) for f in files} + for ignore in ignore_files: + files_path -= set(fnmatch.filter(files_path, ignore)) + + self.logger.debug('Files before filtering: %r', files) + files = [os.path.split(f)[1] for f in files_path] + self.logger.debug('Files after filtering: %r', files) + + # Remove sub-directories that have been ignored in a previous + # iteration (as topdown=False, sub-directories are processed before + # their parent for d in dirs[:]: path = join(relpath, d) if relpath != '.' else d if path not in albums.keys(): dirs.remove(d) - album = Album(relpath, self.settings, dirs, files, self) + album = Album(relpath, settings, dirs, files, self) if not album.medias and not album.albums: self.logger.info('Skip empty album: %r', album) + # TODO delete empty directories else: albums[relpath] = album diff --git a/sigal/settings.py b/sigal/settings.py index 138a533..4d4d8e5 100644 --- a/sigal/settings.py +++ b/sigal/settings.py @@ -28,6 +28,7 @@ from pprint import pformat from .compat import PY2 + _DEFAULT_CONFIG = { 'adjust_options': {'color': 1.0, 'brightness': 1.0, 'contrast': 1.0, 'sharpness': 1.0}, @@ -38,6 +39,8 @@ _DEFAULT_CONFIG = { 'destination': '_build', 'files_to_copy': (), 'google_analytics': '', + 'ignore_directories': [], + 'ignore_files': [], 'img_ext_list': ['.jpg', '.jpeg', '.JPG', '.JPEG', '.png'], 'img_processor': 'ResizeToFit', 'img_size': (640, 480), diff --git a/sigal/templates/sigal.conf.py b/sigal/templates/sigal.conf.py index 2b4509d..8921d04 100644 --- a/sigal/templates/sigal.conf.py +++ b/sigal/templates/sigal.conf.py @@ -71,6 +71,12 @@ thumb_size = (280, 210) # Reverse sort for medias # medias_sort_reverse = False +# Filter directories and files. +# The settings take a list of patterns matched with the fnmatch module: +# http://docs.python.org/2/library/fnmatch.html +ignore_directories = [] +ignore_files = [] + # Jpeg options # jpg_options = {'quality': 85, # 'optimize': True, diff --git a/tests/test_gallery.py b/tests/test_gallery.py index eba577b..20ea521 100644 --- a/tests/test_gallery.py +++ b/tests/test_gallery.py @@ -197,3 +197,18 @@ def test_empty_dirs(settings): gal = Gallery(settings, ncpu=1) assert 'empty' not in gal.albums assert 'dir1/empty' not in gal.albums + + +def test_ignores(settings, tmpdir): + tmp = str(tmpdir) + settings['destination'] = tmp + settings['ignore_directories'] = ['*test2'] + settings['ignore_files'] = ['dir2/Hubble*', '*.png'] + gal = Gallery(settings, ncpu=1) + gal.build() + + assert 'test2' not in os.listdir(join(tmp, 'dir1')) + assert 'archlinux-kiss-1024x640.png' not in os.listdir( + join(tmp, 'dir1', 'test1')) + assert 'Hubble Interacting Galaxy NGC 5257.jpg' not in os.listdir( + join(tmp, 'dir2'))