SIGAL(1)

NAME
sigal - Sigal 2.6.2.dev6+g136c6caab [image: CI Status] [image]
 <https://github.com/saimn/sigal/actions>[image: codecov.io] [image]
 <https://codecov.io/gh/saimn/sigal>

Sigal is yet another simple static gallery generator. It's written in Python and it allows to build a static gallery of images with the following features:

•   Process directories recursively.

•   Generate HTML pages using Jinja2 <https://palletsprojects.com/p/jinja/> templates.

•   Relative links for a portable output.

•   Support themes, videos, EXIF tags, zip download.

•   Parallel processing.

•   MIT licensed.

    The idea behind Sigal is to ease the use of the javascript libraries like galleria <https://github.com/GalleriaJS/galleria>. These libraries do a great job to display the images, Sigal does what is missing: resize images, create thumbnails, generate HTML pages.

    Sigal requires Python 3.11+.

LINKS

•   Latest documentation on the website <https://sigal.readthedocs.io/en/latest/>

•   Source, issues and pull requests on GitHub <https://github.com/saimn/sigal/>

•   Releases on PyPI <https://pypi.org/project/sigal/>

THEMES & DEMO

Sigal comes with three themes, based on the colorbox <http://www.jacklmoore.com/colorbox>, galleria <https://github.com/GalleriaJS/galleria> and photoswipe <http://photoswipe.com> Javascript libraries:

•   colorbox demo <http://saimon.org/sigal-demo/colorbox/>

•   galleria demo <http://saimon.org/sigal-demo/galleria/>

•   photoswipe demo <http://saimon.org/sigal-demo/photoswipe/>

DOCUMENTATION

  Installation

With pip:

    $ pip install sigal

Or to install with optional dependencies (listed below):

    $ pip install sigal\[all,tests\]

To install the development version, see the Contributing guidelines <>.

Also, note that Sigal depends on Pillow <https://github.com/python-pillow/Pillow>, which needs specific libraries when building from sources. See their Installation documentation <https://pillow.readthedocs.io/en/stable/installation.html> for more details.

  Dependencies

The mandatory dependencies are:

•   Blinker

•   Click

•   Jinja2

•   natsort

•   Pilkit

•   Pillow

•   Python Markdown

    There are also a number of optional dependencies for the Plugins <>, installable with the [all] marker:

•   Brotli, zopfli (compress assets plugin)

•   feedgenerator (feeds plugin)

•   cryptography (encrypt plugin)

•   pillow-heif (HEIF/HEIC support)

  Packages

Some packages are available for Linux distributions:

•   Archlinux <https://www.archlinux.org/packages/community/any/sigal/>

•   Gentoo <https://packages.gentoo.org/packages/media-gfx/sigal>

•   OpenSuse <https://build.opensuse.org/package/show/openSUSE:Factory/python-sigal>

•   NixOS <https://nixos.org/nixos/packages.html#sigal>

  Getting started

  How to Use

Initialize
    To get started, just run sigal init which will copy an example configuration file <> in the current directory.

    All configuration values have a default; values that are commented out serve to show the default. Default values are specified when modified in this example config file.

Build
    After adapting the configuration to your needs, put your images in a sub-directory and run sigal build <your images directory>.

    The next time you run sigal build, only the new images will be processed. You can use the -f flag to force the reprocessing of all the images or the -a flag to force only the specified matching albums. Images (resp. videos) that are smaller than the size specified by the img_size (resp. video_size) setting will not be resized.

    You may also want to know how to specify information about albums <> and images <>.

Serve
    To visualize your gallery, you can use sigal serve which runs a basic web server. This server should only be used for local browsing, not in production.

    Another option is to use the index_in_url = True setting, which will add index.html to the urls to allow browsing without a server.

  Help on the sigal build command

    $ sigal build [-h] [-d] [-v] [-f] [-a PATTERN] [-c CONFIG] [-t THEME] [-n NCPU]
            [source] [destination]

Required arguments:

source
    Input directory

destination
    Output directory (default: _build/)

    Optional arguments:

-h, --help
    Show this help message and exit

-f, --force
    Force the reprocessing of existing images and thumbnails

-a --force-album
    Force the reprocessing of existing images matching the given album wildcard pattern. Patterns containing wildcards will be matched against the full album path, while patterns without wildcards will be match against the album name only:

        -a 'My Pictures/*Pics'
                My Pictures/Old Pics => Force
                My Pictures/New Pics => Force
                My Pictures/Pictures => No Force
        -a 'Landscapes'
                My Pictures/Landscapes => Force
                My Other Pictures/Landscapes => Force

-v, --verbose
    Show all messages

-d, --debug
    Show all message, including debug messages

-c CONFIG, --config CONFIG
    Configuration file (default: sigal.conf.py in the current working directory)

-t THEME, --theme THEME
    Specify a theme directory, or a theme name for the themes included with Sigal

-n NCPU, --ncpu NCPU
    Number of cpu to use (default: all)

  Help on the sigal serve command

    $ sigal serve [-c CONFIG] [-p PORT] [destination]

Optional arguments:

-c CONFIG, --config CONFIG
    Configuration file (default: sigal.conf.py in the current working directory)

-p PORT, --port PORT
    Port number to start the server on (default: 8000)

destination
    Destination directory where the output of build is located (default: _build)

  Configuration

The configuration must be set in a sigal.conf.py file in the current directory. It can also be specified with the -c flag. An example file with explanations on the settings is available in sigal/templates/sigal.conf.py and is shown below. This file is copied to the current directory with the sigal init commmand.

    # All configuration values have a default; values that are commented out serve
    # to show the default. Default values are specified when modified in this
    # example config file
    # Gallery title. Can be set here or as the '--title' option of the `sigal
    # build` command, or in the 'index.md' file of the source directory.
    # The priority order is: cli option > settings file > index.md file
    # title = "Sigal test gallery"
    # ---------------------
    # General configuration
    # ---------------------
    # Source directory. Can be set here or as the first argument of the `sigal
    # build` command
    source = "pictures"
    # Destination directory. Can be set here or as the second argument of the
    # `sigal build` command (default: '_build')
    # destination = '_build'
    # Theme :
    # - colorbox (default), galleria, photoswipe, or the path to a custom theme
    # directory
    theme = "galleria"
    # Theme for galleria (https://galleriajs.github.io/themes/)
    # galleria_theme = 'classic'
    # Author. Used in the footer of the pages and in the author meta tag.
    # author = ''
    # Use originals in gallery (default: False). If True, this will bypass all
    # processing steps (resize, auto-orient, recompress, and any plugin-specific
    # step).
    # Originals will be symlinked if orig_link = True, else they will be copied.
    # use_orig = False
    # Path to a CSS file that can be used to customize themes
    # user_css =
    # Enable autoplay (galleria only)
    # autoplay = False
    # ----------------
    # Image processing (ignored if use_orig = True)
    # ----------------
    # Size of resized image (default: (640, 480))
    img_size = (800, 600)
    # Max input image size in pixels (default: None, i.e. use PIL default)
    # This option sets `PIL.Image.MAX_IMAGE_PIXELS` in case you want to
    # convert/resize very large images.
    # max_img_pixels = None
    # Output format of images (default: None, i.e. use input format)
    # img_format = "JPEG"
    # Show a map of the images where possible?
    # This option only has an effect on the galleria theme for the while.
    # The leaflet_provider setting allow to customize the tile provider (see
    # https://github.com/leaflet-extras/leaflet-providers#providers)
    # show_map = False
    # leaflet_provider = 'OpenStreetMap.Mapnik'
    # map_height = '500px'
    # File extensions that should be treated as images
    # img_extensions = [".jpg", ".jpeg", ".png", ".gif", ".heic", ".tif", ".tiff", ".webp"]
    # Pilkit processor used to resize the image
    # (see http://pilkit.readthedocs.org/en/latest/#processors)
    # - ResizeToFit: fit the image within the specified dimensions (default)
    # - ResizeToFill: crop THE IMAGE it to the exact specified width and height
    # - SmartResize: identical to ResizeToFill, but uses entropy to crop the image
    # - None: don't resize
    # img_processor = 'ResizeToFit'
    # Autorotate images
    # Warning: this setting is not compatible with `copy_exif_data` (see below),
    # because Sigal can't save the modified Orientation tag (currently Pillow can't
    # write EXIF).
    # autorotate_images = True
    # If True, EXIF data from the original image is copied to the resized image
    # copy_exif_data = False
    # Python's datetime format string used for the EXIF date formatting
    # https://docs.python.org/3/library/datetime.html#strftime-strptime-behavior
    # datetime_format = '%c'
    # Display generated datetime in the resulting output
    # display_timestamp = False
    # Jpeg options
    # jpg_options = {'quality': 85,
    #                'optimize': True,
    #                'progressive': True}
    # --------------------
    # Thumbnail generation
    # --------------------
    # Generate thumbnails
    # make_thumbs = True
    # Subdirectory of the thumbnails
    # thumb_dir = 'thumbnails'
    # Prefix and/or suffix for thumbnail filenames (default: '')
    # thumb_prefix = ''
    # thumb_suffix = '.tn'
    # Thumbnail size (default: (200, 150))
    # For the galleria theme, use 280 px for the width
    # For the colorbox and photoswipe theme, use 200 px for the width
    thumb_size = (280, 210)
    # Crop the image to fill the box
    # thumb_fit = True
    # When using thumb_fit, specifies what we should crop
    # for usage see
    # http://pillow.readthedocs.io/en/stable/reference/ImageOps.html#PIL.ImageOps.fit
    # thumb_fit_centering = (0.5, 0.5)
    # Delay in seconds to avoid black thumbnails in videos with fade-in
    # thumb_video_delay = 0
    # Max retries to generate a non-black thumbnail
    # thumb_video_black_retries = 0
    # For each retry, advance another N seconds on top of original delay
    # thumb_video_black_retry_offset = 1
    # A thumbnail with more than max_colors will not be considered "all black"
    # thumb_video_black_max_colors = 4
    # Keep original image (default: False)
    # keep_orig = False
    # Subdirectory for original images
    # orig_dir = 'original'
    # Use symbolic links instead of copying the original images
    # orig_link = False
    # Use symbolic links that are relative to the source directory instead of
    # absolute paths
    # rel_link = False
    # Attribute of Album objects which is used to sort medias (eg 'title'). To
    # sort on a metadata key, use 'meta.key'.
    # albums_sort_attr = 'name'
    # Reverse sort for albums
    # albums_sort_reverse = False
    # Attribute of Media objects which is used to sort medias. 'date' can be used
    # to sort with EXIF dates, and 'meta.key' to sort on a metadata key (which then
    # must exist for all images).
    # medias_sort_attr = 'filename'
    # Reverse sort for medias
    # medias_sort_reverse = False
    # Filter directories and files.
    # The settings take a list of patterns matched with the fnmatch module on the
    # path relative to the source directory:
    # http://docs.python.org/3/library/fnmatch.html
    ignore_directories = []
    ignore_files = []
    # -------------
    # Video options
    # -------------
    # Video converter binary (can be 'avconv' on certain GNU/Linux distributions)
    # video_converter = 'ffmpeg'
    # File extensions that should be treated as video files
    # video_extensions = ['.mov', '.avi', '.mp4', '.webm', '.ogv', '.3gp']
    # Video format
    # specify an alternative format, valid are 'webm' (default) and 'mp4'
    # video_format = 'webm'
    # Webm options
    # Options used in ffmpeg to encode the webm video. You may want to read
    # http://ffmpeg.org/trac/ffmpeg/wiki/vpxEncodingGuide
    # Be aware of the fact these options need to be passed as strings. If you are
    # using avconv (for example with Ubuntu), you will need to adapt the settings.
    # webm_options = ['-crf', '10', '-b:v', '1.6M',
    #                 '-qmin', '4', '-qmax', '63']
    # Webm options for 2-pass encoding
    # Options used to encode the webm video on the second pass.
    # Set to None by default, set to an array if a second pass is desired.
    # webm_options_second_pass = None
    # MP4 options
    # Options used to encode the mp4 video. You may want to read
    # https://trac.ffmpeg.org/wiki/Encode/H.264
    # mp4_options = ['-crf', '23' ]
    # MP4 options for 2-pass encoding
    # Options used to encode the mp4 video on the second pass.
    # Set to None by default, set to an array if a second pass is desired.
    # mp4_options_second_pass = None
    # Size of resized video (default: (480, 360))
    # Set this to None if no resizing is desired on the video.
    # video_size = (480, 360)
    # If the desired video extension and filename are the same, the video will
    # not be converted. If a transcode to different quality is required,
    # set this to True to force convert it. False by default.
    # video_always_convert = False
    # -------------
    # Miscellaneous
    # -------------
    # Write HTML files. If False, sigal will only process the images.
    # write_html = True
    # Name of the generated HTML files
    # output_filename = 'index.html'
    # Add output filename (see above) to the URLs
    # index_in_url = False
    # A list of links (tuples (title, URL))
    # links = [('Example link', 'http://example.org'),
    #          ('Another link', 'http://example.org')]
    # Google Analytics tracking code (UA-xxxx-x)
    # google_analytics = ''
    # Google Tag Manager tracking code (GTM-xxxxxx)
    # google_tag_manager = ''
    # Piwik tracking
    # tracker_url must not contain trailing slash.
    # Example : {'tracker_url': 'http://stats.domain.com', 'site_id' : 2}
    # piwik = {'tracker_url': '', 'site_id' : 0}
    # Specify a different locale. If set to '', the default locale is used.
    # locale = ''
    # Define language used on main <html> tag in templates
    # html_language = 'en'
    # 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'),)
    # Colorbox theme config
    # The column size is given in number of column of the css grid of the Skeleton
    # framework which is used for this theme: http://www.getskeleton.com/#grid
    # Then the image size must be adapted to fit the column size.
    # The default is 3 columns (176px).
    # colorbox_column_size = 3
    # Site Logo - Use a logo file in the sidebar
    # Only for colorbox currently, it could be adapted for other themes
    # You must place the logo file into the theme's static images folder, which
    # can be done using 'files_to_copy':
    # files_to_copy = (('extra/logo.png', 'static/logo.png'))
    # site_logo = 'logo.png'
    # --------
    # Plugins
    # --------
    # List of plugins to use. The values must be a path than can be imported.
    # Another option is to import the plugin and put the module in the list, but
    # this will break with the multiprocessing feature (the settings dict obtained
    # from this file must be serializable).
    # plugins = [
    #     'sigal.plugins.adjust',
    #     'sigal.plugins.compress_assets',
    #     'sigal.plugins.copyright',
    #     'sigal.plugins.encrypt',
    #     'sigal.plugins.extended_caching',
    #     'sigal.plugins.feeds',
    #     'sigal.plugins.media_page',
    #     'sigal.plugins.nomedia',
    #     'sigal.plugins.nonmedia_files',
    #     'sigal.plugins.watermark',
    #     'sigal.plugins.zip_gallery',
    # ]
    # Adjust the image after resizing it. A default value of 1.0 leaves the images
    # untouched.
    # adjust_options = {'color': 1.0,
    #                   'brightness': 1.0,
    #                   'contrast': 1.0,
    #                   'sharpness': 1.0}
    # Settings for compressing static assets
    # compress_assets_options = {
    #    'method': 'gzip' # Or 'zopfli' or 'brotli'
    # }
    # Add a copyright text on the image (default: '')
    # copyright = "© An example copyright message"
    # Settings for encryption plugin
    # encrypt_options = {
    #    'password': 'password',
    #    'ask_password': False
    # }
    # Settings for nonmedia_files plugin.
    # nonmedia_files_options = {
    #     'ext_as_thumb': True,
    #     'ignore_ext': ['.md'],
    #     'thumb_bg_color': (255, 255, 255),
    #     'thumb_font': None, # name/path of font file
    #     'thumb_font_color': (0, 0, 0),
    #     'thumb_font_size': 40, # only applies when a font is selected
    # }
    # Set zip_gallery to either False or a file name. The file name can
    # be formatted python style with an 'album' variable, for example
    # '{album.name}.zip'. The final archive will contain all resized or
    # original files (depending on `zip_media_format`).
    # zip_gallery = False   # False or 'archive.zip'
    # zip_media_format = 'resized'  # 'resized' or 'orig'
    # zip_skip_if_exists = False # Skip archive generation if archive is
    # already present. Warning: new photos in an album won't be added to archive

  Album information

Information on an album can be given in a file using the markdown <http://daringfireball.net/projects/markdown/> syntax, named index.md :

    Title: Another example gallery
    Thumbnail: test2.jpg
    Author: John Doe
    Sort: -name
    And a description with *Markdown* syntax.

Some meta-data keys are used by Sigal to get the useful informations on the gallery:

•   Title: the gallery title.

•   Thumbnail: the thumbnail that will be used in the parent directory to represent the gallery.

•   Author: the author of the gallery, if present it is used instead of the author setting.

•   Sort: the sort order for the sub-albums of this album. If prefixed with a '-' it will be in reversed order. Not supported to sort medias.

    Any additional meta-data is available in the templates. For instance:

        Authors: Waylan Limberg
                 John Doe

    can be used in the template with:

        {% if 'authors' in album.meta %}
        <p>Authors: {{ album.meta.authors|join(', ') }}</>
        {% endif %}

    If this file does not exist or if some meta-data is missing:

•   The directory's name is used for the title.

•   The first landscape image of the directory is used as thumbnail, or the first image if no landscape image is found.

  Image information

Additional information on an image can be given in a file using the markdown <http://daringfireball.net/projects/markdown/> syntax, named <imagename>.md (example: IMG_5206.md):

    Title: My awesome photo
    Date: 2020-01-01T09:00:00
    And a description with *Markdown* syntax.

EXIF data is directly extracted, see Simpler EXIF data output <#simple-exif-data>. Some meta-data keys are used by Sigal to get the useful informations on the gallery:

•   Title: the image title.

•   Date: the file date, useful when it cannot be read from the EXIF metadata, e.g. for videos and some image formats.

    Any additional meta-data is available in the templates. For instance:

        Location: Las Vegas

    can be used in the template with:

        {% if media.meta.location %}
        <p>Location: {{ media.meta.location[0] }}</>
        {% endif %}

  Themes

Sigal themes are created using the Jinja2 <http://jinja.pocoo.org/docs/> templating system.

  Bundled themes

Sigal comes with three themes, located in the sigal/themes folder:

colorbox:
    source <http://www.jacklmoore.com/colorbox>, demo <http://saimon.org/sigal-demo/colorbox/>. This theme uses a Swipe plugin to browse pictures on touch devices.

galleria:
    source <http://galleria.io/>, demo <http://saimon.org/sigal-demo/galleria/>. This theme is based on the classic theme, pictures can be browsed with left/right keys, fullscreen support is available with the f key, and a map can be shown with the m key if the show_map setting is True. The leaflet_provider setting can be used to customize the tile provider (using Leaflet-providers <https://github.com/leaflet-extras/leaflet-providers#providers>).

photoswipe:
    source <http://photoswipe.com/>, demo <http://saimon.org/sigal-demo/photoswipe/>.

    The themes folder also includes a default theme. This theme cannot be used on its own, instead, it contains Jinja2 templates that are used by the bundled themes to enable functionality such as the feeds and ZIP gallery plugins, as well as settings such as Google Analytics.

  Creating a theme

Sigal requires the following two templates in order to generate a gallery. These templates must be located in THEME_DIR/templates:

•   album_list.html: Generates the album list, if you have multiple albums

•   album.html: Generates each individual album page

    Themes may also include static content such as CSS and JavaScript by placing this content in the THEME_DIR/static folder. You can then access this content in your template by using the theme.url variable.

    Custom themes may also include the templates available in the default theme.

  Variables

You can use the following variables in your template:

album
    The current album that is rendered in the HTML file, represented by an Album object. album.medias contains the list of all medias in the album (represented by the Image and Video objects, inherited from Media).

index_title
    Name of the index. This is either the directory name or the title specified in the index.md of the source directory.

settings
    The entire dictionary from sigal.conf.py.

sigal_link
    URL to the Sigal homepage.

theme.name, theme.url
    Name and url of the currently used theme.

  Filters

You can define custom jinja filters for your template by creating a filters.py script at the root of your template directory.

This script will then be imported and all defined functions will be available as jinja filters with the same names in your templates.

  Documentation of sigal's main classes

class sigal.gallery.Album(path, settings, dirnames, filenames, gallery)
    Gather all informations on an album.

    Attributes:

Variables

•   description_file -- Name of the Markdown file which gives information on an album

•   index_url -- URL to the index page.

•   output_file -- Name of the output HTML file

•   meta -- Meta data from the Markdown file.

•   description -- description from the Markdown file.

    For details how to annotate your albums with meta data, see Album information <>.

property albums
    List of Album objects for each sub-directory.

property author
    Author extracted from the Markdown index.md file or settings.

property breadcrumb
    List of (url, title) tuples defining the current breadcrumb path.

create_output_directories()
    Create output directories for thumbnails and original images.

property description
    Description extracted from the Markdown index.md file.

description_file = 'index.md'

property images
    List of images (Image).

property markdown_metadata
    Get metadata from filename.md: title, description, meta.

property markdown_metadata_filepath

property meta
    Other metadata extracted from the Markdown index.md file.

property nbmedias

property random_thumbnail

property show_map
    Check if we have at least one photo with GPS location in the album

sort_medias(medias_sort_attr)

sort_subdirs(albums_sort_attr)

property thumbnail
    Path to the thumbnail of the album.

property title
    Title extracted from the Markdown index.md file.

property url
    URL of the album, relative to its parent.

property videos
    List of videos (Video).

property zip
    Placeholder ZIP method. The ZIP logic is controlled by the zip_gallery plugin

class sigal.gallery.Media(filename, path, settings)
    Base Class for media files.

    Attributes:

Variables

•   Media.type -- "image" or "video".

•   Media.dst_filename -- Filename of the resized image.

•   Media.thumbnail -- Location of the corresponding thumbnail image.

•   Media.big -- If not None, location of the unmodified image.

•   Media.big_url -- If not None, url of the unmodified image.

property big
    Path to the original image, if keep_orig is set (relative to the album directory). Copy the file if needed.

property big_url
    URL of the original media.

property description
    Description extracted from the Markdown <imagename>.md file.

dst_filename
    Filename of the resized image.

property dst_path

property file_metadata
    Type-specific metadata

property markdown_metadata
    Get metadata from filename.md: title, description, meta.

property markdown_metadata_filepath

property meta
    Other metadata extracted from the Markdown <imagename>.md file.

src_ext
    Input extension.

src_filename
    Filename of the input image.

property thumb_path

property thumbnail
    Path to the thumbnail image (relative to the album directory).

property title
    Title extracted from the metadata, or defaults to the filename.

type = ''
    Type of media, e.g. "image" or "video".

property url
    URL of the media.

class sigal.gallery.Image(filename, path, settings)
    Gather all informations on an image file.

property big
    Path to the original image, if keep_orig is set (relative to the album directory). Copy the file if needed.

property big_url
    URL of the original media.

property date
    The date from the EXIF DateTimeOriginal metadata if available, or from the file date.

property description
    Description extracted from the Markdown <imagename>.md file.

dst_filename
    Filename of the resized image.

property dst_path

property exif
    If not None contains a dict with the most common tags. For more information, see Simpler EXIF data output.

property file_metadata
    Image file metadata (Exif and IPTC)

has_location()
    True if location information is available for EXIF GPSInfo.

property input_size
    The dimensions of the input image.

property markdown_metadata
    Get metadata from filename.md: title, description, meta.

property markdown_metadata_filepath

property meta
    Other metadata extracted from the Markdown <imagename>.md file.

property raw_exif
    If not None, contains the raw EXIF tags.

property size
    The dimensions of the resized image.

src_ext
    Input extension.

src_filename
    Filename of the input image.

property thumb_path

property thumb_size
    The dimensions of the thumbnail image.

property thumbnail
    Path to the thumbnail image (relative to the album directory).

property title
    Title extracted from the metadata, or defaults to the filename.

type = 'image'
    Type of media, e.g. "image" or "video".

property url
    URL of the media.

class sigal.gallery.Video(filename, path, settings)
    Gather all informations on a video file.

property big
    Path to the original image, if keep_orig is set (relative to the album directory). Copy the file if needed.

property big_url
    URL of the original media.

property date
    The date from the Date metadata if available, or from the file date.

property description
    Description extracted from the Markdown <imagename>.md file.

dst_filename
    Filename of the resized image.

property dst_path

property file_metadata
    Type-specific metadata

property markdown_metadata
    Get metadata from filename.md: title, description, meta.

property markdown_metadata_filepath

property meta
    Other metadata extracted from the Markdown <imagename>.md file.

src_ext
    Input extension.

src_filename
    Filename of the input image.

property thumb_path

property thumbnail
    Path to the thumbnail image (relative to the album directory).

property title
    Title extracted from the metadata, or defaults to the filename.

type = 'video'
    Type of media, e.g. "image" or "video".

property url
    URL of the media.

  Simpler EXIF data output

Because the tags in the media.raw_exif dictionary are a little bit cumbersome to use, some common tags are extracted and formatted for easy use in templates. If available, you can use:

media.exif.iso
    The ISO speed rating.

media.exif.focal
    The focal length, formatted as a decimal number.

media.exif.exposure
    The exposure time formatted as a fractional number, e.g. "1/500".

media.exif.fstop
    The aperture value given as an F-number and formatted as a decimal.

media.exif.datetime
    The time the image was taken. It is formatted with the datetime_format setting, which is %c by default. See Python's datetime documentation <https://docs.python.org/3/library/datetime.html#strftime-strptime-behavior> for a list of all possible values.

media.exif.dateobj
    The time the image was taken. It is a datetime object, that can be formatted with strftime:

        {% if media.exif.dateobj %}
            {{ media.exif.dateobj.strftime('%A, %d. %B %Y') }}
        {% endif %}

    This will output something like "Monday, 25. June 2013", depending on your locale.

media.exif.gps
    If not None, the dict contains two keys lat and lon denoting the GPS coordinates of the location where the image was taken. lat will always be referenced to the north pole whereas lon will be referenced to east to the prime meridan. To provide a link on an OpenStreetMap you could write a template like this:

        {% if media.exif.gps %}
            <a href="https://www.openstreetmap.org/?mlat={{
                media.exif.gps.lat }}&mlon={{
                media.exif.gps.lon }}#map=18/{{
                media.exif.gps.lat }}/{{
                media.exif.gps.lon }}">Go to location (OpenStreetMap)</a>
        {% endif %}

  Plugins

  How to use plugins

Plugins must be specified with the plugins setting:

    plugins = ['sigal.plugins.adjust', 'sigal.plugins.copyright']

You can either specify the name of the module which contains the plugin, or import the plugin before adding it to the list:

    from sigal.plugins import copyright
    plugins = ['sigal.plugins.adjust', copyright]

Note: Using an import like this will break the multiprocessing feature, because the settings dict must be serializable. So in most cases you should prefer the first option.

The plugin_paths setting can be used to specify paths to search for plugins (if they are not in the python path).

  Write a new plugin

Plugins are based on signals with the blinker <http://pythonhosted.org/blinker/> library. A plugin must subscribe to a signal (the list is given below). New signals can be added if need. See an example with the copyright plugin:

    """Plugin which add a copyright to the image.
    Settings:
    - ``copyright``: the copyright text.
    - ``copyright_text_font``: the copyright text font - either system/user
      font-name or absolute path to font.ttf file.  If no font is specified, or
      specified font is not found, the default font is used.
    - ``copyright_text_font_size``: the copyright text font-size. If no font is
      specified, this setting is ignored.
    - ``copyright_text_color``: the copyright text color in a tuple (R, G, B)
      with decimal RGB code, e.g. ``(255, 255, 255)`` is white.
    - ``copyright_text_position``: the copyright text position in 2 tuple (left,
      top).  By default text would be positioned at bottom-left corner.
    """
    import logging
    from PIL import ImageDraw, ImageFont
    from sigal import signals
    logger = logging.getLogger(__name__)
    def add_copyright(img, settings=None):
        logger.debug("Adding copyright to %r", img)
        draw = ImageDraw.Draw(img)
        text = settings["copyright"]
        font = settings.get("copyright_text_font", None)
        font_size = settings.get("copyright_text_font_size", 10)
        assert font_size >= 0
        color = settings.get("copyright_text_color", (0, 0, 0))
        bottom_margin = 3  # bottom margin for text
        text_height = bottom_margin + 12  # default text height (of 15)
        if font:
            try:
                font = ImageFont.truetype(font, font_size)
                text_height = font.getsize(text)[1] + bottom_margin
            except Exception:  # load default font in case of any exception
                logger.debug("Exception: Couldn't locate font %s, using default font", font)
                font = ImageFont.load_default()
        else:
            font = ImageFont.load_default()
        left, top = settings.get("copyright_text_position", (5, img.size[1] - text_height))
        draw.text((left, top), text, fill=color, font=font)
        return img
    def register(settings):
        if settings.get("copyright"):
            signals.img_resized.connect(add_copyright)
        else:
            logger.warning("Copyright text is not set")

  Signals

sigal.signals.album_initialized(album)
    Called after the Album <#sigal.gallery.Album> is initialized.

Parameters
    album -- the Album <#sigal.gallery.Album> object.

sigal.signals.gallery_initialized(gallery)
    Called after the gallery is initialized.

Parameters
    gallery -- the Gallery object.

sigal.signals.media_initialized(media)
    Called after the Media <#sigal.gallery.Media> (Image <#sigal.gallery.Image> or Video <#sigal.gallery.Video>) is initialized.

Parameters
    media -- the media object.

sigal.signals.gallery_build(gallery)
    Called after the gallery is build (after media are resized and html files are written).

Parameters
    gallery -- the Gallery object.

sigal.signals.img_resized(img, settings=settings)
    Called after the image is resized. This signal work differently, the modified image object must be returned by the registered function.

Parameters

•   img -- the PIL image object.

•   settings -- the settings dict.

  List of plugins

  Adjust plugin

Plugin which adjust the image after resizing.

Based on pilkit's Adjust <https://github.com/matthewwithanm/pilkit/blob/master/pilkit/processors/base.py#L19> processor.

Settings:

    adjust_options = {
        'color': 1.0,
        'brightness': 1.0,
        'contrast': 1.0,
        'sharpness': 1.0
    }

  Compress assets plugin

Plugin to compress static files for faster HTTP transfer.

Your web server must be configured in order to select pre-compressed files instead of the required one, to save CPU. For example, in nginx:

    server {
        gzip_static;
    }

Currently, 3 methods are supported:

•   gzip: No dependency required. This is the fastest, but also largest output.

•   zopfli: Requires zopfli <https://pypi.org/project/zopfli/>. gzip compatible output with optimized size.

•   brotli: Requires brotli <https://pypi.org/project/Brotli/>. Brotli is the best compressor for web usage.

    Settings available as dictionary in compress_assets_options:

•   method: One of gzip, zopfli or brotli.

•   suffixes: List of file suffixes eligible to compression. Default to ['htm', 'html', 'css', 'js', 'svg']

  Copyright plugin

Plugin which add a copyright to the image.

Settings:

•   copyright: the copyright text.

•   copyright_text_font: the copyright text font - either system/user font-name or absolute path to font.ttf file. If no font is specified, or specified font is not found, the default font is used.

•   copyright_text_font_size: the copyright text font-size. If no font is specified, this setting is ignored.

•   copyright_text_color: the copyright text color in a tuple (R, G, B) with decimal RGB code, e.g. (255, 255, 255) is white.

•   copyright_text_position: the copyright text position in 2 tuple (left, top). By default text would be positioned at bottom-left corner.

  Encrypt plugin

Plugin to protect gallery by encrypting image files using a password.

Options:

    encrypt_options = {
        'password': 'password',
        'ask_password': False,
        'gcm_tag': 'randomly_generated',
        'kdf_salt': 'randomly_generated',
        'kdf_iters': 10000,
    }

•   password: The password used to encrypt the images on gallery build, and decrypt them when viewers access the gallery. No default value. You must specify a password.

•   ask_password: Whether or not viewers are asked for the password to view the gallery. If set to False, the password will be present in the HTML files so the images are decrypted automatically. Defaults to False.

•   gcm_tag, kdf_salt, kdf_iters: Cryptographic parameters used when encrypting the files. gcm_tag, kdf_salt are meant to be randomly generated, kdf_iters defaults to 10000. Do not specify them in the config file unless you have good reasons to do so.

    Note: The plugin caches the cryptographic parameters (but not the password) after the first build, so that incremental builds can share the same credentials. DO NOT CHANGE THE PASSWORD OR OTHER CRYPTOGRAPHIC PARAMETERS ONCE A GALLERY IS BUILT, or there will be inconsistency in encrypted files and viewers will not be able to see some of the images any more.

    Compatibility with other plugins:

•   zip_gallery: if you enable both this plugin and the zip_gallery plugin, the generated zip archives will contain encrypted images, which is generally meaningless since viewers cannot easily decrypt them outside a browser.

  Extended caching plugin

Decreases the time needed to build large galleries (e.g.: 25k images in 2.5s instead of 30s)

This plugin allows extended caching, which is useful for large galleries. Once a gallery has been built it caches all metadata for all media (markdown, exif, itpc) in the gallery target folder. Before the next run it restores them so that the image and metadata files do not have to be parsed again. For large galleries this can speed up the creation of index files dramatically.

  Feeds plugin

Plugin which add RSS/ATOM feeds.

This plugin requires feedgenerator <https://pypi.org/project/feedgenerator/>. It uses all the images and videos of the gallery, sorted by date, to show the most recent ones.

Settings:

•   rss_feed and atom_feed, see below.

    Example:

        rss_feed = {'feed_url': 'http://example.org/feed.rss', 'nb_items': 10}
        atom_feed = {'feed_url': 'http://example.org/feed.atom', 'nb_items': 10}

  Media page plugin

Plugin which generates HTML pages for each image.

Currently this plugin can be used only with the colorbox theme, the other themes have to be adapted.

For themes, the previous_media and next_media variables contain the previous/next Media <#sigal.gallery.Media> objects.

  Nomedia plugin

This plugin offers more fine-grained control over exluded images and folders, similarly to how it's handled on Android.

To ignore a folder or image put a .nomedia file next to it in its parent folder and put its name into the file. E.g.:

    content of folder:
        IMG_3425.JPG, IMG_2426.JPG, IMG_2427.JPG, subfolder, .nomedia
    content of .nomedia:
        IMG_2426.JPG
        IMG_2427.JPG
        subfolder

will ignore all images but IMG_3425.JPG and the subfolder.

Alternatively, if you put a .nomedia file into a folder and leave it blank (i.e. an empty file called .nomedia in a folder containing images), this ignores the whole folder it's located in (like on Android).

WARNING: When you have a pre-existing gallery from a previous run of sigal adding a new .nomedia file will not remove the newly ignored images/albums from the existing gallery (only the entries in the parent gallery pointing to it). They might still be reachable thereafter. Either remove the whole gallery to be sure or remove the ignored files/folders inside the gallery to remove them for good.

  Non-media Files plugin

Plugin to index non-media files.

This plugin will copy the files into the build tree and generate generic thumbnails for the files. In-browser previews will likely fail, and it is up to the theme to provide correct support for downloads.

If the pdf2image <https://pypi.org/project/pdf2image/> optional dependency is installed, it will be used to generate thumbnails for PDF files.

Settings available as dictionary in nonmedia_files_options:

•   ext_as_thumb: Enable simple thumbnail showing ext. Default to True

•   ignore_ext: List of file extensions to ignore. Default to [".md"]

•   thumb_bg_color: Background color for thumbnail. Accepts (r, g, b) tuple. Default to white (255, 255, 255).

•   thumb_font: Name or path to font file. Default to None to use the PIL built-in font.

•   thumb_font_color: Font color for thumbnail. Accepts (r, g, b) tuple. Default to black (0, 0, 0).

•   thumb_font_size: Font size for thumbnail. Must select a font to apply. Default to 40.

    Note: Thumbnails are generated using the file extension text on a background color. It is highly recommended to select a font (such as "FreeMono.ttf"), since the default PIL font does not respect font size.

  Titleregexp plugin

This plugin modifies titles of galleries by using regular-expressions and simple string or character replacements. It is acting in two phases: First, all regular-expression-based modifications are carried out, second, string/character replacements are done.

The first phase may be interrupted if a match occurs by the 'break'-setting individually per regular-expression part. Additionally, if a match occurs, string/character replacements may be added.

The second phase is done even if the first phase had been interrupted.

Settings:

•

titleregexp with the following keys:

•   regexp, which is an array of dicts with 'search', 'replace', 'break' 'substitute' and 'count' keys. All but 'break' and 'substitute' are the arguments for re.subn, without given 'count' all matches are replaced. If 'break' is anything but an empty string, the rest of the regexp-array is being skipped. The 'substitute'-key contains an array following the substitute format explained in the next sentence and does string-replacement if the regular-expression matched.

•   substitute, which is an array of 2-element-arrays, of which the occurences of the first element will be replaced by the second element by the replace-method of strings.

    Example:

        titleregexp = {
            'regexp' : [
                { 'search': r"^([0-9]*)-(.*)$", 'replace': r"\2 (\1)", 'count': 1,
                  'break': 1, substitute: [ ['ae','ä'] ] },
                { 'search': r"([a-z][a-z])([A-Z][a-z])", 'replace': r"\1 \2" }
                ],
            'substitute' : [ [ '_', ' ' ] ]
        }

  Watermark plugin

Plugin which adds a watermark to the image.

Based on <http://code.activestate.com/recipes/362879-watermark-with-pil/> (Licensed under the PSF License).

Settings:

•   watermark: path to the watermark image.

•   watermark_position: the watermark position either 'scale' or 'tile' or a 2-tuple giving the upper left corner, or a 4-tuple defining the left, upper, right, and lower pixel coordinate, or None (same as (0, 0)). If a 4-tuple is given, the size of the pasted image must match the size of the region.

•   watermark_opacity: the watermark opacity (0.0 to 1.0).

  ZIP Gallery plugin

This plugin controls the generation of a ZIP archive for a gallery

If the zip_gallery setting is set, it contains the location of a zip archive with all original images of the corresponding directory.

To ignore a ZIP gallery generation for a particular album, put a .nozip_gallery file next to it in its parent folder. Only the existence of this .nozip_gallery file is tested. If no .nozip_gallery file is present, then make a ZIP archive with all media files.

See compatibility with the encrypt plugin.

  Frequently Asked Questions (FAQ)

  How do I protect the gallery with a password?

Sigal simply generates HTML pages, there is no server process that could handle a password protection. So the password has to be handled in your web server (Apache, Nginx, etc). A complete treatise on webserver configuration is beyond the scope of this document, but, for example, you may get started with Apache with the official documentation <https://httpd.apache.org/docs/2.2/en/howto/auth.html#gettingitworking>.

Here is an example Apache configuration, assuming your gallery was built in /var/www/sigal/_build:

    <Directory /var/www/sigal/_build>
        AuthType Basic
        AuthName "Restricted Content"
        AuthUserFile /etc/apache2/htpasswd
        Require valid-user
    </Directory>

You will then need to create username/password combinations in the /etc/apache2/htpasswd using the htpasswd command <https://httpd.apache.org/docs/2.4/programs/htpasswd.html>.

  How do I protect only some folders of the gallery with a password?

This is more complicated than the above. Assuming you want to protect only the foo/ subdirectory, the following will unfortunately not do what you expect:

    <Directory /var/www/sigal/_build/foo>
        AuthType Basic
        AuthName "Restricted Content"
        AuthUserFile /etc/apache2/htpasswd
        Require valid-user
    </Directory>

It will protect the folder with a password, but, because of the thumbnails shown on the main page, the web browser will prompt the user for a password on the parent directory as well, which will confuse users and is probably not what you want.

The trick is then to whitelist the thumbnail files. Here we'll assume you will name the thumbnail files public.jpg and then configure those files to be visible even in the private section, like so:

    <Directory /var/www/sigal/_build/foo>
        AuthType Basic
        AuthName "Restricted Content"
        AuthUserFile /etc/apache2/htpasswd
        Require valid-user
    </Directory>
    <Files "public.jpg">
        Satisfy any
    </Files>

Then just make sure, through the album information mechanism, that the right image is chosen as a thumbnail for that album, for example, in foo/index.md:

    Title: Private section
    Thumbnail: public.jpg

Et voilà! You now have a hybrid private/public gallery. This is not recommended for highly sensitive pictures; because other parts of Sigal may (eventually?) leak information about filenames, thumbnails or even contents without your knowledge in the future. But it's a good simple way to add basic snooping protection over certain areas with minimal configuration.

  How to regenerate the gallery when something changes ?

It can be convenient to build continuously the gallery when adding or removing pictures in the albums, however Sigal does not provide currently a buitin "autoreload" feature. This can be achieved with external tool like peat <https://github.com/sjl/peat>:

    peat --dynamic 'find pictures/' 'sigal build'

will watch changes inside the pictures/ directory and rebuild the gallery in this case. Many other tools do similar things, here is the equivalent command with entr <http://entrproject.org/>:

    while true; do  find pictures/ | entr -d sigal build; done

  How to automatically build the gallery on a remote git server?

Another way to handle this is by storing your files on a remote git <https://git-scm.com/> repository, optionally with git-annex <https://git-annex.branchable.com/> or git-lfs <https://git-lfs.github.com/> to avoid managing large image files directly with git.

Then Sigal can be triggered using git hook <https://git-scm.com/docs/githooks> to update the repository on push. The hook can be as simple as this:

    #!/bin/sh
    sigal build

But a more robust implementation <https://gitlab.com/anarcat/git-hooks/blob/master/sigal-git-hook> is also available. The hook should be installed in .git/hooks/post-receive. If you are using git-annex, this hook will already be present, so you'll need to add the sigal hook at the end of the file, like so:

    #!/bin/sh
    # automatically configured by git-annex
    git annex post-receive
    /home/foo/src/git-hooks/sigal-git-hook

This assumes, of course, that you are running your own Git server; this will not work with commercial providers like GitHub or GitLab unless you setup a periodic job to automatically pull from those server, in which case the above hook would be installed as an update hook.

  Contributing guidelines

  Filing issues

If you have an issue with sigal, the first step is to run:

    sigal build -fd -n 1

to get diagnostic information (debug mode, only one core). If you can identify an image or video that is causing the issue, you can create a new directory containing only this image/video and rerun sigal build -fd -n 1.

Then, put the output into a gist/pastebin, and fill an issue on github. You can also try to get help via the #sigal IRC channel on freenode.

  How To Contribute

sigal is always open for suggestions and contributions by generous developers. Here are a few tips to get you started.

Please:

•   Obey PEP 8 <http://www.python.org/dev/peps/pep-0008/> and PEP 257 <http://www.python.org/dev/peps/pep-0257/>.

•   Always add tests and docs for your code.

•   Add yourself to the AUTHORS file in an alphabetical fashion, and add your name to the license header of the files you modify.

•   Write good commit messages <http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html>.

•   Ideally, squash <http://gitready.com/advanced/2009/02/10/squashing-commits-with-rebase.html> your commits, i.e. make your pull requests just one commit.

•   Use a branch, it will be easier to squash or rebase on upstream's main.

    Thank you for considering to contribute to sigal !

  Setting up the development environment

Using a virtualenv <https://virtualenv.pypa.io/>:

    git clone https://github.com/saimn/sigal.git
    cd sigal
    virtualenv venv
    . venv/bin/activate

Install sigal in development mode:

    pip install -e .

Install additional dependencies for development (Sphinx, pytest), and optional dependencies:

    pip install -e .\[all,tests\]

  Building the docs

•   Using tox <https://tox.readthedocs.io/>, run tox -e doc

•   Or make html in the docs/ directory.

  Running the test suite

•   Using tox <https://tox.readthedocs.io/>, run tox -e py37 (replacing py37 with your Python version if needed).

  Building the test gallery

•   Using tox <https://tox.readthedocs.io/>, run tox -e demo

  License

Sigal itself is available under the MIT license, but it also relies on several librairies (thanks!):

•   Colorbox <http://www.jacklmoore.com/colorbox> (MIT)

•   Galleria <http://galleria.io/> (MIT)

•   Photoswipe <http://photoswipe.com/> (MIT)

•   JQuery <https://jquery.org/> (MIT)

•   JQuery TouchSwipe <https://github.com/mattbryson/TouchSwipe-Jquery-Plugin> (MIT)

•   Skeleton <http://getskeleton.com/> (MIT)

•   normalize.css <https://github.com/necolas/normalize.css> (MIT)

•   Leaflet <http://leafletjs.com/> (BSD)

•   echo <https://github.com/toddmotto/echo> (MIT)

    The tests/sample/pictures directory contain images used for the unit tests:

•   11.jpg, 21.jpg, 22.jpg, 3.jpg : From @saimn

•   1.jpg, 2.jpg : From @edwinsteele (<https://github.com/saimn/sigal/pull/297#issuecomment-365879755>)

•   example.gif : <https://commons.wikimedia.org/wiki/File:00_nuvolosit%C3%A0_media_AM.GIF> (CC-BY-3.0)

•   CMB_Timeline300_no_WMAP.jpg : <https://en.wikipedia.org/wiki/File:CMB_Timeline300_no_WMAP.jpg> (Public domain)

•   KeckObservatory20071020.jpg : <https://commons.wikimedia.org/wiki/File:KeckObservatory20071020.jpg> (CC-BY-3.0)

•   flickr_jerquiaga_2394751088_cc-by-nc.jpg <http://www.flickr.com/photos/jerquiaga/2394751088/> (CC-BY-NC)

•   hélicoïde.jpg : <https://commons.wikimedia.org/wiki/File:Helicoid.PNG> (CC BY-SA 3.0)

•   Hubble Interacting Galaxy NGC 5257.jpg <https://commons.wikimedia.org/wiki/File:Hubble_Interacting_Galaxy_NGC_5257_(2008-04-24).jpg> (Public domain)

•   Hubble ultra deep field.jpg : <https://commons.wikimedia.org/wiki/File%3AHubble_ultra_deep_field.jpg> (Public domain)

•   m57_the_ring_nebula-587px.jpg <https://commons.wikimedia.org/wiki/File%3AM57_The_Ring_Nebula.JPG> (Public domain)

•   noexif.png : <https://commons.wikimedia.org/wiki/File:Ilc_9yr_moll4096.png> (Public domain)

•   should_be_created.jpg, should_be_ignored_1.jpg, should_be_ignored2.jpg, should_be_ignored3.jpg, should_be_ignored.jpg : from the apollo 7 mission, public domain: <https://www.flickr.com/photos/projectapolloarchive/21756099278/in/album-72157657129869694/> (<https://github.com/saimn/sigal/pull/233#issuecomment-275430083>)

•   example video.ogv : <https://commons.wikimedia.org/wiki/File:Examplevideo.ogv> (Public domain)

•   outdoor.heic: From @ususdei, <https://github.com/saimn/sigal/pull/519#issuecomment-2543310727> (Public domain)

  Changelog

  Version 2.7dev

Not released yet.

  Version 2.6.1

•   Fix a bug in photoswipe when some EXIF data does not contain the date information [#544 <https://github.com/saimn/sigal/issues/544>].

  Version 2.6

Released on 2026-02-06.

Sigal now requires Python 3.11+.

•   With the photoswipe theme, albums can contain both images and sub-albums [#535 <https://github.com/saimn/sigal/issues/535>].

•   Fix issue with latest version of feedgenerator.

•   Fix compat with click 8.2.0.

•   Fix theme URL for photoswipe.

•   Thumbnail can now be set in index.md either with the original filename or with the thumbnail name after format conversion [#476 <https://github.com/saimn/sigal/issues/476>].

•   Allow portrait orientation for thumbnails [#531 <https://github.com/saimn/sigal/issues/531>].

•   nonmedia_files plugin: adding support for PDF thumbnails [#536 <https://github.com/saimn/sigal/issues/536>].

  Version 2.5

Released on 2025-02-25.

Sigal now requires Python 3.9+.

•   Remove s3 plugin since it relied on boto which is no longer maintained. Help is welcome to update the plugin with the new boto3 library. [#513 <https://github.com/saimn/sigal/issues/513>]

•   Cache input size to make updating faster [#506 <https://github.com/saimn/sigal/issues/506>].

•   Allow sorting albums with negative numbers [#507 <https://github.com/saimn/sigal/issues/507>].

•   Write the static files only once [#510 <https://github.com/saimn/sigal/issues/510>].

•   Remove subdirectories for the ones skipped with ignore_dirs [#515 <https://github.com/saimn/sigal/issues/515>].

•   New cli flag sigal serve --browser to open in default browser [#516 <https://github.com/saimn/sigal/issues/516>].

•   Add support for .heic files (requires the optional pillow-heif package) [#519 <https://github.com/saimn/sigal/issues/519>].

•   Add autoplay setting for galleria [#520 <https://github.com/saimn/sigal/issues/520>].

•   Show HTML in media description (with galleria) [#521 <https://github.com/saimn/sigal/issues/521>].

•   New display_timestamp setting to show the generation timestamp [#524 <https://github.com/saimn/sigal/issues/524>].

•   Update photoswipe to v5.4.4 [#528 <https://github.com/saimn/sigal/issues/528>].

  Version 2.4

Released on 2023-09-29.

Sigal now requires Pillow>=8.0.0

•   Avoid IndexError with empty source dir [#498 <https://github.com/saimn/sigal/issues/498>].

•   New cli option --force-album to reprocess only specific albums [#491 <https://github.com/saimn/sigal/issues/491>].

•   Added support for black detection in video thumbnail generation [#485 <https://github.com/saimn/sigal/issues/485>].

•   Don't show the galleria container if there are no medias [#484 <https://github.com/saimn/sigal/issues/484>].

•   Force encrypt's password form to be on top [#483 <https://github.com/saimn/sigal/issues/483>].

•   Add mkv to video_extensions [#481 <https://github.com/saimn/sigal/issues/481>].

•   Make sure zip_gallery is set correctly [#477 <https://github.com/saimn/sigal/issues/477>].

•   Updates for recent Pillow changes, requires Pillow>=8.0.0 [#479 <https://github.com/saimn/sigal/issues/479>].

•   Make theme dir writable after copying to it [#471 <https://github.com/saimn/sigal/issues/471>].

•   New plugin: Titleregexp - modify titles of albums with regular expressions [#469 <https://github.com/saimn/sigal/issues/469>].

•   List of sort-properties as fallback instead of zero-length string [#468 <https://github.com/saimn/sigal/issues/468>].

  Version 2.3

Released on 2022-04-08.

Sigal now requires Python 3.8+.

•   Add option max_img_pixels to allow processing huge images (sets PIL.Image.MAX_IMAGE_PIXELS) [#431 <https://github.com/saimn/sigal/issues/431>].

•   Add webp to the list of images formats supported by default [#433 <https://github.com/saimn/sigal/issues/433>].

•   Allow video_size = None in settings [#435 <https://github.com/saimn/sigal/issues/435>].

•   New plugin to handle non-image or video files [#434 <https://github.com/saimn/sigal/issues/434>].

•   With the galleria theme, albums can contain both images and sub-albums [#438 <https://github.com/saimn/sigal/issues/438>].

•   Add original size information for 'Download ZIP' link in album [#446 <https://github.com/saimn/sigal/issues/446>].

•   Allow specifying the file date in the Markdown metadata file [#447 <https://github.com/saimn/sigal/issues/447>].

•   Add gallery title to albums' <title> [#441 <https://github.com/saimn/sigal/issues/441>].

•   Add map for all themes. This replaces the map feature that was specific to the galleria theme [#450 <https://github.com/saimn/sigal/issues/450>].

•   Fix loading filters.py [#452 <https://github.com/saimn/sigal/issues/452>].

•   Fix compatibility with Click 8.1.

•   colorbox theme: avoiding holes due to non image/video files present in the source directory [#455 <https://github.com/saimn/sigal/issues/455>].

•   Extend caching plugin to handle markdown and iptc metadata [#443 <https://github.com/saimn/sigal/issues/443>].

  Version 2.2

Released on 2021-04-18.

•   Convert pillow warnings to logging with filename [#394 <https://github.com/saimn/sigal/issues/394>].

•   Catch warnings when reading EXIF data.

•   Avoid crash when thumbnail cannot be generated [#401 <https://github.com/saimn/sigal/issues/401>].

•   Replace deprecated usage of imp.

•   Fix video thumbnail creation when delay > video length [#411 <https://github.com/saimn/sigal/issues/411>].

•   Update photoswipe to 4.4.0 [#415 <https://github.com/saimn/sigal/issues/415>].

•   Update galleria to v1.6.1 and add new themes [#417 <https://github.com/saimn/sigal/issues/417>].

•   Add user_css option to allow easier css customization [#418 <https://github.com/saimn/sigal/issues/418>].

•   Allow to specify the sort order per album.

•   Add a .nbmedias attribute to get the number of files in an album.

•   More options for vieo resizing [#420 <https://github.com/saimn/sigal/issues/420>].

•   Fixes for img_format [#421 <https://github.com/saimn/sigal/issues/421>].

•   Fix encoding issue with ffmpeg output [#423 <https://github.com/saimn/sigal/issues/423>].

  Version 2.1.1

Released on 2020-08-03.

•   Compatibility with Pillow 7.2

•   Fix issue with encrypt template and some Jinja2 versions [#399 <https://github.com/saimn/sigal/issues/399>].

•   Bug fixes and UI improvements for encrypt plugin [#399 <https://github.com/saimn/sigal/issues/399>].

•   Reorganize info about plugins in the template config and fix documentation issues with some plugins.

  Version 2.1

Released on 2020-05-21.

•   Add setting to use relative symbolic links [#359 <https://github.com/saimn/sigal/issues/359>].

•   Add a setting to force image output format [#360 <https://github.com/saimn/sigal/issues/360>].

•   Feeds: fix links to gallery and image [#361 <https://github.com/saimn/sigal/issues/361>].

•   Improve performance when reading metadata [#362 <https://github.com/saimn/sigal/issues/362>].

•   Add new plugin to allow one to disable ZIP generation on a per album basis with a .nozip_gallery file [#368 <https://github.com/saimn/sigal/issues/368>].

•   Make sure that read-only files can be copied [#375 <https://github.com/saimn/sigal/issues/375>].

•   Add a quiet flag [#376 <https://github.com/saimn/sigal/issues/376>].

•   Update photoswipe to v4.1.3

•   Improve error message when template is not found [#384 <https://github.com/saimn/sigal/issues/384>].

•   New plugin to protect gallery by encrypting image files using a password [#385 <https://github.com/saimn/sigal/issues/385>].

•   Force conversion of some EXIF tags to str [#386 <https://github.com/saimn/sigal/issues/386>].

•   Use natural sorting thanks to the natsort package [#387 <https://github.com/saimn/sigal/issues/387>].

  Version 2.0

Released on 2019-01-26.

Sigal now requires Python 3.5+.

•   Add some transparency for galleria's info box [#308 <https://github.com/saimn/sigal/issues/308>].

•   Galleria theme now reads image data from json [#312 <https://github.com/saimn/sigal/issues/312>].

•   Galleria: Load first image earlier [#307 <https://github.com/saimn/sigal/issues/307>].

•   Galleria: Do not load tiles by default.

•   Fixed crash when IPTC reading fails [#316 <https://github.com/saimn/sigal/issues/316>].

•   Force loading of truncated files [#320 <https://github.com/saimn/sigal/issues/320>].

•   Include tests in PyPI tarball [#323 <https://github.com/saimn/sigal/issues/323>].

•   Optimize a bit markdown initialization [#329 <https://github.com/saimn/sigal/issues/329>].

•   Quote special characters in urls [#345 <https://github.com/saimn/sigal/issues/345>].

•   Reorganization of templates, splitting landing page and album templates [#343 <https://github.com/saimn/sigal/issues/343>], [#347 <https://github.com/saimn/sigal/issues/347>], [#348 <https://github.com/saimn/sigal/issues/348>].

•   Add IPTC Headline (2:105) and to iptc_data [#356 <https://github.com/saimn/sigal/issues/356>].

•   Avoid IPTC errors [#355 <https://github.com/saimn/sigal/issues/355>], [#358 <https://github.com/saimn/sigal/issues/358>].

  Version 1.4.1

Released on 2018-10-01.

•   compatibility with Click 7.0

  Version 1.4.0

Released on 2018-02-20.

This is the last version supporting Python 2.

•   Update libraries used in themes (Galleria, Colorbox, PhotoSwipe) and their dependencies.

•   Remove use of CDNs (JQuery, Google fonts).

•   Hint to how to suppress decompressionbomb warnings [#235 <https://github.com/saimn/sigal/issues/235>].

•   New plugin for finer control over ignored files [#233 <https://github.com/saimn/sigal/issues/233>].

•   New plugin to cache the exif data of images [#236 <https://github.com/saimn/sigal/issues/236>].

•   Feeds plugin: include videos in feeds [#238 <https://github.com/saimn/sigal/issues/238>].

•   Allow formatting in zip_gallery [#244 <https://github.com/saimn/sigal/issues/244>].

•   Added random thumbnail property for album [#241 <https://github.com/saimn/sigal/issues/241>].

•   Improve CSP compatibility with colorbox theme [#245 <https://github.com/saimn/sigal/issues/245>].

•   Set html lang attribute based upon locale [#257 <https://github.com/saimn/sigal/issues/257>].

•   Resize portrait images to same size as landscape [#258 <https://github.com/saimn/sigal/issues/258>].

•   New setting thumb_fit_centering for tweaking how thumbnails should be cropped [#263 <https://github.com/saimn/sigal/issues/263>].

•   New settings to configure what file extensions should be recognised as images and videos [#270 <https://github.com/saimn/sigal/issues/270>].

•   New setting datetime_format to customize the EXIF datetime format [#271 <https://github.com/saimn/sigal/issues/271>].

•   Add a progress bar for writing index files [#234 <https://github.com/saimn/sigal/issues/234>].

•   Add setting to customize the EXIF datetime format [#271 <https://github.com/saimn/sigal/issues/271>].

•   Allow to configure the ffmpeg binary [#273 <https://github.com/saimn/sigal/issues/273>].

•   Filter .nomedia files with the source filename [#295 <https://github.com/saimn/sigal/issues/295>].

•   Populate title & description from IPTC image data [#297 <https://github.com/saimn/sigal/issues/297>].

•   Defer loading of leaflet js til late in the page [#298 <https://github.com/saimn/sigal/issues/298>].

•   Add compress_assets plugin [#300 <https://github.com/saimn/sigal/issues/300>].

•   Sidebar site logo image in Colorbox [#292 <https://github.com/saimn/sigal/issues/292>].

  Version 1.3.0

Released on 2017-01-03.

•   Support videos with rotation [#210 <https://github.com/saimn/sigal/issues/210>].

•   Generate missing thumbnails from the resized image if possible [#211 <https://github.com/saimn/sigal/issues/211>].

•   Fix background-image url in the PhotoSwipe theme [#213 <https://github.com/saimn/sigal/issues/213>].

•   Implement a first version of video support for the PhotoSwipe theme [#216 <https://github.com/saimn/sigal/issues/216>].

•   Update Google Analytics UA Code [#221 <https://github.com/saimn/sigal/issues/221>].

•   Use leaflet-providers.js to allow chosing the tile provider for the map in the Galleria theme [#218 <https://github.com/saimn/sigal/issues/218>].

•   Fix theme.url path in the media page plugin for the Colorbox theme. [#224 <https://github.com/saimn/sigal/issues/224>]

•   Add 3gp to the list of supported video formats. [#226 <https://github.com/saimn/sigal/issues/226>]

  Version 1.2.0

Released on 2016-06-05.

•   Fix videos not opening correctly with colorbox [#201 <https://github.com/saimn/sigal/issues/201>].

•   Allow to create large zip files [#205 <https://github.com/saimn/sigal/issues/205>].

•   Allow sorting on metadata keys (for albums_sort_attr and medias_sort_attr) [#202 <https://github.com/saimn/sigal/issues/202>].

•   Add a set_meta command to write metadata keys to .md files [#203 <https://github.com/saimn/sigal/issues/203>]. For example, to set the title of test.jpg to "My test image":

        sigal set_meta test.jpg title "My test image"

  Version 1.1.0

Released on 2016-04-24.

•   Add GIF support [#185 <https://github.com/saimn/sigal/issues/185>].

•   Add a feeds plugin [#98 <https://github.com/saimn/sigal/issues/98>].

•   Implement album sorting [#192 <https://github.com/saimn/sigal/issues/192>].

•   Enable autoescape in Jinja templates [#195 <https://github.com/saimn/sigal/issues/195>].

•   Raise exceptions in debug mode (--debug).

•   Fix unicode bug with special characters in path names.

•   Better representation for exposure time fraction [#187 <https://github.com/saimn/sigal/issues/187>].

•   Catch cPickle.PicklingError on python 2 [#191 <https://github.com/saimn/sigal/issues/191>].

•   Fix ZeroDivisionError when ExposureTime contains null values [#193 <https://github.com/saimn/sigal/issues/193>].

•   Fix hard-coded video mime-type in the galleria theme [#196 <https://github.com/saimn/sigal/issues/196>].

•   Update theme libraries: colorbox 1.6.3, jQuery 2.2.1, touchSwipe 1.6.15, photoswipe 4.1.1

•   Galleria: always show fullscreen icon, replace fullscreen and map icons.

•   Use https for external resources, remove html5shiv.

  Version 1.0.1

Released on 2015-11-19.

•   Simplify a bit photoswipe's style [#181 <https://github.com/saimn/sigal/issues/181>].

•   Improves CSP compatibility (Remove an inline javascript line) [#179 <https://github.com/saimn/sigal/issues/179>].

•   Warn that Pillow 3.0 is broken [#184 <https://github.com/saimn/sigal/issues/184>].

  Version 1.0.0

Released on 2015-09-07.

•   Colorbox: Use the media title if available (fix #145).

•   Adds a thumb_video_delay parameter for the creation of thumbnails with fade-in videos [#143 <https://github.com/saimn/sigal/issues/143>].

•   Add fullscreen display support to Galleria theme [#149 <https://github.com/saimn/sigal/issues/149>].

•   Add watermark plugin [#148 <https://github.com/saimn/sigal/issues/148>].

•   Allow more settings for font, color, position in the copyright plugin [#150 <https://github.com/saimn/sigal/issues/150>].

•   Tables support in markdown [#155 <https://github.com/saimn/sigal/issues/155>].

•   Honor 'use_orig' for videos [#153 <https://github.com/saimn/sigal/issues/153>].

•   Fix for the relative path checks for Windows [#160 <https://github.com/saimn/sigal/issues/160>].

•   Add support for mp4 [#159 <https://github.com/saimn/sigal/issues/159>].

•   Add size property into Image object [#164 <https://github.com/saimn/sigal/issues/164>].

•   Make sure that bad exif data does not crash sigal.

•   Strip spaces for some exif tags (fix #154).

•   Add support for piwik [#165 <https://github.com/saimn/sigal/issues/165>].

•   Add a theme using photoswipe [#163 <https://github.com/saimn/sigal/issues/163>].

•   Add a setting to disable google fonts and jquery [#168 <https://github.com/saimn/sigal/issues/168>].

•   Add swipe to colorbox theme [#116 <https://github.com/saimn/sigal/issues/116>].

•   Map view for albums in galleria theme [#45 <https://github.com/saimn/sigal/issues/45>].

  Version 0.9.2

Released on 2015-01-25.

•   Allow to specify the author of an album (ref #139).

•   Fix encoding issue with the progress bar on py3 (fix #137).

•   Avoid failure when an image can't be read (fix #134).

  Version 0.9.1

Released on 2014-12-08.

•   Fix images path for the galleria theme (fix #130).

  Version 0.9.0

Released on 2014-12-07.

•   New plugin which adds the ability to generate media pages [#126 <https://github.com/saimn/sigal/issues/126>].

•   Decrease logs level for the parsing of exif tags [#127 <https://github.com/saimn/sigal/issues/127>].

•   Enhance documentation for album information [#123 <https://github.com/saimn/sigal/issues/123>].

•   Fix the title which was not unicode when using the settings file [#104 <https://github.com/saimn/sigal/issues/104>].

•   Add more info on how the report a bug or contribute [#128 <https://github.com/saimn/sigal/issues/128>].

•   Add more commands to the Makefile.

•   Use coveralls.io

•   New plugin to upload generated gallery to Amazon S3 [#114 <https://github.com/saimn/sigal/issues/114>].

•   Handling of empty markdown or missing meta-data [#120 <https://github.com/saimn/sigal/issues/120>].

•   Include plugins in the distributed package [#117 <https://github.com/saimn/sigal/issues/117>].

•   Allow to use directly original files [#118 <https://github.com/saimn/sigal/issues/118>].

•   Add settings to give a different output filename than index.html [#115 <https://github.com/saimn/sigal/issues/115>].

•   Remove files that can't be processed for some reason [#112 <https://github.com/saimn/sigal/issues/112>].

•   Skip files that don't exist in the ZIP archiving [#110 <https://github.com/saimn/sigal/issues/110>].

•   Show progress (spinners & bars), read exif only on access [#109 <https://github.com/saimn/sigal/issues/109>].

•   Use the correct filename for original videos [#111 <https://github.com/saimn/sigal/issues/111>].

•   Check that the file exists before removing. [#110 <https://github.com/saimn/sigal/issues/110>].

•   Enhance the serve command [#107 <https://github.com/saimn/sigal/issues/107>].

•   Catch cPickle error and add a message about serialization error with the settings file.

  Version 0.8.1

Released on 2014-10-07.

•   Include plugins in the distributed package.

  Version 0.8.0

Released on 2014-08-30.

•   Add a setting and a cli option to specify the gallery title (title and --title) (ref #91).

•   Add a mailing list at Librelist (sigal at librelist.com).

•   Add an option to specify the port to use for the serve command.

•   Replace argh with click.

•   Don't overwrite existing config file (with the init command).

•   Don't fail if there are no pictures.

•   Use plain css to simplify theme customizing (no more sass).

•   Upgrade colorbox 1.5.13

•   Upgrade galleria 1.4.2

•   Use HTML5 output for Markdown.

•   Allow to read additional data for images from markdown files.

•   Use case insensitive check for file extensions (fix #99).

•   Add a plugin system with blinker, and make plugins for copyright and adjust.

•   Mention the irc channel on freenode and add travis notifications.

•   Avoid failure if GPS tags contain zero values (fix #96).

•   Remove output file when the ffmpeg process has been interrupted (ref #90).

•   Fix thumbnail urls to always use slashes (ref #81).

  Version 0.7

Released on 2014-05-10.

•   Refactor the way to store album and media informations. Albums, images and videos are now represented by objects, and these objects are directly available in the templates. The following template variables have been renamed:

•   albums => album.albums

•   breadcrumb => album.breadcrumb

•   description => album.description

•   index_url => album.index_url

•   medias => album.medias

•   title => album.title

•   media.file => media.filename

•   media.thumb => media.thumbnail

•   zip_gallery => album.zip

•   New settings to define the sort order for albums and medias: albums_sort_reverse, medias_sort_attr, medias_sort_reverse [#2 <https://github.com/saimn/sigal/issues/2>].

•   New setting (autorotate_images) to disable autorotation of images, and warn about the incompatibility between autorotation and EXIF copy [#72 <https://github.com/saimn/sigal/issues/72>].

•   New settings to filter directories and files with pattern matching (ignore_directories and ignore_files) [#63 <https://github.com/saimn/sigal/issues/63>].

•   New setting to customize the column width of the colorbox theme (colorbox_column_size).

•   New setting to choose the media format used for ZIP archives (zip_media_format).

•   Update galleria to 1.3.5 and add the history plugin [#93 <https://github.com/saimn/sigal/issues/93>].

•   Skip image instead of failing when the image is corrupted [#69 <https://github.com/saimn/sigal/issues/69>].

•   Better handling of album urls (quoting special caracters).

  Version 0.6.0

Released on 2014-01-25.

•   Add support for Python 3.3.

•   Parallel processing (new command-line option -n|--ncpu, uses all cores by default).

•   Adding keyboard shortcuts for the galleria theme [#32, #39].

•   Include symlinked directories in the source directory.

•   New setting to use symbolic links for original files (orig_link) [#36 <https://github.com/saimn/sigal/issues/36>].

•   New setting for the video size (video_size) [#35 <https://github.com/saimn/sigal/issues/35>].

•   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 [#58 <https://github.com/saimn/sigal/issues/58>].

•   Fix whitespace issues with video filenames [#54 <https://github.com/saimn/sigal/issues/54>].

  Version 0.5.1

Released on 2013-09-23.

•   Fix error in calculating the degrees from exif data.

  Version 0.5.0

Released on 2013-09-06.

•   Add support for videos. Videos are encoded to webm (see the webm_options setting).

•   Check jinja2's version for lstrip_blocks (only for Jinja 2.7+).

•   Add option to zip galleries. See the zip_gallery setting.

•   Add support for EXIF tags and GPS coordinates. EXIF tags are added to the media context (for themes). The copy_exif_data setting allow to choose if the exif data from the original image is copied to the resized image.

•   Correct themes design with long directory names.

•   Add the possibility to adjust images after resizing (with the Adjust processor from Pilkit). See the adjust_options setting.

•   Add the possibility to disable image resizing.

  Version 0.4.1

Released on 2013-07-19.

•   Fix a bug with unicode paths and filenames.

•   Update colorbox to 1.4.26

•   Add links to the original images.

  Version 0.4.0

Released on 2013-06-12.

•   Add a setting to disable the writing of HTML files.

•   Use Pilkit.

•   Remove multiprocessing.

•   Add new settings for the source and destination directories.

•   All meta-data are available in the templates.

•   Galleria theme is now responsive

•   Add a setting to choose the pilkit processor used to resize the images.

  Version 0.3.3

Released on 2013-03-20.

•   Catch exception when PIL fails to read the exif metadata.

  Version 0.3.2

Released on 2013-03-14.

•   Bugfix for PNG files which don't have exif metadata.

•   Move unit tests to pytest.

•   Fix images path in colorbox theme.

•   Group package meta in a module.

  Version 0.3.1

Released on 2013-03-11.

•   Fix the path of the sample config file (which was not included in the previous release).

  Version 0.3

Released on 2013-03-04.

•   Fix packaging issues.

•   New setting index_in_url to optionally add index.html to the URLs.

•   New setting links to specify a list of links.

•   Use EXIF info to fix orientation.

•   Replace the jpg_quality setting with a dict of options.

•   Manage directories with only sub-directories and add some checks.

•   Change the command-line interface to use sub-commands: init, build and serve.

•   Parallel processing.

  Version 0.2

Released on 2012-12-20.

•   Improve the bundled themes (update galleria, new colorbox theme).

•   Improve the CLI (new arguments, nicer output).

•   Change the licence to MIT.

•   Change the description file to a markdown syntax file.

•   Change the settings file to a python file, and add more settings.

  Version 0.1

Released on 2012-05-13.

First public release.

Author
Author name not set

Copyright
2012-2026, Simon Conseil