diff --git a/sigal/gallery.py b/sigal/gallery.py index daa52b84..8aae112d 100644 --- a/sigal/gallery.py +++ b/sigal/gallery.py @@ -38,6 +38,7 @@ from itertools import cycle from os.path import isfile, join, splitext from urllib.parse import quote as url_quote +from gi.repository import GExiv2 from . import image, video, signals from .image import (process_image, get_exif_tags, get_exif_data, get_size, @@ -570,6 +571,40 @@ def __init__(self, settings, ncpu=None, quiet=False): files = [os.path.split(f)[1] for f in files_path] self.logger.debug('Files after filtering: %r', files) + # Only keep files that match only_metadata and + # do not match ignore_metadata filters + ff = [] + tags_field = self.settings['xmp_tags_field'] + for f in files: + try: + tagstring = GExiv2.Metadata(join(src_path, f)).get(tags_field) + if tagstring is None or tagstring is '': + taglist = [] + else: + taglist = [x.strip() for x in tagstring.split(',')] + except RuntimeError: + # The file format is unknown to GExiv2: + # filters are not applicable, include file + taglist = None + + self.logger.debug('Taglist: %r', taglist) + if taglist is None: + keep = True + else: + if len(self.settings['include_xmp_tags'])>0 and len(set(self.settings['include_xmp_tags']).intersection(taglist))==0: + self.logger.debug('File %s dropped: does not match positive taglist', f) + keep = False + else: + # either no include filter was given, or there is a match + keep = True + if len(self.settings['exclude_xmp_tags'])>0 and len(set(self.settings['exclude_xmp_tags']).intersection(taglist))==0: + self.logger.debug('File %s dropped: matches exclude taglist', f) + keep = False + if keep: + ff.append(f) + files = ff + self.logger.debug('Files after tag filtering: %r', files) + # Remove sub-directories that have been ignored in a previous # iteration (as topdown=False, sub-directories are processed before # their parent diff --git a/sigal/settings.py b/sigal/settings.py index 8110d301..e4c3fac4 100644 --- a/sigal/settings.py +++ b/sigal/settings.py @@ -39,6 +39,9 @@ 'google_tag_manager': '', 'ignore_directories': [], 'ignore_files': [], + 'include_xmp_tags': [], + 'exclude_xmp_tags': [], + 'xmp_tags_field': 'Xmp.dc.subject', 'img_extensions': ['.jpg', '.jpeg', '.png', '.gif'], 'img_processor': 'ResizeToFit', 'img_size': (640, 480), diff --git a/sigal/templates/sigal.conf.py b/sigal/templates/sigal.conf.py index d70f9485..b7028b45 100644 --- a/sigal/templates/sigal.conf.py +++ b/sigal/templates/sigal.conf.py @@ -139,6 +139,15 @@ # http://docs.python.org/2/library/fnmatch.html ignore_directories = [] ignore_files = [] +# List of tags that the image must have to be included in gallery: +# (if empty, all images are included) +# include_xmp_tags = [] +# List of tags that the image must NOT have to be included in gallery: +# (if empty, all images are included) +# exclude_xmp_tags = [] +# The XMP property that holds the tag list: +# xmp_tags_field = 'Xmp.dc.subject' + # ------------- # Video options