Merge pull request #70 (from branch 'pr/70').

This commit is contained in:
Simon Conseil
2014-07-17 00:42:24 +02:00
9 changed files with 100 additions and 31 deletions

View File

@@ -0,0 +1,29 @@
===================
Image information
===================
Additional information on an image can be given in a file using the `markdown`_
syntax, named ``<imagename>.md`` (example: ``IMG_5206.md``)::
Title: My awesome photo
And a description with *Markdown* syntax.
EXIF data is directly extracted, see :ref:`simple-exif-data`. Some meta-data
keys are used by Sigal to get the useful informations on the gallery:
- *Title*: the image title.
Any additional meta-data is available in the templates. For instance::
Location: Las Vegas
can be used in the template with:
.. code-block:: jinja
{% if media.meta.location %}
<p>Location: {{ media.meta.location[0] }}</>
{% endif %}
.. _markdown: http://daringfireball.net/projects/markdown/

View File

@@ -10,6 +10,7 @@ Documentation
getting_started
configuration
album_information
image_information
themes
plugins
changelog

View File

@@ -23,10 +23,8 @@
from __future__ import absolute_import, print_function
import codecs
import fnmatch
import logging
import markdown
import multiprocessing
import os
import sys
@@ -42,7 +40,7 @@ from .compat import UnicodeMixin, strxfrm, url_quote
from .image import process_image, get_exif_tags
from .log import colored, BLUE
from .settings import get_thumb
from .utils import copy, check_or_create_dir, url_from_path
from .utils import copy, check_or_create_dir, url_from_path, read_markdown
from .video import process_video
from .writer import Writer
@@ -80,6 +78,7 @@ class Media(UnicodeMixin):
self.raw_exif = None
self.exif = None
self.date = None
self._get_metadata()
signals.media_initialized.send(self)
def __repr__(self):
@@ -119,6 +118,18 @@ class Media(UnicodeMixin):
return
return url_from_path(self.thumb_name)
def _get_metadata(self):
""" Get image metadata from filename.md: title, description, meta."""
self.description = ''
self.meta = {}
self.title = ''
descfile = splitext(self.src_path)[0] + '.md'
if isfile(descfile):
meta = read_markdown(descfile)
for key, val in meta.items():
setattr(self, key, val)
class Image(Media):
"""Gather all informations on an image file."""
@@ -246,24 +257,16 @@ class Album(UnicodeMixin):
"""
descfile = join(self.src_path, self.description_file)
self.description = ''
self.meta = {}
# default: get title from directory name
self.title = os.path.basename(self.path if self.path != '.'
else self.src_path)
if isfile(descfile):
# Use utf-8-sig codec to remove BOM if it is present
with codecs.open(descfile, 'r', 'utf-8-sig') as f:
text = f.read()
md = markdown.Markdown(extensions=['meta'])
html = md.convert(text)
self.title = md.Meta.get('title', [''])[0]
self.description = html
self.meta = md.Meta.copy()
else:
self.description = ''
self.meta = {}
# default: get title from directory name
self.title = os.path.basename(self.path if self.path != '.'
else self.src_path)
meta = read_markdown(descfile)
for key, val in meta.items():
setattr(self, key, val)
def create_output_directories(self):
"""Create output directories for thumbnails and original images."""

View File

@@ -90,7 +90,7 @@
{% if loop.index % nb_columns == 0 %}omega{% endif%}">
<a href="{{ media.filename }}" class="gallery" title="{{ media.filename }}" {{ img_description(media) }}>
<img src="{{ media.thumbnail }}" alt="{{ media.filename }}"
title="{{ media.filename }}" /></a>
title="{{ media.title if media.title else media.filename }}" /></a>
</div>
{% endif %}
{% if media.type == "video" %}
@@ -101,7 +101,7 @@
class="gallery" inline='yes' title="{{ media.filename }}"
{% if media.big %} data-big="{{ media.big }}"{% endif %}>
<img src="{{ media.thumbnail }}" alt="{{ media.filename }}"
title="{{ media.filename }}" /></a>
title="{{ media.title if media.title else media.filename }}" /></a>
</div>
<!-- This contains the hidden content for the video -->
<div style='display:none'>

View File

@@ -60,6 +60,8 @@
{% if album.medias %}
{% macro img_description(media) -%}
{%- if media.big %}<a href='{{ media.big }}'>Full size</a>{% endif %}
{% if media.description %}<br>{{ media.description }}{% endif %}
{%- if media.exif %}
<br>
{% if media.exif.iso %}ISO: {{ media.exif.iso }}, {% endif %}
@@ -76,16 +78,18 @@
{% if media.type == "image" %}
<a href="{{ media.filename }}">
<img src="{{ media.thumbnail }}" alt="{{ media.filename }}"
data-title="{{ media.filename }}"
data-title="{{ media.title if media.title else media.filename }}"
data-description="{{ img_description(media) }}"/>
</a>
{% endif %}
{% if media.type == "video" %}
<a href="{{ theme.url }}/img/empty.png">
<img src="{{ media.thumbnail }}" alt="{{ media.filename }}"
data-layer="<video controls>
<source src='{{ media.filename }}' type='video/webm' />
</video>" />
data-title="{{ media.title if media.title else media.filename }}"
data-description="{{ img_description(media) }}"
data-layer="<video controls>
<source src='{{ media.filename }}' type='video/webm' />
</video>" />
</a>
{% endif %}
{% endfor %}

View File

@@ -20,6 +20,8 @@
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
import codecs
import markdown
import os
import shutil
@@ -46,3 +48,18 @@ def url_from_path(path):
return path
else:
return '/'.join(path.split(os.sep))
def read_markdown(filename):
# Use utf-8-sig codec to remove BOM if it is present
with codecs.open(filename, 'r', 'utf-8-sig') as f:
text = f.read()
md = markdown.Markdown(extensions=['meta'])
html = md.convert(text)
return {
'title': md.Meta.get('title', [''])[0],
'description': html,
'meta': md.Meta.copy()
}

View File

@@ -0,0 +1,4 @@
Title: Foo Bar
Location: Bavaria
This is a funny description of this image

View File

@@ -71,6 +71,8 @@ def test_media(settings):
assert m.dst_path == join(settings['destination'], file_path)
assert m.thumb_name == thumb
assert m.thumb_path == join(settings['destination'], path, thumb)
assert m.title == "Foo Bar"
assert m.description == "<p>This is a funny description of this image</p>"
assert repr(m) == "<Media>('{}')".format(file_path)
assert str(m) == file_path

View File

@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
import os
from sigal.utils import copy, check_or_create_dir, url_from_path
from sigal import utils
CURRENT_DIR = os.path.dirname(__file__)
SAMPLE_DIR = os.path.join(CURRENT_DIR, 'sample')
@@ -11,28 +11,37 @@ def test_copy(tmpdir):
filename = 'exo20101028-b-full.jpg'
src = os.path.join(SAMPLE_DIR, 'pictures', 'dir2', filename)
dst = str(tmpdir.join(filename))
copy(src, dst)
utils.copy(src, dst)
assert os.path.isfile(dst)
filename = 'm57_the_ring_nebula-587px.jpg'
src = os.path.join(SAMPLE_DIR, 'pictures', 'dir2', filename)
dst = str(tmpdir.join(filename))
copy(src, dst, symlink=True)
utils.copy(src, dst, symlink=True)
assert os.path.islink(dst)
assert os.readlink(dst) == src
filename = 'exo20101028-b-full.jpg'
src = os.path.join(SAMPLE_DIR, 'pictures', 'dir2', filename)
copy(src, dst, symlink=True)
utils.copy(src, dst, symlink=True)
assert os.path.islink(dst)
assert os.readlink(dst) == src
def test_check_or_create_dir(tmpdir):
path = str(tmpdir.join('new_directory'))
check_or_create_dir(path)
utils.check_or_create_dir(path)
assert os.path.isdir(path)
def test_url_from_path():
assert url_from_path(os.sep.join(['foo', 'bar'])) == 'foo/bar'
assert utils.url_from_path(os.sep.join(['foo', 'bar'])) == 'foo/bar'
def test_read_markdown():
src = os.path.join(SAMPLE_DIR, 'pictures', 'dir1', 'test1', '11.md')
m = utils.read_markdown(src)
assert m['title'] == "Foo Bar"
assert m['meta']['location'][0] == "Bavaria"
assert m['description'] == \
"<p>This is a funny description of this image</p>"