Browse Source

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

pull/97/head
Simon Conseil 12 years ago
parent
commit
e3f34db5dc
  1. 1
      docs/index.rst
  2. 29
      docs/plugins.rst
  3. 31
      sigal/__init__.py
  4. 22
      sigal/image.py
  5. 0
      sigal/plugins/__init__.py
  6. 34
      sigal/plugins/adjust.py
  7. 31
      sigal/plugins/copyright.py
  8. 5
      sigal/settings.py
  9. 5
      sigal/signals.py

1
docs/index.rst

@ -11,4 +11,5 @@ Documentation
configuration
album_information
themes
plugins
changelog

29
docs/plugins.rst

@ -0,0 +1,29 @@
=========
Plugins
=========
Signals
-------
.. data:: sigal.signals.img_resized
:noindex:
Called after the image is resized.
Write a new plugin
------------------
See an example with the copyright plugin:
.. literalinclude:: ../sigal/plugins/copyright.py
:language: python
Adjust plugin
-------------
.. automodule:: sigal.plugins.adjust
Copyright plugin
----------------
.. automodule:: sigal.plugins.copyright

31
sigal/__init__.py

@ -28,10 +28,12 @@ sigal is yet another python script to prepare a static gallery of images:
* resize images, create thumbnails with some options (squared thumbs, ...).
* generate html pages.
"""
from __future__ import absolute_import, print_function
import importlib
import io
import locale
import logging
@ -41,6 +43,7 @@ import time
from argh import ArghParser, arg
from .compat import server, socketserver, string_types
from .gallery import Gallery
from .log import init_logging
from .pkgmeta import __version__
@ -105,6 +108,8 @@ def build(source, destination, debug=False, verbose=False, force=False,
sys.exit(1)
locale.setlocale(locale.LC_ALL, settings['locale'])
init_plugins(settings)
gal = Gallery(settings, theme=theme, ncpu=ncpu)
gal.build(force=force)
@ -120,14 +125,36 @@ def build(source, destination, debug=False, verbose=False, force=False,
'seconds.').format(duration=time.time() - start_time, **gal.stats))
def init_plugins(settings):
"""Load plugins and call register()."""
logger = logging.getLogger(__name__)
logger.debug('Plugin paths: %s', settings['plugin_paths'])
for path in settings['plugin_paths']:
sys.path.insert(0, path)
for plugin in settings['plugins']:
try:
if isinstance(plugin, string_types):
mod = importlib.import_module(plugin)
mod.register(settings)
else:
plugin.register(settings)
logger.debug('Registered plugin %s', plugin)
except Exception as e:
logger.error('Failed to load plugin %s: %r', plugin, e)
for path in settings['plugin_paths']:
sys.path.remove(path)
@arg('path', nargs='?', default='_build',
help='Directory to serve (default: _build/)')
def serve(path):
"""Run a simple web server."""
if os.path.exists(path):
from .compat import server, socketserver
os.chdir(path)
PORT = 8000
Handler = server.SimpleHTTPRequestHandler

22
sigal/image.py

@ -38,11 +38,11 @@ from copy import deepcopy
from datetime import datetime
from PIL.ExifTags import TAGS, GPSTAGS
from PIL import Image as PILImage
from PIL import ImageDraw, ImageOps
from pilkit.processors import Transpose, Adjust
from PIL import ImageOps
from pilkit.processors import Transpose
from pilkit.utils import save_image
from . import compat
from . import compat, signals
from .settings import get_thumb
@ -97,11 +97,10 @@ def generate_image(source, outname, settings, options=None):
processor = processor_cls(*settings['img_size'], upscale=False)
img = processor.process(img)
# Adjust the image after resizing
img = Adjust(**settings['adjust_options']).process(img)
if settings['copyright']:
add_copyright(img, settings['copyright'])
# signal.send() does not work here as plugins can modify the image, so we
# iterate other the receivers to call them with the image.
for receiver in signals.img_resized.receivers_for(img):
img = receiver(img, settings=settings)
outformat = img.format or original_format or 'JPEG'
logger.debug(u'Save resized image to {0} ({1})'.format(outname, outformat))
@ -152,13 +151,6 @@ def process_image(filepath, outpath, settings):
fit=settings['thumb_fit'], options=options)
def add_copyright(img, text):
"""Add a copyright to the image."""
draw = ImageDraw.Draw(img)
draw.text((5, img.size[1] - 15), '\xa9 ' + text)
def _get_exif_data(filename):
"""Return a dict with EXIF data."""

0
sigal/plugins/__init__.py

34
sigal/plugins/adjust.py

@ -0,0 +1,34 @@
# -*- coding: utf-8 -*-
"""Plugin which adjust the image after resizing.
Based on pilkit's Adjust_ processor.
.. _Adjust: https://github.com/matthewwithanm/pilkit/blob/master/pilkit/processors/base.py#L19
Settings::
adjust_options = {'color': 1.0,
'brightness': 1.0,
'contrast': 1.0,
'sharpness': 1.0}
"""
import logging
from sigal import signals
from pilkit.processors import Adjust
logger = logging.getLogger(__name__)
def adjust(img, settings=None):
logger.debug('Adjust image %r', img)
return Adjust(**settings['adjust_options']).process(img)
def register(settings):
if settings.get('adjust_options'):
signals.img_resized.connect(adjust)
else:
logger.warning('Adjust options are not set')

31
sigal/plugins/copyright.py

@ -0,0 +1,31 @@
# -*- coding: utf-8 -*-
"""Plugin which add a copyright to the image.
Settings:
- ``copyright``: the copyright text.
TODO: Add more settings (font, size, ...)
"""
import logging
from PIL import ImageDraw
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)
draw.text((5, img.size[1] - 15), settings['copyright'])
return img
def register(settings):
if settings.get('copyright'):
signals.img_resized.connect(add_copyright)
else:
logger.warning('Copyright text is not set')

5
sigal/settings.py

@ -31,13 +31,10 @@ from .compat import PY2
_DEFAULT_CONFIG = {
'adjust_options': {'color': 1.0, 'brightness': 1.0,
'contrast': 1.0, 'sharpness': 1.0},
'albums_sort_reverse': False,
'autorotate_images': True,
'colorbox_column_size': 4,
'copy_exif_data': False,
'copyright': '',
'destination': '_build',
'files_to_copy': (),
'google_analytics': '',
@ -55,6 +52,8 @@ _DEFAULT_CONFIG = {
'make_thumbs': True,
'orig_dir': 'original',
'orig_link': False,
'plugins': [],
'plugin_paths': [],
'source': '',
'theme': 'colorbox',
'thumb_dir': 'thumbnails',

5
sigal/signals.py

@ -0,0 +1,5 @@
# -*- coding: utf-8 -*-
from blinker import signal
img_resized = signal('img_resized')
Loading…
Cancel
Save