diff --git a/sigal/gallery.py b/sigal/gallery.py index ce738c8..86273d8 100644 --- a/sigal/gallery.py +++ b/sigal/gallery.py @@ -35,6 +35,7 @@ from datetime import datetime 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 click import get_terminal_size, progressbar from natsort import natsort_keygen, ns @@ -604,6 +605,40 @@ class Gallery: 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 2d655df..3c8bc60 100644 --- a/sigal/settings.py +++ b/sigal/settings.py @@ -39,6 +39,9 @@ _DEFAULT_CONFIG = { '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 3481768..1ff3d38 100644 --- a/sigal/templates/sigal.conf.py +++ b/sigal/templates/sigal.conf.py @@ -148,6 +148,15 @@ thumb_size = (280, 210) # 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