Merge branch 'pr/164'
This commit is contained in:
1
AUTHORS
1
AUTHORS
@@ -5,6 +5,7 @@ alphabetical order):
|
||||
- Andreas Sieferlinger
|
||||
- Antoine Pitrou
|
||||
- Christophe-Marie Duquesne
|
||||
- @franek (François D.)
|
||||
- Giel van Schijndel
|
||||
- Jamie Starke
|
||||
- @jdn06
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
# Copyright (c) 2009-2014 - Simon Conseil
|
||||
# Copyright (c) 2013 - Christophe-Marie Duquesne
|
||||
# Copyright (c) 2014 - Jonas Kaufmann
|
||||
# Copyright (c) 2015 - François D.
|
||||
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to
|
||||
@@ -41,7 +42,7 @@ from PIL import Image as PILImage
|
||||
|
||||
from . import image, video, signals
|
||||
from .compat import PY2, UnicodeMixin, strxfrm, url_quote, text_type
|
||||
from .image import process_image, get_exif_tags, get_exif_data
|
||||
from .image import process_image, get_exif_tags, get_exif_data, get_size
|
||||
from .settings import get_thumb
|
||||
from .utils import (Devnull, copy, check_or_create_dir, url_from_path,
|
||||
read_markdown, cached_property, is_valid_html5_video,
|
||||
@@ -168,6 +169,14 @@ class Image(Media):
|
||||
self.src_path)
|
||||
return None
|
||||
|
||||
@cached_property
|
||||
def size(self):
|
||||
return get_size(self.dst_path)
|
||||
|
||||
@cached_property
|
||||
def thumb_size(self):
|
||||
return get_size(self.thumb_path)
|
||||
|
||||
|
||||
class Video(Media):
|
||||
"""Gather all informations on a video file."""
|
||||
@@ -370,17 +379,18 @@ class Album(UnicodeMixin):
|
||||
for f in self.medias:
|
||||
ext = splitext(f.filename)[1]
|
||||
if ext.lower() in Image.extensions:
|
||||
try:
|
||||
im = PILImage.open(f.src_path)
|
||||
except:
|
||||
self.logger.error("Failed to open %s", f.src_path)
|
||||
else:
|
||||
if im.size[0] > im.size[1]:
|
||||
self._thumbnail = join(self.name, f.thumbnail)
|
||||
self.logger.debug(
|
||||
"Use 1st landscape image as thumbnail for %r :"
|
||||
" %s", self, self._thumbnail)
|
||||
return url_from_path(self._thumbnail)
|
||||
# Use f.size if available as it is quicker (in cache), but
|
||||
# fallback to the size of src_path if dst_path is missing
|
||||
size = f.size
|
||||
if size is None:
|
||||
size = get_size(f.src_path)
|
||||
|
||||
if size['width'] > size['height']:
|
||||
self._thumbnail = join(self.name, f.thumbnail)
|
||||
self.logger.debug(
|
||||
"Use 1st landscape image as thumbnail for %r :"
|
||||
" %s", self, self._thumbnail)
|
||||
return url_from_path(self._thumbnail)
|
||||
|
||||
# else simply return the 1st media file
|
||||
if not self._thumbnail and self.medias:
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
|
||||
# Copyright (c) 2009-2014 - Simon Conseil
|
||||
# Copyright (c) 2015 - François D.
|
||||
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to
|
||||
@@ -151,8 +152,8 @@ def process_image(filepath, outpath, settings):
|
||||
if settings['make_thumbs']:
|
||||
thumb_name = os.path.join(outpath, get_thumb(settings, filename))
|
||||
generate_thumbnail(outname, thumb_name, settings['thumb_size'],
|
||||
settings['thumb_video_delay'], fit=settings['thumb_fit'],
|
||||
options=options)
|
||||
settings['thumb_video_delay'],
|
||||
fit=settings['thumb_fit'], options=options)
|
||||
except Exception as e:
|
||||
logger.info('Failed to process: %r', e)
|
||||
return Status.FAILURE
|
||||
@@ -160,6 +161,21 @@ def process_image(filepath, outpath, settings):
|
||||
return Status.SUCCESS
|
||||
|
||||
|
||||
def get_size(file_path):
|
||||
"""Return image size (width and height)."""
|
||||
try:
|
||||
im = PILImage.open(file_path)
|
||||
except (IOError, IndexError, TypeError, AttributeError) as e:
|
||||
logger = logging.getLogger(__name__)
|
||||
logger.error("Could not read size of %s due to %r", file_path, e)
|
||||
else:
|
||||
width, height = im.size
|
||||
return {
|
||||
'width': width,
|
||||
'height': height
|
||||
}
|
||||
|
||||
|
||||
def get_exif_data(filename):
|
||||
"""Return a dict with the raw EXIF data."""
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ from PIL import Image
|
||||
|
||||
from sigal import init_logging
|
||||
from sigal.image import (generate_image, generate_thumbnail, get_exif_tags,
|
||||
get_exif_data)
|
||||
get_exif_data, get_size)
|
||||
from sigal.settings import create_settings
|
||||
|
||||
CURRENT_DIR = os.path.dirname(__file__)
|
||||
@@ -115,3 +115,22 @@ def test_exif_gps(tmpdir):
|
||||
|
||||
assert abs(simple['gps']['lat'] - lat) < 0.0001
|
||||
assert abs(simple['gps']['lon'] - lon) < 0.0001
|
||||
|
||||
def test_get_size(tmpdir):
|
||||
"""Test reading out image size"""
|
||||
|
||||
test_image = 'flickr_jerquiaga_2394751088_cc-by-nc.jpg'
|
||||
src_file = os.path.join(CURRENT_DIR, 'sample', 'pictures', 'dir1', 'test1',
|
||||
test_image)
|
||||
|
||||
result = get_size(src_file)
|
||||
assert result == {'height': 800, 'width': 600}
|
||||
|
||||
def test_get_size_with_invalid_path(tmpdir):
|
||||
"""Test reading out image size with a missing file"""
|
||||
|
||||
test_image = 'missing-file.jpg'
|
||||
src_file = os.path.join(CURRENT_DIR, test_image)
|
||||
|
||||
result = get_size(src_file)
|
||||
assert result == None
|
||||
Reference in New Issue
Block a user