Merge pull request #70 (from branch 'pr/70').
This commit is contained in:
29
docs/image_information.rst
Normal file
29
docs/image_information.rst
Normal 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/
|
||||
@@ -10,6 +10,7 @@ Documentation
|
||||
getting_started
|
||||
configuration
|
||||
album_information
|
||||
image_information
|
||||
themes
|
||||
plugins
|
||||
changelog
|
||||
|
||||
@@ -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."""
|
||||
|
||||
@@ -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'>
|
||||
|
||||
@@ -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 %}
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
4
tests/sample/pictures/dir1/test1/11.md
Normal file
4
tests/sample/pictures/dir1/test1/11.md
Normal file
@@ -0,0 +1,4 @@
|
||||
Title: Foo Bar
|
||||
Location: Bavaria
|
||||
|
||||
This is a funny description of this image
|
||||
@@ -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
|
||||
|
||||
@@ -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>"
|
||||
|
||||
Reference in New Issue
Block a user